Skip to content

Commit

Permalink
Merge pull request #41 from stzups/feature/data-persistence
Browse files Browse the repository at this point in the history
v0.2.6 Design
  • Loading branch information
griffinht authored Mar 3, 2021
2 parents 241be6d + c70bc2f commit d32de84
Show file tree
Hide file tree
Showing 28 changed files with 302 additions and 242 deletions.
62 changes: 62 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
##v0.1
Add real time drawing

- Change file structure and how files are served
- Fix custom invite URL
- Automatic connection

##v0.2
Basic functionality to allow for more features to be added

###v0.2.1
Room to document based model

- Add sidebar
- Change offset points to absolute points in draw
- Refactor packets
- Refactor js
- Event based WebSocketHandler
- Change how URLs work

###v0.2.2
Add document opening/closing

- Change how queued packets work
- Documents are saved before closed
- Change protocol again

###v0.2.3
Flat file data persistence

- Remove ConsoleManager
- Add shutdown hooks for saving
- Change handshake
- Functioning Java serialization
- Complete rework of config system
- SSL support

###v0.2.4
User identity

- Change URL parsing
- Add HTTP cache as a config option
- Session management
- Sessions are linked to documents
- Improve toString debug

###v0.2.5
Multiple clients per user

- Change how sessions are handled
- Clean up script loading
- Fix hashcode issues

###v0.2.6
Design
- Clean up CSS
- Add changelog
- Add invite/connected users toolbar
- "Fix" canvas resize
- Change/clean up config system
- Improve client debug
- Better local user with different handshake
38 changes: 11 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,14 @@ Create a file called `board.properties` in the working directory of the server a
##### Command line arguments

java -jar board-server-xxx.jar --key value --other.key "value with spaces"


- ssl.keystore:
- Path to the PKCS12 `mykeystore.pfx` containing the private key for the server
- Required, set to `http` to disable encryption and use `http://` for connecting to the server
- ssl.passphrase:
- Optional
- Passphrase for `mykeystore.pfx`
- document.root.path:
- default: documentRoot (file path, relative paths start from the working directory)
- Sets the folder location of where the HTTP server should look to serve files. If the directory does not exist, one will be made.
- Should be set to where `board-web-client` is.
- HTTP requests to a directory (`localhost` or `localhost/folder/`) will be served the `index.html` file of those directories
- HTTP requests to a file that do not specify an extension (`localhost/file`) will be served a `.html` that corresponds to the requested name
- data.root.path
- default: data (file path, relative paths start from the working directory)
- Sets the folder location of the flat file storage
- debug.log.traffic
- default: false (boolean)
- Will print network throughput (read/write) into the console
- autosave.interval
- default: -1 (integer in seconds, negative values will disable autosave)
- Sets how often flat file storage will be saved to disk
- http.cache.seconds
- default: 0 (integer, seconds)
- How long before a cached item expires
- Set to 0 for development purposes so refreshing the page will always load your new changes (equivalent of `crtl+f5`)
File indicates a relative (<working directory>/folder/file.ext) or absolute path (C:/folder/file.ext)

| Flag | Type | Default | Description |
| --- | ---- | ------- | ----------- |
| ssl.keystore.path | file | (required) | Path to the PKCS12 `mykeystore.pfx` containing the private key for the server. Set to `http` to use HTTP without SSL encryption |
| ssl.passphrase | string | (optional) | Passphrase for `mykeystore.pfx` |
| document.root.path | file | documentRoot | Should be set to where `board-web-client` is. HTTP requests to a directory (`localhost` or `localhost/folder/`) will be served the `index.html` file of those directories HTTP requests to a file that do not specify an extension (`localhost/file`) will be served a `.html` that corresponds to the requested name
| data.root.path | file | data | Sets the folder location of the flat file storage |
| debug.log.traffic | boolean | false | Will print network throughput (read/write) into the console |
| autosave.interval | integer (seconds) | -1 | Sets how often flat file storage will be saved to disk, or negative value to disable |
| http.cache.time | integer (seconds) | 0 | How long before a cached item expires. Set to 0 for development purposes so refreshing the page will always load your new changes (equivalent of `crtl+f5`) |
10 changes: 5 additions & 5 deletions board-server/src/main/java/net/stzups/board/Board.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package net.stzups.board;

