Skip to content

Commit

Permalink
PartyInfo Controller (Consensys#28)
Browse files Browse the repository at this point in the history
Introduce PartyInfo controller and supporting objects
Modified Config to store URL objects for 'url' and 'othernodes' keys
  • Loading branch information
bretthenderson authored Dec 15, 2017
1 parent 6f516b2 commit a8011c3
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 27 deletions.
8 changes: 6 additions & 2 deletions src/main/java/net/consensys/athena/api/cmd/Athena.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import static java.util.Optional.empty;

import net.consensys.athena.api.config.Config;
import net.consensys.athena.api.network.NetworkNodes;
import net.consensys.athena.impl.config.TomlConfigBuilder;
import net.consensys.athena.impl.http.server.Serializer;
import net.consensys.athena.impl.http.server.netty.DefaultNettyServer;
import net.consensys.athena.impl.http.server.netty.NettyServer;
import net.consensys.athena.impl.http.server.netty.NettySettings;
import net.consensys.athena.impl.network.MemoryNetworkNodes;

import java.io.File;
import java.io.FileInputStream;
Expand All @@ -20,12 +22,14 @@

public class Athena {

private static final int DEFAULT_HTTP_PORT = 8080;
private static NetworkNodes networkNodes;

public static void main(String[] args) throws Exception {
Optional<String> configFileName = args.length > 0 ? Optional.of(args[0]) : Optional.empty();

Config config = loadConfig(configFileName);
networkNodes = new MemoryNetworkNodes(config);

// start http server
NettyServer server = startServer(config);
joinServer(server);
Expand Down Expand Up @@ -55,7 +59,7 @@ static NettyServer startServer(Config config) throws InterruptedException {
config.socket(),
Optional.of((int) config.port()),
empty(),
new AthenaRouter(),
new AthenaRouter(networkNodes),
new Serializer(new ObjectMapper()));
NettyServer server = new DefaultNettyServer(settings);
server.start();
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/net/consensys/athena/api/cmd/AthenaRouter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.consensys.athena.api.cmd;

import net.consensys.athena.api.enclave.Enclave;
import net.consensys.athena.api.network.NetworkNodes;
import net.consensys.athena.api.storage.KeyValueStore;
import net.consensys.athena.api.storage.Storage;
import net.consensys.athena.api.storage.StorageIdBuilder;
Expand Down Expand Up @@ -34,6 +35,11 @@ public class AthenaRouter implements Router {
private static final Storage STORAGE =
new StorageKeyValueStorageDelegate(KEY_VALUE_STORE, KEY_BUILDER);
private static final Serializer SERIALIZER = new Serializer(new ObjectMapper());
private static NetworkNodes networkNodes;

public AthenaRouter(NetworkNodes info) {
networkNodes = info;
}

@Override
public Controller lookup(HttpRequest request) {
Expand Down Expand Up @@ -61,8 +67,7 @@ public Controller lookup(HttpRequest request) {
return new ResendController(ENCLAVE, STORAGE);
}
if (uri.getPath().startsWith("/partyinfo")) {
//probably need to inject something that stores the party info state.
return new PartyInfoController();
return new PartyInfoController(networkNodes);
}
if (uri.getPath().startsWith("/push")) {
return new PushController(STORAGE);
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/net/consensys/athena/api/config/Config.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package net.consensys.athena.api.config;

import java.io.File;
import java.net.URL;
import java.util.Optional;

/** Configuration for Athena Refer to the "sample.conf" file for documentation on config elements */
/**
* Configuration for Athena. Refer to the "sample.conf" file for documentation on config elements
*/
public interface Config {

/**
Expand All @@ -12,7 +15,7 @@ public interface Config {
*
* @return URL for this node
*/
String url();
URL url();

/**
* Port to listen on for the public API.
Expand Down Expand Up @@ -47,7 +50,7 @@ public interface Config {
*
* @return Array of other node URLs to connect to on startup
*/
File[] otherNodes();
URL[] otherNodes();

/**
* The set of public keys this node will host.
Expand Down Expand Up @@ -182,7 +185,7 @@ public interface Config {
* after populating the <i>tlsKnownClients</i> list to restrict access.
* <li><strong>ca:</strong> Only nodes with a valid certificate and chain of trust to one of the
* system root certificates will be allowed to connect. The folder containing trusted root
* certificates can be overridden with the SYSTEM_CERTIFICATE_PATH environment variable.
* certificates can be overriden with the SYSTEM_CERTIFICATE_PATH environment variable.
* <li><strong>ca-or-tofu:</strong> A combination of ca and tofu: If a certificate is valid, it
* is always allowed and added to the <i>tlsKnownClients</i> list. If it is self-signed, it
* will be allowed only if it's the first certificate this node has seen for that host.
Expand Down Expand Up @@ -250,7 +253,7 @@ public interface Config {
* server for any given host. (Similar to how OpenSSH works.)
* <li><strong>ca:</strong> The node will only connect to servers with a valid certificate and
* chain of trust to one of the system root certificates. The folder containing trusted root
* certificates can be overridden with the SYSTEM_CERTIFICATE_PATH environment variable.
* certificates can be overriden with the SYSTEM_CERTIFICATE_PATH environment variable.
* <li><strong>ca-or-tofu:</strong> A combination of ca and tofu: If a certificate is valid, it
* is always allowed and added to the <i>tlsKnownServers</i> list. If it is self-signed, it
* will be allowed only if it's the first certificate this node has seen for that host.
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/net/consensys/athena/api/network/NetworkNodes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.consensys.athena.api.network;

import java.net.URL;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.HashSet;

/** Details of other nodes on the network */
public interface NetworkNodes {

/**
* URL of this node
*
* @return URL of node
*/
URL url();

/**
* List of URLs of other nodes on the network
*
* @return
*/
HashSet<URL> nodeURLs();

/**
* Map from URL to public key for all discovered nodes.
*
* @return
*/
HashMap<URL, PublicKey> nodePKs();
}
13 changes: 7 additions & 6 deletions src/main/java/net/consensys/athena/impl/config/MemoryConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import net.consensys.athena.api.config.Config;

import java.io.File;
import java.net.URL;
import java.util.Optional;

public class MemoryConfig implements Config {

private String url;
private URL url;
private long port;
private Optional<File> workDir = Optional.empty();
private Optional<File> socket = Optional.empty();
private File[] otherNodes;
private URL[] otherNodes;
private File[] publicKeys;
private File[] privateKeys;
private File[] alwaysSendTo;
Expand All @@ -33,7 +34,7 @@ public class MemoryConfig implements Config {
private Optional<Boolean> showVersion = Optional.empty();
private long verbosity;

public void setUrl(String url) {
public void setUrl(URL url) {
this.url = url;
}

Expand All @@ -49,7 +50,7 @@ public void setSocket(File socket) {
this.socket = Optional.ofNullable(socket);
}

public void setOtherNodes(File[] otherNodes) {
public void setOtherNodes(URL[] otherNodes) {
this.otherNodes = otherNodes;
}

Expand Down Expand Up @@ -134,7 +135,7 @@ public void setVerbosity(long verbosity) {
}

@Override
public String url() {
public URL url() {
return url;
}

Expand All @@ -154,7 +155,7 @@ public Optional<File> socket() {
}

@Override
public File[] otherNodes() {
public URL[] otherNodes() {
return otherNodes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;

Expand All @@ -19,7 +21,12 @@ public Config build(InputStream config) throws ConfigException {
Toml toml = new Toml().read(config);

if (toml.getString("url") != null) {
memoryConfig.setUrl(toml.getString("url"));
try {
memoryConfig.setUrl(new URL(toml.getString("url")));
} catch (MalformedURLException e) {
errorMsg.append("Error: key 'url' in config is malformed.\n\t");
errorMsg.append(e.getMessage()).append("\n");
}
} else {
errorMsg.append("Error: value for key 'url' in config must be specified\n");
}
Expand All @@ -38,7 +45,12 @@ public Config build(InputStream config) throws ConfigException {
memoryConfig.setSocket(new File(toml.getString("socket")));
}

memoryConfig.setOtherNodes(convertListToFileArray(toml.getList("othernodes")));
try {
memoryConfig.setOtherNodes(convertListToURLArray(toml.getList("othernodes")));
} catch (ConfigException e) {
errorMsg.append("Error: key 'othernodes' in config containes malformed URLS.\n");
errorMsg.append(e.getMessage());
}

memoryConfig.setPublicKeys(convertListToFileArray(toml.getList("publickeys")));
memoryConfig.setPrivateKeys(convertListToFileArray(toml.getList("privatekeys")));
Expand Down Expand Up @@ -113,6 +125,34 @@ private File[] convertListToFileArray(List<String> paths) {
return paths == null ? new File[0] : paths.stream().map(File::new).toArray(File[]::new);
}

private URL[] convertListToURLArray(List<String> urls) {
URL[] urlArray;
StringBuilder errorMsg = new StringBuilder();

if (urls == null) {
urlArray = new URL[0];
} else {
urlArray = new URL[urls.size()];
for (int i = 0; i < urls.size(); i++) {
try {
urlArray[i] = new URL(urls.get(i));
} catch (MalformedURLException e) {
errorMsg
.append("\tURL [")
.append(urls.get(i))
.append("] ")
.append(e.getMessage())
.append("\n");
}
}
}
if (errorMsg.length() != 0) {
throw new ConfigException(errorMsg.toString());
}

return urlArray;
}

private String[] convertListToStringArray(List<String> paths) {
return paths == null ? new String[0] : paths.toArray(new String[paths.size()]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.consensys.athena.impl.http.controllers;

import net.consensys.athena.api.network.NetworkNodes;
import net.consensys.athena.impl.http.server.ContentType;
import net.consensys.athena.impl.http.server.Controller;
import net.consensys.athena.impl.http.server.Result;
Expand All @@ -12,8 +13,14 @@
*/
public class PartyInfoController implements Controller {

private static NetworkNodes networkNodes;

public PartyInfoController(NetworkNodes info) {
networkNodes = info;
}

@Override
public Result handle(FullHttpRequest request) {
return Result.notImplemented(ContentType.HASKELL_ENCODED);
return Result.ok(ContentType.HASKELL_ENCODED, networkNodes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package net.consensys.athena.impl.network;

import net.consensys.athena.api.config.Config;
import net.consensys.athena.api.network.NetworkNodes;

import java.net.URL;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

public class MemoryNetworkNodes implements NetworkNodes {

private URL url;
private HashSet<URL> nodeURLs;
private HashMap<URL, PublicKey> nodePKs;

public MemoryNetworkNodes() {
nodeURLs = new HashSet<>();
nodePKs = new HashMap<>();
}

public MemoryNetworkNodes(Config config) {
url = config.url();
if (config.otherNodes().length > 0) {
nodeURLs = new HashSet<>(Arrays.asList(config.otherNodes()));
} else {
nodeURLs = new HashSet<>();
}

nodePKs = new HashMap<>();
}

/**
* Add the URL of a node to the nodeURLs list.
*
* @param node URL of new node
*/
public void addNodeURL(URL node) {
this.nodeURLs.add(node);
}

/**
* Add a node's URL and PublcKey to the nodeURLs and nodePKs lists
*
* @param node URL of new node
* @param nodePk PublicKey of new node
*/
public void addNode(URL node, PublicKey nodePk) {
this.nodeURLs.add(node);
this.nodePKs.put(node, nodePk);
}

@Override
public URL url() {
return url;
}

@Override
public HashSet<URL> nodeURLs() {
return nodeURLs;
}

public HashMap<URL, PublicKey> nodePKs() {
return nodePKs;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import net.consensys.athena.impl.http.controllers.SendController;
import net.consensys.athena.impl.http.controllers.UpcheckController;
import net.consensys.athena.impl.http.server.Controller;
import net.consensys.athena.impl.network.MemoryNetworkNodes;

import java.util.Arrays;
import java.util.Collection;
Expand All @@ -28,7 +29,7 @@ public class AthenaRouterTest {
private final String testName;
private final String path;
private final Class controllerClass;
AthenaRouter router = new AthenaRouter();
AthenaRouter router = new AthenaRouter(new MemoryNetworkNodes());

@Parameterized.Parameters
public static Collection routes() {
Expand All @@ -42,7 +43,7 @@ public static Collection routes() {
{"Receive", "/receive", ReceiveController.class},
{"Delete", "/delete", DeleteController.class},
{"Resend", "/resend", ResendController.class},
{"PartyInfo", "/partyinfo", PartyInfoController.class},
{"NetworkNodes", "/partyinfo", PartyInfoController.class},
{"Push", "/push", PushController.class},
});
}
Expand Down
Loading

0 comments on commit a8011c3

Please sign in to comment.