From 6d21f641e4a8d09c8c5a43b6717e3975055b14e9 Mon Sep 17 00:00:00 2001 From: Conor Flynn Date: Sat, 8 Oct 2022 14:28:49 -0400 Subject: [PATCH] Modify internal architecture to support easy parameterization. --- .../Internal Manual/Packet Spreadsheet.xlsx | Bin 19043 -> 19481 bytes .../src/main/java/org/core/core/Core.java | 2 +- .../src/main/java/org/core/engine/Engine.java | 5 +- .../src/main/java/org/core/logger/Logger.java | 5 +- .../java/org/framework/interfaces/Hash.java | 6 +- .../java/org/framework/router/Packet.java | 56 +++-- .../org/framework/router/ResponseFactory.java | 6 + .../java/org/framework/router/Router.java | 18 +- .../out/destinations/SocketDestination.java | 2 +- .../java/org/out/handler/OutputHandler.java | 14 +- .../java/org/out/handler/OutputManager.java | 6 +- .../connections/AmberDataConnection.java | 43 ++-- .../TemplateExternalConnection.java | 80 ++++---- .../handler/ExternalStreamConnection.java | 31 ++- .../handler/ExternalStreamHandler.java | 191 ++++++++---------- .../handler/ExternalStreamManager.java | 45 +---- .../local/handler/LocalStreamHandler.java | 111 +++++----- .../registry/StreamRegistryController.java | 106 +++++----- .../src/test/java/test/protocols/TestSRC.java | 117 +++++------ DeFi-Data-Engine/Rest Application/pom.xml | 12 +- .../src/main/java/org/properties/Config.java | 47 +++-- .../org/rest/application/RestApplication.java | 4 +- DeFi-Data-Engine/Testing Environment/pom.xml | 5 + .../socket/SocketConnectionTest.java | 30 ++- 24 files changed, 482 insertions(+), 460 deletions(-) diff --git a/Data Engine/Documents/Internal Manual/Packet Spreadsheet.xlsx b/Data Engine/Documents/Internal Manual/Packet Spreadsheet.xlsx index bdbad7c0ef407c77706f1f3eb02999759635d123..7220a67c4412ddc9197fd2cac3a74e4c507949fb 100644 GIT binary patch delta 12123 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 diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/core/Core.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/core/Core.java index eb550b57..36debac0 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/core/Core.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/core/Core.java @@ -20,7 +20,7 @@ public Core() { this.connect(out, crl, eng, str); - Response response = this.send("ENG", "STRT", ""); + Response response = this.send("ENG", "STRT"); if(response.code() != 200) Logger.terminate(response); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/engine/Engine.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/engine/Engine.java index 34196b7b..42decc2f 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/engine/Engine.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/engine/Engine.java @@ -12,16 +12,17 @@ public Engine() { super("engine", "ENG"); } + // source: source of the local stream to initialize public Response processSTRT(Packet packet) { // start output processes: - Response out_response = send("OUT", "STRT", ""); + Response out_response = send("OUT", "STRT"); if(out_response.code() != 200) return out_response; // start local stream handler processes: String lsh_type = Config.getProperty("stream", "local.stream.type"); if(!lsh_type.equals("null")) { - Response lsh_response = send("LSH", "INIT", lsh_type); + Response lsh_response = send("LSH", "INIT", "local_source", lsh_type); if(lsh_response.code() != 200) return lsh_response; } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/logger/Logger.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/logger/Logger.java index 718da906..68b0bdfd 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/logger/Logger.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/core/logger/Logger.java @@ -35,14 +35,13 @@ public static final void terminate(Response response) { } private static final String packetFormat(Packet packet) { - return String.format("[%s] [%-10s] PACKET - [%3s -> %3s] [%4s] [%s] [%s]", + return String.format("[%s] [%-10s] PACKET - [%3s -> %3s] [%4s] [%s]", time(), Thread.currentThread().getName(), packet.getSender(), packet.getTag(), packet.getSubTag(), - packet.getData(), - packet.getSubData()); + packet.getData()); } private static final String responseFormat(Response response) { diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/interfaces/Hash.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/interfaces/Hash.java index 375f8c5b..4be60859 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/interfaces/Hash.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/interfaces/Hash.java @@ -1,5 +1,7 @@ package org.framework.interfaces; +import java.util.HashMap; + /** * Interface used for requiring components to have a unique hash based on the passed data. * The hash does not require any standard formatting so long as it is unique. @@ -13,8 +15,8 @@ public interface Hash { * Unique hash based on the passed data for identification. Algorithm is recommended to be * a salted SHA-512. * - * @param data {@link String} which holds all data, primarily that used for authorization. + * @param data {@link HashMap} which holds all data, primarily that used for authorization. * @return {@link String} that contains the newly created hash. */ - public String getHash(String data); + public String getHash(HashMap data); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Packet.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Packet.java index be8bafab..6ed0eff8 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Packet.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Packet.java @@ -1,5 +1,7 @@ package org.framework.router; +import java.util.HashMap; + import org.core.logger.Logger; import org.properties.Config; @@ -19,8 +21,7 @@ public class Packet { private final String sender; private final String tag; private final String sub_tag; - private final String data; - private final String sub_data; + private final HashMap data; /** * Initializes a new {@link Packet} object. @@ -29,14 +30,12 @@ public class Packet { * @param tag Tag of the destination the {@link Packet} will be sent to. * @param sub_tag Sub tag describing the action performed at the destination. * @param data Data transmitted through the {@link Packet} for processing at the destination. - * @param sub_data Supporting data used for processing and transmitting from {@code data}. This parameter is optional. */ - private Packet(Router router, String tag, String sub_tag, String data, String sub_data) { + private Packet(Router router, String tag, String sub_tag, HashMap data) { this.sender = router.getTag(); this.tag = tag; this.sub_tag = sub_tag; this.data = data; - this.sub_data = sub_data; } /** @@ -66,22 +65,41 @@ public final String getSubTag() { return sub_tag; } + public final boolean containsKey(String key) { + return data.containsKey(key); + } + /** * Data transmitted through the {@link Packet} for processing at the destination. * * @return String containing all data sent. */ - public final String getData() { + public final HashMap getData() { return data; } /** - * Supporting data used for processing and transmitting from {@code data}. + * Retrieves data point stored within {@link Packet}. * - * @return String containing all sub_data. + * @param key Key that the data point is stored under. + * @return {@link String} containing data stored. */ - public final String getSubData() { - return sub_data; + public final String getData(String key) { + if(data.containsKey(key)) + return data.get(key); + + return null; + } + + public final String validate(String... keys) { + if(keys == null) + return null; + + for(String key : keys) + if(!data.containsKey(key) || data.get(key).equals("")) + return key; + + return null; } /** @@ -93,8 +111,11 @@ public final String getSubData() { * @param data Data transmitted through the {@link Packet} for processing at the destination. * @return New {@link Packet} object. */ - public static Packet packet(Router router, String tag, String sub_tag, String data) { - Packet packet = new Packet(router, tag, sub_tag, data, ""); + public static Packet packet(Router router, String tag, String sub_tag, HashMap data) { + if(data == null) + return null; + + Packet packet = new Packet(router, tag, sub_tag, data); if(log) Logger.log(packet); return packet; @@ -110,8 +131,15 @@ public static Packet packet(Router router, String tag, String sub_tag, String da * @param sub_data Supporting data used for processing and transmitting from {@code data}. * @return New {@link Packet} object. */ - public static Packet packet(Router router, String tag, String sub_tag, String data, String sub_data) { - Packet packet = new Packet(router, tag, sub_tag, data, sub_data); + public static Packet packet(Router router, String tag, String sub_tag, String... data) { + if(data.length % 2 != 0) + return null; + + HashMap map = new HashMap(); + for(int i = 0; i < data.length; i+=2) + map.put(data[i], data[i + 1]); + + Packet packet = new Packet(router, tag, sub_tag, map); if(log) Logger.log(packet); return packet; diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/ResponseFactory.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/ResponseFactory.java index c2d24e95..050e0e2c 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/ResponseFactory.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/ResponseFactory.java @@ -45,6 +45,12 @@ public static Response response405(String router, String subtag) { + "is written properly.", router, subtag)); } + public static Response response407(String router, String tag, String sub_tag, String... data) { + return Response.create(407, String.format("Malformed packet when sending data from <%s> to <%s> using protocol " + + "<%s>. Data does not contain an even amount of pairs. Data <%s>.", + router, tag, sub_tag, Arrays.toString(data))); + } + public static Response response410(String router, String subtag) { return Response.create(410, String.format("Router <%s> process <%s> is formatted incorrectly. Check to make sure the process' " + "method contains the proper format of .", router, subtag)); diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Router.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Router.java index e440021c..f503c2e1 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Router.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/framework/router/Router.java @@ -171,8 +171,15 @@ protected final Collection connectedTags() { * @param data Data transmitted through the {@link Packet} for processing at the destination. * @return Integer representing the return code of the sent {@link Packet}. */ - public final Response send(String tag, String sub_tag, String data) { - return send(tag, sub_tag, data, ""); + public final Response send(String tag, String sub_tag, HashMap data) { + if(manager == null) + return ResponseFactory.response400(this.getTag()); + + Packet packet = Packet.packet(this, tag, sub_tag, data); + if(packet == null) + return ResponseFactory.response407(this.tag, tag, sub_tag, data.toString()); + + return manager.send(packet); } /** @@ -184,12 +191,15 @@ public final Response send(String tag, String sub_tag, String data) { * @param sub_data Supporting data used for processing and transmitting from {@code data}. This parameter is optional. * @return Integer representing the return code of the sent {@link Packet}. */ - public final Response send(String tag, String sub_tag, String data, String sub_data) { + public final Response send(String tag, String sub_tag, String... data) { if(manager == null) return ResponseFactory.response400(this.getTag()); // create packet and push to receive method - Packet packet = Packet.packet(this, tag, sub_tag, data, sub_data); + Packet packet = Packet.packet(this, tag, sub_tag, data); + if(packet == null) + return ResponseFactory.response407(this.tag, tag, sub_tag, data); + return manager.send(packet); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/destinations/SocketDestination.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/destinations/SocketDestination.java index daab980b..239bdd4a 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/destinations/SocketDestination.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/destinations/SocketDestination.java @@ -19,7 +19,7 @@ public SocketDestination(String key, DataOutputStream out) { public final synchronized boolean send(Packet packet) { try { - out.write(packet.getData().getBytes()); + out.write(packet.getData("data").getBytes()); out.write(10); } catch (JSONException | IOException e) { return false; diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputHandler.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputHandler.java index 9f818188..26d99db9 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputHandler.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputHandler.java @@ -36,14 +36,18 @@ public Response processSTRT(Packet packet) { } public Response processEDAT(Packet packet) { - if(packet.getSubData().equals("null")) + String destination = packet.getData("destination"); + if(destination == null) + return ResponseFactory.response500("OutputHandler", "destination"); + + if(destination.equals("null")) return ResponseFactory.response200(); - if(!manager.containsDestination(packet.getSubData())) - return ResponseFactory.response471(packet.getSubData()); + if(!manager.containsDestination(destination)) + return ResponseFactory.response471(destination); - if(!manager.send(packet.getSubData(), packet)) - return ResponseFactory.response472(packet.getSubData()); + if(!manager.send(destination, packet)) + return ResponseFactory.response472(destination); return ResponseFactory.response200(); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputManager.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputManager.java index d274dca0..65ca05de 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputManager.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/out/handler/OutputManager.java @@ -111,14 +111,10 @@ public Object[] producerListen() { return new Object[] {true, ""}; } - protected final Response send(String tag, String sub_tag, String data) { + protected final Response send(String tag, String sub_tag, String... data) { return handler.send(tag, sub_tag, data); } - protected final Response send(String tag, String sub_tag, String data, String sub_data) { - return handler.send(tag, sub_tag, data, sub_data); - } - public final synchronized void add(OutputDestination destination) { destinations.put(destination.getKey(), destination); //destination.send(Packet.packet(handler, "", "", "Connected: " + destination.getKey())); diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/AmberDataConnection.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/AmberDataConnection.java index e248a87c..cdd57bdb 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/AmberDataConnection.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/AmberDataConnection.java @@ -3,10 +3,10 @@ import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.HashMap; import org.framework.router.ResponseFactory; import org.json.JSONObject; -import org.stream.external.connected.amberdata.AmberDataRequestHandler; import org.stream.external.handler.ExternalStreamConnection; import org.stream.external.handler.ExternalStreamManager; @@ -17,7 +17,7 @@ public class AmberDataConnection extends ExternalStreamConnection { private boolean authorized = false; - public AmberDataConnection(ExternalStreamManager manager, String data) { + public AmberDataConnection(ExternalStreamManager manager, HashMap data) { super(manager, data); } @@ -28,16 +28,6 @@ public String getUUID() { public void init() { } - - @Override - public void defineSubscriptionTypes() { - - } - - @Override - public void defineRequestTypes() { - addRequestType("lending-latest"); - } public String getHash(String data) { try { @@ -65,7 +55,7 @@ public boolean authorize() { .url("https://web3api.io/api/v2/market/defi/lending/exchanges/aave/latest") .get() .addHeader("Accept", "application/json") - .addHeader("x-api-key", data) + .addHeader("x-api-key", data.get("key")) .build(); try { @@ -114,14 +104,33 @@ public boolean start() { public boolean stop() { return false; } - + + @Override + public String getHash(HashMap data) { + // TODO Auto-generated method stub + return null; + } + @Override - public Object[] request(String destination, String data) { - return AmberDataRequestHandler.request(this.data, data); + public boolean containsSubscriptionType(String type) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean containsRequestType(String type) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Object[] request(HashMap request) { + // TODO Auto-generated method stub + return null; } @Override - public Object[] request(String destination, String request, String date) { + public Object[] request(HashMap request, String date) { // TODO Auto-generated method stub return null; } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/TemplateExternalConnection.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/TemplateExternalConnection.java index 74e0afa8..0fae45f0 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/TemplateExternalConnection.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/connected/connections/TemplateExternalConnection.java @@ -1,5 +1,7 @@ package org.stream.external.connected.connections; +import java.util.HashMap; + import org.stream.external.handler.ExternalStreamConnection; import org.stream.external.handler.ExternalStreamManager; @@ -9,11 +11,11 @@ public class TemplateExternalConnection extends ExternalStreamConnection { private boolean authorized = false; private boolean override = false; - public TemplateExternalConnection(ExternalStreamManager manager, String data) { - super(manager, data.split(",")[0]); + public TemplateExternalConnection(ExternalStreamManager manager, HashMap data) { + super(manager, data); - if(data.contains(",")) - override = Boolean.parseBoolean(data.split(",")[1].trim()); + if(data.containsKey("override")) + override = true; } public String getUUID() { @@ -26,10 +28,8 @@ public String getHash(String data) { @Override public boolean authorize() { - if(override) - authorized = true; - else - authorized = this.data.equals("key"); + if(this.data.containsKey("key")) + authorized = data.get("key").equals("key") || data.get("key").equals("not_ready"); return authorized; } @@ -37,21 +37,6 @@ public boolean authorize() { public boolean isAuthorized() { return authorized; } - - @Override - public void defineSubscriptionTypes() { - addSubscriptionType("correct"); - addSubscriptionType("irregular"); - addSubscriptionType("external"); - } - - @Override - public void defineRequestTypes() { - addRequestType("correct"); - addRequestType("irregular"); - addRequestType("external"); - addRequestType("template-external-request"); - } @Override public Object[] subscribe(String data) { @@ -84,29 +69,32 @@ public boolean stop() { active = false; return true; } - + + @Override + public String getHash(HashMap data) { + return data.get("key"); + } + + @Override + public boolean containsSubscriptionType(String type) { + return type.equals("correct") || type.equals("irregular"); + } + + @Override + public boolean containsRequestType(String type) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Object[] request(HashMap request) { + // TODO Auto-generated method stub + return null; + } + @Override - public Object[] request(String destination, String data, String date) { - if(date == null) { - if(data.equals("correct")) - return new Object[] {true, "success"}; - - else if(data.equals("template-external-request")) { - for(int i = 0; i < 3; i++) - this.processRequest(data, date, destination, String.format("element, %d, mult7, %d", i, i * 7)); - return new Object[] {true, "success"}; - } - } else { - if(data.equals("correct")) - return new Object[] {true, "success"}; - - else if(data.equals("template-external-request")) { - for(int i = 0; i < 3; i++) - this.processRequest(data, date, destination, String.format("element, %d, mult10, %d", i, i * 10)); - return new Object[] {true, "success"}; - } - } - - return new Object[] {false, "Request handled irregularly"}; + public Object[] request(HashMap request, String date) { + // TODO Auto-generated method stub + return null; } } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamConnection.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamConnection.java index 8fba47b4..34c596ea 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamConnection.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamConnection.java @@ -1,5 +1,6 @@ package org.stream.external.handler; +import java.util.HashMap; import java.util.TreeSet; import org.framework.interfaces.Hash; @@ -10,11 +11,11 @@ public abstract class ExternalStreamConnection implements UUID, Hash { private final String hash; private final ExternalStreamManager manager; - protected final String data; + protected final HashMap data; protected final TreeSet subscriptionTypes; protected final TreeSet requestTypes; - public ExternalStreamConnection(ExternalStreamManager manager, String data) { + public ExternalStreamConnection(ExternalStreamManager manager, HashMap data) { this.hash = getHash(data); this.manager = manager; this.data = data; @@ -23,8 +24,6 @@ public ExternalStreamConnection(ExternalStreamManager manager, String data) { if(data != null) { init(); - defineSubscriptionTypes(); - defineRequestTypes(); } } @@ -32,21 +31,19 @@ public void init() { } - public void processSubscription(String subscription, String destination, String data) { - manager.processSubscription(hash, subscription, destination, data); + public void processSubscription(String subscription, String data) { + manager.processSubscription(hash, subscription, data); } - public void processRequest(String request, String date, String destination, String data) { + public void processRequest(String request, String date, String data) { if(date != null) manager.processRequest(hash, - getUUID() + Config.getProperty("app", "general.collection.delim") + request + Config.getProperty("app", "general.collection.delim") + date, - destination, + getUUID() + Config.getProperty("app", "general.collection.delim") + request + Config.getProperty("app", "general.collection.delim") + date, data); else manager.processRequest(hash, - getUUID() + Config.getProperty("app", "general.collection.delim") + request, - destination, + getUUID() + Config.getProperty("app", "general.collection.delim") + request, data); } @@ -59,16 +56,12 @@ public final String getHash() { public abstract boolean isReady(); public abstract boolean isActive(); - public abstract void defineSubscriptionTypes(); - public final void addSubscriptionType(String type) { subscriptionTypes.add(type); } - public final boolean containsSubscriptionType(String type) { return subscriptionTypes.contains(type); } + public abstract boolean containsSubscriptionType(String type); public abstract Object[] subscribe(String data); - public abstract void defineRequestTypes(); - public final void addRequestType(String type) { requestTypes.add(type); } - public final boolean containsRequestType(String type) { return requestTypes.contains(type); } - public Object[] request(String destination, String request) { return request(destination, request, null); } - public abstract Object[] request(String destination, String request, String date); + public abstract boolean containsRequestType(String type); + public abstract Object[] request(HashMap request); + public abstract Object[] request(HashMap request, String date); public abstract boolean start(); public abstract boolean stop(); diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamHandler.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamHandler.java index 74d4114d..2be7a9af 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamHandler.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamHandler.java @@ -4,7 +4,6 @@ import org.framework.router.Response; import org.framework.router.ResponseFactory; import org.framework.router.Router; -import org.properties.Config; public final class ExternalStreamHandler extends Router { @@ -16,51 +15,46 @@ public ExternalStreamHandler() { manager = new ExternalStreamManager(this); } + // source: source of data public Response processEXSR(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "source"); + String validate; + if((validate = packet.validate("source")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - return ResponseFactory.response200(String.format("%s", manager.containsTemplate(packet.getData().toString()))); + return ResponseFactory.response200(String.format("%s", manager.containsTemplate(packet.getData("source")))); } + // key: key of the given stream public Response processEXST(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - return ResponseFactory.response200(String.format("%s", manager.containsStream(packet.getData().toString()))); + return ResponseFactory.response200(String.format("%s", manager.containsStream(packet.getData("key")))); } @SuppressWarnings("deprecation") + // source: source of the given stream + // auth_data[]: all keys associated with data public Response processINIT(Packet packet) { - // extract template from data - String data = packet.getData(); - String delim = Config.getProperty("app", "general.internal.delim"); - int delim_len = delim.length(); - int splitIndex = data.indexOf(delim); - String template = ""; - if(splitIndex != -1) { - template = data.substring(0, splitIndex).trim(); - data = data.substring(splitIndex + delim_len).trim(); - } else { - template = data; - data = ""; - } + String validate; + if((validate = packet.validate("source")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); + + String source = packet.getData("source"); // validate data - if(template.isEmpty()) - return ResponseFactory.response500("ExternalStreamHandler", "source"); - - String tempHash = manager.getHash(template, data); + String tempHash = manager.getHash(source, packet.getData()); if(manager.containsStream(tempHash)) return ResponseFactory.response220(tempHash); // attempt to add stream - Object[] output = manager.addStream(template, data); + Object[] output = manager.addStream(source, packet.getData()); boolean success = (Boolean) output[0]; String hash = (String) output[1]; if(!success) - return ResponseFactory.response420(template); + return ResponseFactory.response420(source); boolean authorized = manager.authorizeStream(hash); @@ -69,135 +63,122 @@ public Response processINIT(Packet packet) { return ResponseFactory.response200(String.format("%s", hash)); manager.removeStream(hash); - return ResponseFactory.response422(template); + return ResponseFactory.response422(source); } + // key: stream key public Response processIATH(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - if(!manager.containsStream(packet.getData())) - return ResponseFactory.response421(packet.getData()); + if(!manager.containsStream(packet.getData("key"))) + return ResponseFactory.response421(packet.getData("key")); - return ResponseFactory.response200(String.format("%s", manager.isStreamAuthorized(packet.getData()))); + return ResponseFactory.response200(String.format("%s", manager.isStreamAuthorized(packet.getData("key")))); } public Response processIATV(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - if(!manager.containsStream(packet.getData())) - return ResponseFactory.response421(packet.getData()); + String key = packet.getData("key"); + if(!manager.containsStream(key)) + return ResponseFactory.response421(key); - return ResponseFactory.response200(String.format("%s", manager.isStreamActive(packet.getData()))); + return ResponseFactory.response200(String.format("%s", manager.isStreamActive(key))); } public Response processEXEC(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - if(!manager.containsStream(packet.getData())) - return ResponseFactory.response421(packet.getData()); + String key = packet.getData("key"); + if(!manager.containsStream(key)) + return ResponseFactory.response421(key); - if(!manager.isStreamReady(packet.getData())) - return ResponseFactory.response423(packet.getData()); + if(!manager.isStreamReady(key)) + return ResponseFactory.response423(key); - if(manager.isStreamActive(packet.getData())) - return ResponseFactory.response424(packet.getData()); + if(manager.isStreamActive(key)) + return ResponseFactory.response424(key); - return ResponseFactory.response200(String.format("%s", manager.executeStream(packet.getData()))); + return ResponseFactory.response200(String.format("%s", manager.executeStream(key))); } public Response processKILL(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - if(!manager.containsStream(packet.getData())) - return ResponseFactory.response421(packet.getData()); + String key = packet.getData("key"); + if(!manager.containsStream(key)) + return ResponseFactory.response421(key); - if(!manager.isStreamActive(packet.getData())) - return ResponseFactory.response425(packet.getData()); + if(!manager.isStreamActive(key)) + return ResponseFactory.response425(key); - return ResponseFactory.response200(String.format("%s", manager.killStream(packet.getData()))); + return ResponseFactory.response200(String.format("%s", manager.killStream(key))); } public Response processSUBS(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "streamHash"); + String validate; + if((validate = packet.validate("key", "subscription")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - // extract hash from data - String type = packet.getData(); - int splitIndex = type.indexOf(','); - String hash = ""; - if(splitIndex != -1) { - hash = type.substring(0, splitIndex).trim(); - type = type.substring(splitIndex + 1).trim(); - } else { - return ResponseFactory.response500("ExternalStreamHandler", "subscriptionType"); - } + String key = packet.getData("key"); + String subscription = packet.getData("subscription"); - if(!manager.containsStream(hash)) - return ResponseFactory.response421(hash); + if(!manager.containsStream(key)) + return ResponseFactory.response421(key); - if(!manager.isStreamActive(hash)) - return ResponseFactory.response425(hash); + if(!manager.isStreamActive(key)) + return ResponseFactory.response425(key); - if(!manager.containsSubscriptionType(hash, type)) - return ResponseFactory.response426(hash, type); + if(!manager.containsSubscriptionType(key, subscription)) + return ResponseFactory.response426(key, subscription); - Object[] subscription = manager.subscribe(hash, type); + Object[] response = manager.subscribe(key, subscription); - if((Boolean)subscription[0]) + if((Boolean)response[0]) return ResponseFactory.response200(String.format("%s", "true")); - return ResponseFactory.response427(hash, type, (String)subscription[1]); + return ResponseFactory.response427(key, response[0].toString(), response[1].toString()); } public Response processRQST(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "key, query"); - - if(packet.getSubData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "destination"); + String validate; + if((validate = packet.validate("key", "request", "query", "destination")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - String[] data = packet.getData().split(Config.getProperty("app", "general.internal.delim")); + String key = packet.getData("key"); + String request = packet.getData("request"); - // standard request length is 2: - // key,.,request - if(data.length != 2) - return ResponseFactory.response501("Request is not formatted properly."); - - if(data[0].isEmpty() || data[1].isEmpty()) - return ResponseFactory.response500("ExternalStreamHandler", "key, query"); - - String hash = data[0]; - String[] request = data[1].split(Config.getProperty("app", "general.collection.delim")); - if(!manager.containsStream(hash)) - return ResponseFactory.response421(hash); + if(!manager.containsStream(key)) + return ResponseFactory.response421(key); - if(!manager.isStreamReady(hash)) - return ResponseFactory.response423(hash); + if(!manager.isStreamReady(key)) + return ResponseFactory.response423(key); - if(!manager.containsRequestType(hash, request[1])) - return ResponseFactory.response428(hash, request[1]); + if(!manager.containsRequestType(key, request)) + return ResponseFactory.response428(key, request); - Object[] response; - if(request.length == 2) - response = manager.request(hash, packet.getSubData(), request[1]); - else - response = manager.request(hash, packet.getSubData(), request[1], request[2]); + Object[] response = manager.request(key, packet.getData()); if((Boolean)response[0]) return ResponseFactory.response200(String.format("%s", (String)response[1])); - return ResponseFactory.response429(hash, request[0], (String)response[1]); + return ResponseFactory.response429(key, request, response[1].toString()); } public Response processTYPE(Packet packet) { - if(packet.getData().equals("")) - return ResponseFactory.response500("ExternalStreamHandler", "key"); + String validate; + if((validate = packet.validate("key")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - String key = packet.getData(); + String key = packet.getData("key"); if(!manager.containsStream(key)) return ResponseFactory.response421(key); diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamManager.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamManager.java index 78d45c4b..681a0a4d 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamManager.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/external/handler/ExternalStreamManager.java @@ -67,7 +67,7 @@ private void reflect() throws InstantiationException, IllegalAccessException, Il Reflections reflection = new Reflections("org.stream.external.connected.connections"); Set> types = reflection.getSubTypesOf(ExternalStreamConnection.class); for(Class c : types) - templates.put(c.getDeclaredConstructor(ExternalStreamManager.class, String.class).newInstance(this, "").getUUID(), c); + templates.put(c.getDeclaredConstructor(ExternalStreamManager.class, HashMap.class).newInstance(this, new HashMap()).getUUID(), c); } /** @@ -81,12 +81,12 @@ private void reflect() throws InstantiationException, IllegalAccessException, Il * stream will be unable to authorize. * @return String containing the hashed {@code data}. */ - protected String getHash(String template, String data) { + protected String getHash(String template, HashMap data) { if(!templates.containsKey(template)) return null; try { - return templates.get(template).getDeclaredConstructor(ExternalStreamManager.class, String.class).newInstance(this, "").getHash(data); + return templates.get(template).getDeclaredConstructor(ExternalStreamManager.class, HashMap.class).newInstance(this, new HashMap()).getHash(data); } catch (Exception e) { e.printStackTrace(); } @@ -191,13 +191,13 @@ protected boolean isStreamActive(String hash) { * the action was successful. The second object will return a {@link String} which contains the generated hash of the new stream. * If the initialization is unsuccessful, the second object will be {@code null}. */ - protected Object[] addStream(String type, String data) { + protected Object[] addStream(String type, HashMap data) { if(!templates.containsKey(type)) return new Object[] {false, null}; ExternalStreamConnection stream = null; try { - stream = templates.get(type).getDeclaredConstructor(ExternalStreamManager.class, String.class).newInstance(this, data); + stream = templates.get(type).getDeclaredConstructor(ExternalStreamManager.class, HashMap.class).newInstance(this, data); streams.put(stream.getHash(), stream); } catch (Exception e) { e.printStackTrace(); @@ -312,7 +312,7 @@ protected boolean containsRequestType(String hash, String type) { * @param request Request data used for processing the single request. * @return Returns a string object containing all data returned by the request. */ - protected Object[] request(String hash, String destination, String request) { + protected Object[] request(String hash, HashMap request) { if(!streams.containsKey(hash)) return new Object[] {false, null}; @@ -320,30 +320,7 @@ protected Object[] request(String hash, String destination, String request) { if(!stream.isAuthorized() || !stream.isReady()) return new Object[] {false, null}; - return stream.request(destination, request); - } - - /** - * Sends a data request from the stream with the given hash. This request is in the form of a single - * (typically REST API) request, which will then return a series of data presented. - *
- * If a stream with the given hash does not exist, this function returns false. - * - * @param hash Hash of the stream returned by the {@link ExternalStreamConnection#getHash(String)} function. - * @param destination Destination of the request to be processed by the {@link ExternalStreamManager#process(String, String, String)} function. - * @param request Request data used for processing the single request. - * @param date Date of the {@code request} parameter to be accessed. - * @return Returns a string object containing all data returned by the request. - */ - protected Object[] request(String hash, String destination, String request, String date) { - if(!streams.containsKey(hash)) - return new Object[] {false, null}; - - ExternalStreamConnection stream = streams.get(hash); - if(!stream.isAuthorized() || !stream.isReady()) - return new Object[] {false, null}; - - return stream.request(destination, request, date); + return stream.request(request); } /** @@ -398,11 +375,11 @@ protected boolean killStream(String hash) { * @param data Data sent by the given subscription. */ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Config.getProperty("app", "general.data.dateformat")); - protected void processSubscription(String hash, String subscription, String destination, String data) { + protected void processSubscription(String hash, String subscription, String data) { // define subscribed date String date = LocalDate.now().format(formatter); String collection = subscription + Config.getProperty("app", "general.collection.delim") + date; - Response lsh_response = handler.send("LSH", "PUSH", String.format("%s%s%s", data, Config.getProperty("app", "general.internal.delim"), collection)); + Response lsh_response = handler.send("LSH", "PUSH", "data", data, "collection", collection); if(lsh_response.code() != 200) Logger.warn(lsh_response); } @@ -415,8 +392,8 @@ protected void processSubscription(String hash, String subscription, String dest * @param request Request which the data was received by. * @param data Data sent by the given subscription. */ - protected void processRequest(String hash, String request, String destination, String data) { - Response lsh_response = handler.send("LSH", "PUSH", String.format("%s%s%s", data, Config.getProperty("app", "general.internal.delim"), request)); + protected void processRequest(String hash, String request, String data) { + Response lsh_response = handler.send("LSH", "PUSH", "request", request, "data", data); if(lsh_response.code() != 200) Logger.warn(lsh_response); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/local/handler/LocalStreamHandler.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/local/handler/LocalStreamHandler.java index 958b8de0..18983fcb 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/local/handler/LocalStreamHandler.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/local/handler/LocalStreamHandler.java @@ -18,10 +18,11 @@ public LocalStreamHandler() { } public Response processINIT(Packet packet) { - if(packet.getData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "source"); + String validate; + if((validate = packet.validate("source")) != null) + return ResponseFactory.response500("LocalStreamHandler", validate); - String source = packet.getData(); + String source = packet.getData("source"); if(!manager.containsTemplate(source)) return ResponseFactory.response440(source); @@ -42,16 +43,17 @@ public Response processINIT(Packet packet) { } public Response processSCAN(Packet packet) { - if(packet.getData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "query"); + String validate; + if((validate = packet.validate("query")) != null) + return ResponseFactory.response500("LocalStreamHandler", validate); if(!manager.isReady()) return ResponseFactory.response441(manager.streamType()); - String[] query = packet.getData().split(Config.getProperty("stream", "mongodb.query.delim")); + String[] query = packet.getData("query").split(Config.getProperty("stream", "mongodb.query.delim")); if(!manager.validate(query)) - return ResponseFactory.response445(manager.streamType(), packet.getData()); + return ResponseFactory.response445(manager.streamType(), packet.getData("query")); if(manager.scan(query)) return ResponseFactory.response200("true"); @@ -61,53 +63,57 @@ public Response processSCAN(Packet packet) { //public Response process public Response processRQST(Packet packet) { - if(packet.getData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "request, query"); + String validate; + if((validate = packet.validate("uuid", "request", "query", "destination")) != null) + return ResponseFactory.response500("LocalStreamHandler", validate); - if(packet.getSubData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "destination"); - - String[] data = packet.getData().split(Config.getProperty("app", "general.internal.delim")); - String[] query; + String[] query = packet.getData("query").split(Config.getProperty("app", "general.data.delim")); // standard query - if(data.length == 1) { - query = data[0].split(Config.getProperty("app", "general.data.delim")); - } - - // date query - else if(data.length == 2) { - query = data[1].split(Config.getProperty("app", "general.data.delim")); - int collection_index = manager.getParameterTranslation(query[0], "collection"); - if(collection_index == -1) - return ResponseFactory.response501("Collection index is invalid."); - - // insert dated request into collection index - query[collection_index] = data[0].trim(); - +// if(data.length == 1) { +// query = data[0].split(Config.getProperty("app", "general.data.delim")); +// } +// +// // date query +// else if(data.length == 2) { +// query = data[1].split(Config.getProperty("app", "general.data.delim")); +// int collection_index = manager.getParameterTranslation(query[0], "collection"); +// if(collection_index == -1) +// return ResponseFactory.response501("Collection index is invalid."); +// +// // insert dated request into collection index +// query[collection_index] = data[0].trim(); +// +// } + + String request; + String delim = Config.getProperty("app", "general.collection.delim"); + if(packet.containsKey("date")) { + request = packet.getData("uuid" + delim + packet.getData("request") + delim + packet.getData("date")); + } else { + request = packet.getData("uuid" + delim + packet.getData("request")); } - // invalid internal language - else - return ResponseFactory.response502(); - if(query == null) return ResponseFactory.response501("Query array was null when attempting to process."); + if(request == null || request.isEmpty()) + return ResponseFactory.response501("Request was null when attempting to process."); + if(!manager.validate(query)) - return ResponseFactory.response445(manager.streamType(), packet.getData()); + return ResponseFactory.response445(manager.streamType(), packet.getData("query")); System.out.println(Arrays.toString(query)); if(!manager.scan(query)) - return ResponseFactory.response446(manager.streamType(), packet.getData()); + return ResponseFactory.response446(manager.streamType(), packet.getData("query")); Set output = manager.get(query); if(output == null) - return ResponseFactory.response447(manager.streamType(), packet.getData()); + return ResponseFactory.response447(manager.streamType(), packet.getData("query")); Response response; for(String line : output) { - response = send("SRC", "EDAT", String.format("%s", line), packet.getSubData()); + response = send("SRC", "EDAT", "data", line, "destination", packet.getData("destination")); if(response.code() != 200) return response; } @@ -116,29 +122,30 @@ else if(data.length == 2) { } public Response processSTAT(Packet packet) { - if(packet.getData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "query"); + String validate; + if((validate = packet.validate("query")) != null) + return ResponseFactory.response500("LocalStreamHandler", validate); if(!manager.isReady()) return ResponseFactory.response441(manager.streamType()); - String[] query = packet.getData().split(Config.getProperty("stream", "mongodb.query.delim")); + String[] query = packet.getData("query").split(Config.getProperty("stream", "mongodb.query.delim")); if(!manager.validate(query)) - return ResponseFactory.response445(manager.streamType(), packet.getData()); + return ResponseFactory.response445(manager.streamType(), packet.getData("query")); if(!manager.scan(query)) - return ResponseFactory.response446(manager.streamType(), packet.getData()); + return ResponseFactory.response446(manager.streamType(), packet.getData("query")); DataState state = manager.state(query); if(state == DataState.INVALID) - return ResponseFactory.response448(manager.streamType(), packet.getData()); + return ResponseFactory.response448(manager.streamType(), packet.getData("query")); return ResponseFactory.response200(state.toString()); } - public Response processMODI(Packet packet) { - return ResponseFactory.response501(); +// public Response processMODI(Packet packet) { +// return ResponseFactory.response501(); // if(packet.getData().isEmpty()) // return ResponseFactory.response500("LocalStreamHandler", "query"); // @@ -151,23 +158,19 @@ public Response processMODI(Packet packet) { // if(!manager.scan(packet.getData())) // return ResponseFactory.response446(manager.streamType(), packet.getData()); // - } +// } public Response processPUSH(Packet packet) { // data format: data, location... - if(packet.getData().isEmpty()) - return ResponseFactory.response500("LocalStreamHandler", "data, collection"); - - String[] data = packet.getData().split(Config.getProperty("app", "general.internal.delim")); - if(data.length != 2) - return ResponseFactory.response500("LocalStreamHandler", "collection"); - String collection = data[1]; + String validate; + if((validate = packet.validate("data", "collection")) != null) + return ResponseFactory.response500("LocalStreamHandler", validate); if(!manager.isReady()) return ResponseFactory.response441(manager.streamType()); - if(!manager.push(data[0], collection)) - return ResponseFactory.response449(manager.streamType(), data[0], collection); + if(!manager.push(packet.getData("data"), packet.getData("collection"))) + return ResponseFactory.response449(manager.streamType(), packet.getData("data"), packet.getData("collection")); return ResponseFactory.response200(); } diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/registry/StreamRegistryController.java b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/registry/StreamRegistryController.java index 45a00550..7e5d83e2 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/registry/StreamRegistryController.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/main/java/org/stream/registry/StreamRegistryController.java @@ -2,6 +2,7 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -18,136 +19,133 @@ public StreamRegistryController() { } public Response processEXSR(Packet packet) { - return send("ESH", "EXSR", packet.getData(), packet.getSubData()); + return send("ESH", "EXSR", packet.getData()); } public Response processEXST(Packet packet) { - return send("ESH", "EXST", packet.getData(), packet.getSubData()); + return send("ESH", "EXST", packet.getData()); } public Response processINIT(Packet packet) { - return send("ESH", "INIT", packet.getData(), packet.getSubData()); + return send("ESH", "INIT", packet.getData()); } public Response processIATH(Packet packet) { - return send("ESH", "IATH", packet.getData(), packet.getSubData()); + return send("ESH", "IATH", packet.getData()); } public Response processIATV(Packet packet) { - return send("ESH", "IATV", packet.getData(), packet.getSubData()); + return send("ESH", "IATV", packet.getData()); } public Response processEXEC(Packet packet) { - return send("ESH", "EXEC", packet.getData(), packet.getSubData()); + return send("ESH", "EXEC", packet.getData()); } public Response processKILL(Packet packet) { - return send("ESH", "KILL", packet.getData(), packet.getSubData()); + return send("ESH", "KILL", packet.getData()); } public Response processSUBS(Packet packet) { - return send("ESH", "SUBS", packet.getData(), packet.getSubData()); + return send("ESH", "SUBS", packet.getData()); } public Response processEDAT(Packet packet) { - return send("OUT", "EDAT", packet.getData(), packet.getSubData()); + return send("OUT", "EDAT", packet.getData()); } public Response processSCAN(Packet packet) { - return send("LSH", "SCAN", packet.getData(), packet.getSubData()); + return send("LSH", "SCAN", packet.getData()); } private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Config.getProperty("app", "general.data.dateformat")); public Response processRQST(Packet packet) { // Define passed properties. Types: - // Dated: data=key,.,start_date,.,end_date,.,request,.,query - // subdata=destination - // Not Dated: data=key,.,request,.,query - // subdata=destination + // Dated: data=key, start_date, end_date, request, query, destination + // Not Dated: data=key, request, query, destination - if(packet.getData().isEmpty()) - return ResponseFactory.response500("StreamRegistryController", "key, start_date, end_date, request, query"); + String validate; + if((validate = packet.validate("key", "request", "query", "destination")) != null) + return ResponseFactory.response500("ExternalStreamHandler", validate); - if(packet.getSubData().isEmpty()) - return ResponseFactory.response500("StreamRegistryController", "destination"); - - String[] data = packet.getData().split(Config.getProperty("app", "general.internal.delim")); + // check to see if request is dated + boolean dated = false; + if(packet.containsKey("start_date") || packet.containsKey("end_date")) { + if((validate = packet.validate("start_date", "end_date")) != null) + return ResponseFactory.response500("StreamRegistryController", validate); + + dated = true; + } - for(String d : data) - if(d.isEmpty()) - return ResponseFactory.response500("StreamRegistryController", "key, start_date, end_date, request, query"); + // extract packet data + HashMap data = packet.getData(); - // retrieve stream key - Response type_response = send("ESH", "TYPE", data[0]); + // retrieve stream type based on key + Response type_response = send("ESH", "TYPE", data); if(type_response.code() != 200) return type_response; + // retrieve uuid of the data String uuid = type_response.data(); + data.put("uuid", uuid); // not dated - if(data.length == 3) { - Response lsh_response = send("LSH", "RQST", data[2]); + if(!dated) { + Response lsh_response = send("LSH", "RQST", data); + // if data does not exist send request to external stream handler if(lsh_response.code() == 446) - return send("ESH", "RQST", format(data[0], data[1]), packet.getSubData()); - return lsh_response; + send("ESH", "RQST", data); + return send("LSH", "RQST", data); } // dated - else if(data.length == 5) { + else if(dated) { try { - LocalDate start = LocalDate.parse(data[1], formatter); - LocalDate end = LocalDate.parse(data[2], formatter); + LocalDate start = LocalDate.parse(packet.getData("start_date"), formatter); + LocalDate end = LocalDate.parse(packet.getData("end_date"), formatter); List dates = start.datesUntil(end).collect(Collectors.toList()); // invalid date processing if(dates.isEmpty()) throw new Exception(); - String request; Response lsh_response, esh_response; for(LocalDate date : dates) { // perform requests - request = uuid + Config.getProperty("app", "general.collection.delim") + data[3] + Config.getProperty("app", "general.collection.delim") + date.format(formatter); - lsh_response = send("LSH", "RQST", format(request, data[4]), packet.getSubData()); + + // initial request + data.put("date", date.format(formatter)); + lsh_response = send("LSH", "RQST", data); if(lsh_response.code() == 200) continue; + // if data does not exist if(lsh_response.code() == 446) { - esh_response = send("ESH", "RQST", format(data[0], request), packet.getSubData()); + esh_response = send("ESH", "RQST", data); if(esh_response.code() != 200) return esh_response; - } else { + } + + // invalid request + else { return lsh_response; } - - lsh_response = send("LSH", "RQST", format(request, data[4]), packet.getSubData()); + // request again + lsh_response = send("LSH", "RQST", data); if(lsh_response.code() != 200) return lsh_response; } } catch(Exception e) { - return ResponseFactory.response503(Config.getProperty("app", "general.data.dateformat"), data[1], data[2]); + return ResponseFactory.response503(Config.getProperty("app", "general.data.dateformat"), packet.getData("start_date"), packet.getData("end_date")); } } // invalid query else { - return ResponseFactory.response500("StreamRegistryController", "key, start_date, end_date, request, query"); + return ResponseFactory.response501("Boolean set to non binary value in cache."); } return ResponseFactory.response200(); } - - private static String format(String... objects) { - StringBuilder out = new StringBuilder(); - String delim = Config.getProperty("app", "general.internal.delim"); - for(int i = 0; i < objects.length; i++) { - out.append(objects[i].trim()); - if(i != objects.length - 1) - out.append(delim); - } - - return out.toString(); - - } } \ No newline at end of file diff --git a/DeFi-Data-Engine/DeFi Data Engine/src/test/java/test/protocols/TestSRC.java b/DeFi-Data-Engine/DeFi Data Engine/src/test/java/test/protocols/TestSRC.java index 957d7c71..5bae1cab 100644 --- a/DeFi-Data-Engine/DeFi Data Engine/src/test/java/test/protocols/TestSRC.java +++ b/DeFi-Data-Engine/DeFi Data Engine/src/test/java/test/protocols/TestSRC.java @@ -14,133 +14,136 @@ public class TestSRC { static { // disable loggers LogManager.getRootLogger().setLevel(Level.OFF); - Config.setProperty("output", "consumer.types", "null"); - Config.setProperty("output", "producer.types", "null"); - Config.setProperty("output", "local.stream.type", "null"); + Config.setProperty("stream", "general.consumer.types", "null"); + Config.setProperty("stream", "general.producer.types", "null"); + Config.setProperty("stream", "local.stream.type", "null"); } @Test public void TestEXSR() { Core core = new Core(); - assertEquals(200, core.send("SRC", "EXSR", "external_template").code()); - assertEquals("true", core.send("SRC", "EXSR", "external_template").data()); - assertEquals("false", core.send("SRC", "EXSR", "template").data()); + assertEquals(200, core.send("SRC", "EXSR", "source", "external_template").code()); + assertEquals("true", core.send("SRC", "EXSR", "source", "external_template").data()); + assertEquals("false", core.send("SRC", "EXSR", "source", "template").data()); - assertEquals(500, core.send("SRC", "EXSR", "").code()); + assertEquals(500, core.send("SRC", "EXSR", "source", "").code()); + assertEquals(500, core.send("SRC", "EXSR", "dne", "").code()); } @Test public void TestEXST() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); - assertEquals("true", core.send("SRC", "EXST", "key").data()); - assertEquals("false", core.send("SRC", "EXST", "key1").data()); + assertEquals("true", core.send("SRC", "EXST", "key", "key").data()); + assertEquals("false", core.send("SRC", "EXST", "key", "key1").data()); - assertEquals(500, core.send("SRC", "EXST", "").code()); + assertEquals(500, core.send("SRC", "EXST", "key", "").code()); + assertEquals(500, core.send("SRC", "EXST", "dne", "").code()); } @Test public void TestINIT() { Core core = new Core(); // successful authorization - Response valid = core.send("SRC", "INIT", "external_template, key"); + Response valid = core.send("SRC", "INIT", "source", "external_template", "key", "key"); assertEquals(200, valid.code()); - assertEquals("true, key", valid.data()); - assertEquals("true", core.send("SRC", "EXST", "key").data()); + assertEquals("key", valid.data()); + assertEquals("true", core.send("SRC", "EXST", "key", "key").data()); - assertEquals(220, core.send("SRC", "INIT", "external_template, key").code()); + assertEquals(220, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); - assertEquals(420, core.send("SRC", "INIT", "does_not_exist").code()); - assertEquals(422, core.send("SRC", "INIT", "external_template, wrong").code()); - assertEquals(422, core.send("SRC", "INIT", "external_template").code()); - assertEquals(500, core.send("SRC", "INIT", "").code()); + assertEquals(420, core.send("SRC", "INIT", "source", "does_not_exist").code()); + assertEquals(422, core.send("SRC", "INIT", "source", "external_template", "key", "wrong").code()); + assertEquals(422, core.send("SRC", "INIT", "source", "external_template").code()); + assertEquals(500, core.send("SRC", "INIT", "dne", "").code()); } @Test public void TestIATH() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); - assertEquals(200, core.send("SRC", "IATH", "key").code()); - assertEquals("true", core.send("SRC", "IATH", "key").data()); + assertEquals(200, core.send("SRC", "IATH", "key", "key").code()); + assertEquals("true", core.send("SRC", "IATH", "key", "key").data()); - assertEquals(421, core.send("SRC", "IATH", "does_not_exist").code()); - assertEquals(500, core.send("SRC", "IATH", "").code()); + assertEquals(421, core.send("SRC", "IATH", "key", "does_not_exist").code()); + assertEquals(500, core.send("SRC", "IATH", "key", "").code()); } @Test public void TestIATV() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); - assertEquals("false", core.send("SRC", "IATV", "key").data()); - assertEquals(200, core.send("SRC", "EXEC", "key").code()); - assertEquals("true", core.send("SRC", "IATV", "key").data()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); + assertEquals("false", core.send("SRC", "IATV", "key", "key").data()); + assertEquals(200, core.send("SRC", "EXEC", "key", "key").code()); + assertEquals("true", core.send("SRC", "IATV", "key", "key").data()); - assertEquals(421, core.send("SRC", "IATV", "does_not_exist").code()); - assertEquals(500, core.send("SRC", "IATV", "").code()); + assertEquals(421, core.send("SRC", "IATV", "key", "does_not_exist").code()); + assertEquals(500, core.send("SRC", "IATV", "key", "").code()); } @Test public void TestEXEC() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); - assertEquals(200, core.send("SRC", "INIT", "external_template, not_ready, true").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "not_ready", "override", "true").code()); - assertEquals(200, core.send("SRC", "EXEC", "key").code()); - assertEquals("true", core.send("SRC", "IATH", "key").data()); - assertEquals("true", core.send("SRC", "IATV", "key").data()); + assertEquals(200, core.send("SRC", "EXEC", "key", "key").code()); + assertEquals("true", core.send("SRC", "IATH", "key", "key").data()); + assertEquals("true", core.send("SRC", "IATV", "key", "key").data()); - assertEquals(421, core.send("SRC", "EXEC", "does_not_exist").code()); - assertEquals(423, core.send("SRC", "EXEC", "not_ready").code()); - assertEquals(424, core.send("SRC", "EXEC", "key").code()); + assertEquals(421, core.send("SRC", "EXEC", "key", "does_not_exist").code()); + assertEquals(423, core.send("SRC", "EXEC", "key", "not_ready").code()); + assertEquals(424, core.send("SRC", "EXEC", "key", "key").code()); } @Test public void TestKILL() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); - assertEquals(200, core.send("SRC", "EXEC", "key").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); + assertEquals(200, core.send("SRC", "EXEC", "key", "key").code()); - assertEquals("true", core.send("SRC", "IATV", "key").data()); - assertEquals("true", core.send("SRC", "KILL", "key").data()); - assertEquals("false", core.send("SRC", "IATV", "key").data()); + assertEquals("true", core.send("SRC", "IATV", "key", "key").data()); + assertEquals("true", core.send("SRC", "KILL", "key", "key").data()); + assertEquals("false", core.send("SRC", "IATV", "key", "key").data()); - assertEquals(421, core.send("SRC", "KILL", "does_not_exist").code()); - assertEquals(425, core.send("SRC", "KILL", "key").code()); - assertEquals(500, core.send("SRC", "KILL", "").code()); + assertEquals(421, core.send("SRC", "KILL", "key", "does_not_exist").code()); + assertEquals(425, core.send("SRC", "KILL", "key", "key").code()); + assertEquals(500, core.send("SRC", "KILL", "key", "").code()); } @Test public void TestSUBS() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); - assertEquals(200, core.send("SRC", "EXEC", "key").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); + assertEquals(200, core.send("SRC", "EXEC", "key", "key").code()); - assertEquals("true", core.send("SRC", "SUBS", "key, correct").data()); + assertEquals("true", core.send("SRC", "SUBS", "key", "key", "subscription", "correct").data()); - assertEquals(421, core.send("SRC", "SUBS", "does_not_exist, correct").code()); - assertEquals(200, core.send("SRC", "KILL", "key").code()); - assertEquals(425, core.send("SRC", "SUBS", "key, correct").code()); - assertEquals(200, core.send("SRC", "EXEC", "key").code()); - assertEquals(426, core.send("SRC", "SUBS", "key, does_not_exist").code()); - assertEquals(427, core.send("SRC", "SUBS", "key, irregular").code()); + assertEquals(421, core.send("SRC", "SUBS", "key", "does_not_exist", "subscription", "correct").code()); + assertEquals(200, core.send("SRC", "KILL", "key", "key").code()); + assertEquals(425, core.send("SRC", "SUBS", "key", "key", "subscription", "correct").code()); + assertEquals(200, core.send("SRC", "EXEC", "key", "key").code()); + assertEquals(426, core.send("SRC", "SUBS", "key", "key", "subscription", "does_not_exist").code()); + assertEquals(427, core.send("SRC", "SUBS", "key", "key", "subscription", "irregular").code()); } @Test public void TestRQST() { Core core = new Core(); - assertEquals(200, core.send("SRC", "INIT", "external_template, key").code()); - assertEquals(200, core.send("SRC", "INIT", "external_template, not_ready, true").code()); + assertEquals(200, core.send("SRC", "INIT", "source", "external_template", "key", "key").code()); + assertEquals(200, core.send("SRC", "INIT", "external_template", "key", "not_ready").code()); + assertEquals(200, core.send("SRC", "RQST", "key, correct", "destination").code()); assertEquals(200, core.send("SRC", "RQST", "key, correct", "destination").code()); assertEquals(421, core.send("SRC", "RQST", "does_not_exist, correct", "destination").code()); diff --git a/DeFi-Data-Engine/Rest Application/pom.xml b/DeFi-Data-Engine/Rest Application/pom.xml index 9644e635..4937af40 100644 --- a/DeFi-Data-Engine/Rest Application/pom.xml +++ b/DeFi-Data-Engine/Rest Application/pom.xml @@ -11,14 +11,13 @@ org.out.connections rest-connection 4.3.3 - war + jar restconnection Rest Connection for DeFi Data Engine - 18 - 1.18 - 1.18 - 2.6.0 + 17 + 17 + 17 0.8.3.Final @@ -53,8 +52,6 @@ - - @@ -63,5 +60,4 @@ - diff --git a/DeFi-Data-Engine/Rest Application/src/main/java/org/properties/Config.java b/DeFi-Data-Engine/Rest Application/src/main/java/org/properties/Config.java index 6d51c933..90708126 100644 --- a/DeFi-Data-Engine/Rest Application/src/main/java/org/properties/Config.java +++ b/DeFi-Data-Engine/Rest Application/src/main/java/org/properties/Config.java @@ -1,7 +1,5 @@ package org.properties; -import java.io.File; -import java.io.FileInputStream; import java.util.HashMap; import java.util.Properties; @@ -10,23 +8,40 @@ public class Config { private static final HashMap properties; static { +// properties = new HashMap(); +// +// String[] files = new File("config").list(); +// +// for(String file : files) { +// if(file.lastIndexOf(".properties") == file.length() - 11) { +// String name = file.substring(0, file.length() - 11); +// properties.put(name, new Properties()); +// +// try (FileInputStream in = new FileInputStream("config/" + file)) { +// properties.get(name).load(in); +// } catch(Exception e) { +// e.printStackTrace(); +// System.exit(1); +// } +// } +// } + properties = new HashMap(); - String[] files = new File("src/main/resources/config").list(); + Properties app_properties = new Properties(); + app_properties.put("", ""); + app_properties.put("general.internal.delim", ":::"); + app_properties.put("general.data.delim", ","); + app_properties.put("general.collection.delim", "="); + app_properties.put("general.transfer.delim", "&&&"); + app_properties.put("general.data.dateformat", "yyyy-MM-dd"); + app_properties.put("spring.server.port", "8080"); + app_properties.put("rest.socket.address", "localhost"); + app_properties.put("rest.socket.port", "61100"); + app_properties.put("rest.socket.key", "rest-key-reserved"); + properties.put("app", app_properties); - for(String file : files) { - if(file.lastIndexOf(".properties") == file.length() - 11) { - String name = file.substring(0, file.length() - 11); - properties.put(name, new Properties()); - - try (FileInputStream in = new FileInputStream("src/main/resources/config/" + file)) { - properties.get(name).load(in); - } catch(Exception e) { - e.printStackTrace(); - System.exit(1); - } - } - } + //properties.put("testing", new Properties()); } public static final Properties getProperties(String name) { diff --git a/DeFi-Data-Engine/Rest Application/src/main/java/org/rest/application/RestApplication.java b/DeFi-Data-Engine/Rest Application/src/main/java/org/rest/application/RestApplication.java index c37eb161..19e0d62a 100644 --- a/DeFi-Data-Engine/Rest Application/src/main/java/org/rest/application/RestApplication.java +++ b/DeFi-Data-Engine/Rest Application/src/main/java/org/rest/application/RestApplication.java @@ -4,7 +4,7 @@ import java.net.UnknownHostException; import java.util.Collections; -import org.properties.Config; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -14,7 +14,7 @@ public class RestApplication { public static void main(String[] args) throws InterruptedException, UnknownHostException, IOException { SpringApplication app = new SpringApplication(RestApplication.class); app.setDefaultProperties(Collections.singletonMap( - "server.port", Config.getProperty("app", "spring.server.port"))); + "server.port", "8080")); app.run(args); } } \ No newline at end of file diff --git a/DeFi-Data-Engine/Testing Environment/pom.xml b/DeFi-Data-Engine/Testing Environment/pom.xml index bdff32dc..e38f29b7 100644 --- a/DeFi-Data-Engine/Testing Environment/pom.xml +++ b/DeFi-Data-Engine/Testing Environment/pom.xml @@ -40,6 +40,11 @@ spring-kafka 2.9.0 + + org.json + json + 20220320 + diff --git a/DeFi-Data-Engine/Testing Environment/src/test/connection/socket/SocketConnectionTest.java b/DeFi-Data-Engine/Testing Environment/src/test/connection/socket/SocketConnectionTest.java index 1b139929..4d447d4c 100644 --- a/DeFi-Data-Engine/Testing Environment/src/test/connection/socket/SocketConnectionTest.java +++ b/DeFi-Data-Engine/Testing Environment/src/test/connection/socket/SocketConnectionTest.java @@ -8,8 +8,11 @@ import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; + import javax.net.SocketFactory; +import org.json.JSONObject; + public class SocketConnectionTest { public static void main(String[] args) throws UnknownHostException, IOException { @@ -33,21 +36,26 @@ public void run() { thread.start(); //TODO FIX INTEGRATION WITH REST API - System.out.println("SOURCE_EXISTS RESPONSE: " + request("http://localhost:8080/defi/v1/rest/source_exists?source=external_template")); - System.out.println("INIT RESPONSE: " + request("http://localhost:8080/defi/v1/rest/initialize?source=external_template&auth_data=key")); - System.out.println("STREAM_EXISTS RESPONSE: " + request("http://localhost:8080/defi/v1/rest/stream_exists?key=key")); - System.out.println("IS_AUTHORIZED RESPONSE: " + request("http://localhost:8080/defi/v1/rest/is_authorized?key=key")); +// System.out.println("SOURCE_EXISTS RESPONSE: " + request("http://localhost:8080/defi/v1/rest/source_exists?source=polygon")); +// System.out.println("INIT RESPONSE: " + request("http://localhost:8080/defi/v1/rest/initialize?source=polygon&auth_data=key")); +// System.out.println("STREAM_EXISTS RESPONSE: " + request("http://localhost:8080/defi/v1/rest/stream_exists?key=key")); +// System.out.println("IS_AUTHORIZED RESPONSE: " + request("http://localhost:8080/defi/v1/rest/is_authorized?key=key")); + + String rqst = request("http://localhost:8080/defi/v1/rest/initialize?source=polygon&auth_data=vtTMMRtEywJ_owkHdqoRUmv9vf2hWkrV"); + JSONObject init = new JSONObject(rqst); + System.out.println(rqst); + String hash = init.getString("data"); - System.out.println("RQST RESPONSE: " + request( + System.out.println("RESPONSE: " + request( String.format("http://localhost:8080/defi/v1/rest/request_dated?destination=%s" - + "&key=key" - + "&request=template-external-request" - + "&query=get_all,template-external-request" - + "&start_date=10-09-2022" - + "&end_date=14-09-2022", key))); + + "&key=%s" + + "&request=bar-AAPL-15m" + + "&query=get_all,bar-AAPL-15m" + + "&start_date=2022-09-20" + + "&end_date=2022-09-23", key, hash))); } - public static String request(String str, String... params) throws IOException { + public static String request(String str) throws IOException { URL obj = new URL(str); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("GET");