import io.netty.channel.ChannelFuture;
import net.stzups.board.config.ConfigProvider;
import net.stzups.board.config.ConfigProviderBuilder;
import net.stzups.board.config.Config;
import net.stzups.board.config.ConfigBuilder;
import net.stzups.board.config.configs.ArgumentConfig;
import net.stzups.board.config.configs.PropertiesConfig;
import net.stzups.board.data.TokenGenerator;
Expand All @@ -18,7 +18,7 @@

public class Board {
private static Logger logger;
private static ConfigProvider config;
private static Config config;

private static final String DEFAULT_DOCUMENT_NAME = "Untitled Document";

Expand Down Expand Up @@ -70,7 +70,7 @@ public static void main(String[] args) throws Exception {

long start = System.currentTimeMillis();

config = new ConfigProviderBuilder()
config = new ConfigBuilder()
.addConfig(new ArgumentConfig(args))
.addConfig(new PropertiesConfig("board.properties"))
.build();
Expand Down Expand Up @@ -105,7 +105,7 @@ public static Logger getLogger() {
return logger;
}

public static ConfigProvider getConfig() {
public static Config getConfig() {
return config;
}
}
68 changes: 66 additions & 2 deletions board-server/src/main/java/net/stzups/board/config/Config.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
package net.stzups.board.config;

public interface Config<T> {
T get(String key);
import java.nio.ByteBuffer;
import java.util.List;

/**
* Used to store and retrieve key-value pairs by finding the first result from many different strategies.
*/
public class Config {//todo probably needs a better name
private List<ConfigProvider> configProviders;

/**
* Constructs a new ConfigProvider from its builder
*/
Config(List<ConfigProvider> configProviders) {
this.configProviders = configProviders;
}

/**
* Gets a String value for a String key from any config provider
*/
public String get(String key) {
for (ConfigProvider configProvider : configProviders) {
String value = configProvider.get(key);
if (value != null) {
return value;
}
}

return null;
}

public int getInt(String key) {
try {
return Integer.parseInt(get(key));
} catch (NumberFormatException e) {
return 0;
}
}

public int getInt(String key, int defaultValue) {
try {
return Integer.parseInt(get(key));
} catch (NumberFormatException e) {
return defaultValue;
}
}

public boolean getBoolean(String key) {
return Boolean.parseBoolean(get(key));
}

public boolean getBoolean(String key, boolean defaultValue) {
String value = get(key);
if (value == null) {
return defaultValue;
} else {
return Boolean.parseBoolean(key);
}
}

public String get(String key, String defaultValue) {
String value = get(key);
if (value == null) {
return defaultValue;
}
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.stzups.board.config;

import java.util.ArrayList;
import java.util.List;

/**
* Builds a {@link Config} with several different configs.
*/
public class ConfigBuilder {
private List<ConfigProvider> configProviders = new ArrayList<>();

public ConfigBuilder() {}

public ConfigBuilder addConfig(ConfigProvider configProvider) {
configProviders.add(configProvider);
return this;
}

public Config build() {
return new Config(configProviders);
}
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,5 @@
package net.stzups.board.config;

import java.util.List;

/**
* Used to store and retrieve key-value pairs by finding the first result from many different strategies.
*/
public class ConfigProvider {//todo probably needs a better name
private List<StringConfig> stringConfigs;

/**
* Constructs a new ConfigProvider from its builder
* @param stringConfigs configs for String
*/
ConfigProvider(List<StringConfig> stringConfigs) {
this.stringConfigs = stringConfigs;
}

/**
* Searches all StringConfigs for a key and gets
* @param key the key to match
* @return the matching string, or null if none of the string configs have the key
*/
public String get(String key) {
for (Config<String> config : stringConfigs) {
String value = config.get(key);
if (value != null) {
return value;
}
}

return null;
}

/**
* Searches all configs that provide a String value for a key, which if not found will instead return the defaultValue
* @param key the key to match
* @param defaultValue the value to return if a value for the key is not found
* @return the value for the key, or the defaultValue
*/
public String get(String key, String defaultValue) {
String value = get(key);
if (value == null) {
return defaultValue;
}
return value;
}
public interface ConfigProvider {
String get(String key);
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.stzups.board.config.configs;

import net.stzups.board.config.StringConfig;
import net.stzups.board.config.ConfigProvider;

import java.util.Arrays;
import java.util.HashMap;
Expand All @@ -10,7 +10,7 @@
/**
* Takes arguments from the console and parses them as key value pairs.
*/
public class ArgumentConfig implements StringConfig {
public class ArgumentConfig implements ConfigProvider {
private Map<String, String> flags = new HashMap<>();

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.stzups.board.config.configs;

import net.stzups.board.config.StringConfig;
import net.stzups.board.config.ConfigProvider;

import java.io.File;
import java.io.FileInputStream;
Expand All @@ -11,7 +11,7 @@
* Loads a file that should be formatted as a Java {@link Properties} file, and adds any values defined in that value.
* This still works if the file does not exist or no values are present in the file.
*/
public class PropertiesConfig implements StringConfig {
public class PropertiesConfig implements ConfigProvider {
private Properties properties;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.util.concurrent.TimeUnit;

public class FlatFileStorage<K extends Serializable, V extends Serializable> extends HashMap<K, V> {
private static final int SAVE_INTERVAL = Integer.parseInt(Board.getConfig().get("autosave.interval", "-1"));//in seconds, -1 to disable
private static final int SAVE_INTERVAL = Board.getConfig().getInt("autosave.interval", -1);//in seconds, -1 to disable
private static final String FILE_EXTENSION = "data";

private File file;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public ChannelFuture start() throws Exception {
SslContext sslContext;
int port;

String keystorePath = Board.getConfig().get("ssl.keystore");
String keystorePath = Board.getConfig().get("ssl.keystore.path");
if (keystorePath != null) {//must not be null
if (keystorePath.equals("http")) {
Board.getLogger().warning("Starting server using insecure http:// protocol without SSL");
Expand Down Expand Up @@ -65,7 +65,7 @@ public ChannelFuture start() throws Exception {
}
}
} else {
throw new RuntimeException("Failed to set required flag --ssl.keystore. Perhaps you meant to explicitly disable encrypted sockets over HTTPS using --ssl.keystore http");
throw new RuntimeException("Failed to set required flag --ssl.keystore.path. Perhaps you meant to explicitly disable encrypted sockets over HTTPS using --ssl.keystore.path http");
}

bossGroup = new NioEventLoopGroup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
public class ServerInitializer extends ChannelInitializer<SocketChannel> {
private static final String WEB_SOCKET_PATH = "/websocket";
private static final boolean DEBUG_LOG_TRAFFIC = Boolean.parseBoolean(Board.getConfig().get("debug.log.traffic", "false"));
private static final boolean DEBUG_LOG_TRAFFIC = Board.getConfig().getBoolean("debug.log.traffic", false);

private GlobalTrafficShapingHandler globalTrafficShapingHandler = new GlobalTrafficShapingHandler(Executors.newSingleThreadScheduledExecutor(), 0, 0, 1000) {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpReque
}
private static final String HTTP_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
private static final String HTTP_DATE_GMT_TIMEZONE = "GMT";
private static final int HTTP_CACHE_SECONDS = Integer.parseInt(Board.getConfig().get("http.cache.seconds", "0"));
private static final int HTTP_CACHE_SECONDS = Board.getConfig().getInt("http.cache.time", 0);
private static final String JOIN_PATH = "d";

private static final SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
Expand Down
Loading

0 comments on commit d32de84

Please sign in to comment.