diff --git a/README.md b/README.md
index a98359f..3f9463b 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This is a microservice-libary for java of cryptic-game.
## Quick-Start
-The [EchoMicroService.java](https://github.com/cryptic-game/java-lib/blob/master/src/test/java/net/cryptic_game/microservice/EchoMicroService.java) implements an `EchoMicroService`.
+Just use the [microservice template](https://github.com/cryptic-game/microservice-java-template) to use the latest version of this library.
## Maven
diff --git a/microservice.iml b/microservice.iml
new file mode 100644
index 0000000..8ea2cde
--- /dev/null
+++ b/microservice.iml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 769bb19..2757499 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,78 +1,84 @@
- 4.0.0
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
- net.cryptic-game
- microservice
- 0.1.1
- jar
+ net.cryptic-game
+ microservice
+ 0.1.1
+ jar
- cryptic-game-microservice-lib
- offical microservice-lib of cryptic-game for java
- https://cryptic-game.net
+ cryptic-game-microservice-lib
+ offical microservice-lib of cryptic-game for java
+ https://cryptic-game.net
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.0
-
- 1.8
- 1.8
-
-
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ 1.8
+ 1.8
+
+
+
+
-
- UTF-8
-
+
+ UTF-8
+
-
-
- jitpack.io
- https://jitpack.io
-
-
+
+
+ jitpack.io
+ https://jitpack.io
+
+
-
-
- junit
- junit
- 3.8.1
- test
-
-
- io.netty
- netty-all
- 4.1.34.Final
-
-
- com.googlecode.json-simple
- json-simple
- 1.1.1
-
-
- log4j
- log4j
- 1.2.17
-
-
- org.xerial
- sqlite-jdbc
- 3.27.2
-
-
- mysql
- mysql-connector-java
- 8.0.15
-
-
- org.reflections
- reflections-maven
- 0.9.8
-
-
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.5.1
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 3.0.0
+ test
+
+
+ io.netty
+ netty-all
+ 4.1.34.Final
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.27.2
+
+
+ mysql
+ mysql-connector-java
+ 8.0.15
+
+
+ org.reflections
+ reflections-maven
+ 0.9.8
+
+
diff --git a/src/main/java/net/cryptic_game/microservice/MicroService.java b/src/main/java/net/cryptic_game/microservice/MicroService.java
index bebf9c5..cd6b7d0 100644
--- a/src/main/java/net/cryptic_game/microservice/MicroService.java
+++ b/src/main/java/net/cryptic_game/microservice/MicroService.java
@@ -9,6 +9,7 @@
import java.util.Set;
import java.util.UUID;
+import net.cryptic_game.microservice.utils.JSONUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
@@ -36,280 +37,224 @@
public abstract class MicroService extends SimpleChannelInboundHandler {
- private static MicroService instance = null;
+ private static final boolean EPOLL = Epoll.isAvailable();
- public static MicroService getInstance() {
- return instance;
- }
+ private static MicroService instance;
- private static final boolean EPOLL = Epoll.isAvailable();
+ private Map inter = new HashMap();
- private Map inter = new HashMap();
+ private Map, Tuple> userEndpoints = new HashMap<>();
+ private Map, Tuple> microserviceEndpoints = new HashMap<>();
- private Map, Tuple> userEndpoints = new HashMap, Tuple>();
- private Map, Tuple> microserviceEndpoints = new HashMap, Tuple>();
+ private String name;
+ private Channel channel;
- private String name;
- private Channel channel;
+ public static MicroService getInstance() {
+ return instance;
+ }
- public MicroService(String name) {
- this.name = name;
+ public MicroService(String name) {
+ this.name = name;
- instance = this;
+ instance = this;
- this.init();
- this.start();
- }
+ this.init();
+ this.start();
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- private void start() {
- EventLoopGroup group = EPOLL ? new EpollEventLoopGroup() : new NioEventLoopGroup();
+ private void start() {
+ EventLoopGroup group = EPOLL ? new EpollEventLoopGroup() : new NioEventLoopGroup();
- try {
- Map test = new HashMap();
+ try {
+ JSONObject registration = JSONUtils.json().add("action", "register").add("name", this.getName()).build();
+
+ Channel channel = new Bootstrap().group(group)
+ .channel(EPOLL ? EpollSocketChannel.class : NioSocketChannel.class)
+ .handler(new MicroServiceInitializer(this))
+ .connect(Config.get(DefaultConfig.MSSOCKET_HOST), Config.getInteger(DefaultConfig.MSSOCKET_PORT))
+ .sync().channel();
- test.put("action", "register");
- test.put("name", this.getName());
+ this.channel = channel;
+
+ channel.writeAndFlush(registration.toString());
- Channel channel = new Bootstrap().group(group)
- .channel(EPOLL ? EpollSocketChannel.class : NioSocketChannel.class)
- .handler(new MicroServiceInitializer(this))
- .connect(Config.get(DefaultConfig.MSSOCKET_HOST), Config.getInteger(DefaultConfig.MSSOCKET_PORT))
- .sync().channel();
+ channel.closeFuture().syncUninterruptibly();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void init() {
+ Reflections reflections = new Reflections("net.cryptic_game.microservice", new MethodAnnotationsScanner());
+ {
+ Set methods = reflections.getMethodsAnnotatedWith(UserEndpoint.class);
+ for (Method method : methods) {
+ UserEndpoint methodEndpoint = method.getAnnotation(UserEndpoint.class);
- this.channel = channel;
-
- channel.writeAndFlush(new JSONObject(test).toString());
-
- channel.closeFuture().syncUninterruptibly();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- private void init() {
- Reflections reflections = new Reflections("net.cryptic_game.microservice", new MethodAnnotationsScanner());
- {
- Set methods = reflections.getMethodsAnnotatedWith(UserEndpoint.class);
- for (Method method : methods) {
- UserEndpoint methodEndpoint = method.getAnnotation(UserEndpoint.class);
-
- userEndpoints.put(Arrays.asList(methodEndpoint.path()),
- new Tuple(methodEndpoint, method));
- }
- }
- {
- Set methods = reflections.getMethodsAnnotatedWith(MicroserviceEndpoint.class);
- for (Method method : methods) {
- MicroserviceEndpoint methodEndpoint = method.getAnnotation(MicroserviceEndpoint.class);
-
- microserviceEndpoints.put(Arrays.asList(methodEndpoint.path()),
- new Tuple(methodEndpoint, method));
- }
- }
- }
-
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, String msg) {
- final MicroService m = this;
-
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- JSONObject obj = new JSONObject();
- try {
- obj = (JSONObject) new JSONParser().parse(msg);
- } catch (ParseException e) {
- }
-
- if (obj.containsKey("tag") && obj.get("tag") instanceof String && obj.containsKey("data")
- && obj.get("data") instanceof JSONObject) {
- JSONObject data = (JSONObject) obj.get("data");
-
- UUID tag = UUID.fromString((String) obj.get("tag"));
-
- if (obj.containsKey("endpoint") && obj.get("endpoint") instanceof JSONArray) {
- Object[] endpointArr = ((JSONArray) obj.get("endpoint")).toArray();
- String[] endpoint = Arrays.copyOf(endpointArr, endpointArr.length, String[].class);
-
- if (obj.containsKey("user") && obj.get("user") instanceof String) {
- UUID user = UUID.fromString((String) obj.get("user"));
-
- JSONObject responseData = handle(endpoint, data, user);
-
- Map response = new HashMap();
-
- response.put("tag", tag.toString());
- response.put("data", responseData);
-
- m.send(ctx.channel(), new JSONObject(response));
- } else if (obj.containsKey("ms") && obj.get("ms") instanceof String) {
- String ms = (String) obj.get("ms");
-
- if (!m.inter.containsKey(tag)) {
- m.sendToMicroService(ms, handleFromMicroService(endpoint, data, ms), tag);
- } else {
- m.inter.replace(tag, data);
- }
- }
- }
- }
- }
- }).start();
- }
-
- public JSONObject handle(String[] endpointArray, JSONObject data, UUID user) {
- List endpoint = Arrays.asList(endpointArray);
-
- if (userEndpoints.containsKey(endpoint)) {
- Tuple tuple = userEndpoints.get(endpoint);
-
- UserEndpoint e = tuple.getA();
- Method eMethod = tuple.getB();
- if (checkData(e.keys(), e.types(), data)) {
- try {
- JSONObject result = (JSONObject) eMethod.invoke(new Object(), data, user);
-
- if (result == null) {
- result = new JSONObject(new HashMap());
- }
-
- return result;
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "internal error");
-
- return new JSONObject(jsonMap);
- }
- } else {
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "invalid input data");
-
- return new JSONObject(jsonMap);
- }
- }
-
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "unknown service");
-
- return new JSONObject(jsonMap);
- }
-
- public JSONObject handleFromMicroService(String[] endpointArray, JSONObject data, String ms) {
- List endpoint = Arrays.asList(endpointArray);
-
- if (microserviceEndpoints.containsKey(endpoint)) {
- Tuple tuple = microserviceEndpoints.get(endpoint);
-
- MicroserviceEndpoint e = tuple.getA();
- Method eMethod = tuple.getB();
- if (checkData(e.keys(), e.types(), data)) {
- try {
- JSONObject result = (JSONObject) eMethod.invoke(new Object(), data, ms);
-
- if (result == null) {
- result = new JSONObject(new HashMap());
- }
-
- return result;
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "internal error");
-
- return new JSONObject(jsonMap);
- }
- } else {
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "invalid input data");
-
- return new JSONObject(jsonMap);
- }
- }
-
- Map jsonMap = new HashMap();
-
- jsonMap.put("error", "unknown service");
-
- return new JSONObject(jsonMap);
- }
-
- private void send(Channel channel, JSONObject obj) {
- channel.writeAndFlush(Unpooled.copiedBuffer(obj.toString(), CharsetUtil.UTF_8));
- }
-
- public void sendToMicroService(String ms, JSONObject data, UUID tag) {
- Map jsonMap = new HashMap();
-
- jsonMap.put("ms", ms);
- jsonMap.put("data", data);
- jsonMap.put("tag", tag.toString());
-
- this.send(channel, new JSONObject(jsonMap));
- }
-
- public void sendToUser(UUID user, JSONObject data) {
- Map jsonMap = new HashMap();
-
- jsonMap.put("action", "address");
- jsonMap.put("user", user.toString());
- jsonMap.put("data", data);
-
- this.send(this.channel, new JSONObject(jsonMap));
- }
-
- private static boolean checkData(String[] keys, Class>[] types, JSONObject obj) {
- for (int i = 0; i < keys.length; i++) {
- String key = keys[i];
- Class> type = types[i];
-
- if (!obj.containsKey(key) || obj.get(key).getClass() != type) {
- return false;
- }
- }
-
- return true;
- }
-
- public JSONObject contactMicroservice(String ms, String[] endpoint, JSONObject data) {
- UUID tag = UUID.randomUUID();
-
- Map jsonMap = new HashMap();
-
- jsonMap.put("ms", ms);
- jsonMap.put("data", data);
- jsonMap.put("endpoint", Arrays.asList(endpoint));
- jsonMap.put("tag", tag.toString());
-
- this.send(channel, new JSONObject(jsonMap));
-
- this.inter.put(tag, null);
-
- int counter = 0;
-
- while (this.inter.get(tag) == null) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- counter++;
-
- if (counter > 100 * 30) {
- return null;
- }
- }
-
- return this.inter.remove(tag);
- }
+ userEndpoints.put(Arrays.asList(methodEndpoint.path()),
+ new Tuple<>(methodEndpoint, method));
+ }
+ }
+ {
+ Set methods = reflections.getMethodsAnnotatedWith(MicroserviceEndpoint.class);
+ for (Method method : methods) {
+ MicroserviceEndpoint methodEndpoint = method.getAnnotation(MicroserviceEndpoint.class);
+
+ microserviceEndpoints.put(Arrays.asList(methodEndpoint.path()),
+ new Tuple<>(methodEndpoint, method));
+ }
+ }
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, String msg) {
+ new Thread(() -> {
+
+ JSONObject obj = new JSONObject();
+ try {
+ obj = (JSONObject) new JSONParser().parse(msg);
+ } catch (ParseException e) {
+ }
+
+ if (obj.containsKey("tag") && obj.get("tag") instanceof String && obj.containsKey("data")
+ && obj.get("data") instanceof JSONObject) {
+ JSONObject data = (JSONObject) obj.get("data");
+
+ UUID tag = UUID.fromString((String) obj.get("tag"));
+
+ if (obj.containsKey("endpoint") && obj.get("endpoint") instanceof JSONArray) {
+ Object[] endpointArr = ((JSONArray) obj.get("endpoint")).toArray();
+ String[] endpoint = Arrays.copyOf(endpointArr, endpointArr.length, String[].class);
+
+ if (obj.containsKey("user") && obj.get("user") instanceof String) {
+ UUID user = UUID.fromString((String) obj.get("user"));
+
+ JSONObject responseData = handle(endpoint, data, user);
+
+ this.send(ctx.channel(), JSONUtils.json().add("tag", tag.toString()).add("data", responseData).build());
+ } else if (obj.containsKey("ms") && obj.get("ms") instanceof String) {
+ String ms = (String) obj.get("ms");
+
+ if (!this.inter.containsKey(tag)) {
+ this.sendToMicroService(ms, handleFromMicroService(endpoint, data, ms), tag);
+ } else {
+ this.inter.replace(tag, data);
+ }
+ }
+ }
+ }
+ }).start();
+ }
+
+ public JSONObject handle(String[] endpointArray, JSONObject data, UUID user) {
+ List endpoint = Arrays.asList(endpointArray);
+
+ if (userEndpoints.containsKey(endpoint)) {
+ Tuple tuple = userEndpoints.get(endpoint);
+
+ UserEndpoint e = tuple.getA();
+ Method eMethod = tuple.getB();
+ if (checkData(e.keys(), e.types(), data)) {
+ try {
+ JSONObject result = (JSONObject) eMethod.invoke(new Object(), data, user);
+
+ if (result == null) {
+ result = JSONUtils.empty();
+ }
+
+ return result;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
+ return JSONUtils.error("internal error");
+ }
+ } else {
+ return JSONUtils.error("invalid input data");
+ }
+ }
+
+ return JSONUtils.error("unknown service");
+ }
+
+ public JSONObject handleFromMicroService(String[] endpointArray, JSONObject data, String ms) {
+ List endpoint = Arrays.asList(endpointArray);
+
+ if (microserviceEndpoints.containsKey(endpoint)) {
+ Tuple tuple = microserviceEndpoints.get(endpoint);
+
+ MicroserviceEndpoint e = tuple.getA();
+ Method eMethod = tuple.getB();
+ if (checkData(e.keys(), e.types(), data)) {
+ try {
+ JSONObject result = (JSONObject) eMethod.invoke(new Object(), data, ms);
+
+ if (result == null) {
+ result = JSONUtils.empty();
+ }
+
+ return result;
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
+ return JSONUtils.error("internal error");
+ }
+ } else {
+ return JSONUtils.error("invalid input data");
+ }
+ }
+ return JSONUtils.error("unknown service");
+ }
+
+
+ private void send(Channel channel, JSONObject obj) {
+ channel.writeAndFlush(Unpooled.copiedBuffer(obj.toString(), CharsetUtil.UTF_8));
+ }
+
+ public void sendToMicroService(String ms, JSONObject data, UUID tag) {
+ this.send(channel, JSONUtils.json().add("ms", ms).add("data", data).add("tag", tag.toString()).build());
+ }
+
+ public void sendToUser(UUID user, JSONObject data) {
+ this.send(channel, JSONUtils.json().add("action", "address").add("user", user.toString()).add("data", data).build());
+ }
+
+ private static boolean checkData(String[] keys, Class>[] types, JSONObject obj) {
+ for (int i = 0; i < keys.length; i++) {
+ String key = keys[i];
+ Class> type = types[i];
+
+ if (!obj.containsKey(key) || obj.get(key).getClass() != type) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public JSONObject contactMicroservice(String ms, String[] endpoint, JSONObject data) {
+ UUID tag = UUID.randomUUID();
+
+ this.send(channel, JSONUtils.json().add("ms", ms).add("data", data).add("endpoint", Arrays.asList(endpoint)).add("tag", tag.toString()).build());
+
+ this.inter.put(tag, null);
+
+ int counter = 0;
+
+ while (this.inter.get(tag) == null) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ counter++;
+
+ if (counter > 100 * 30) {
+ return null;
+ }
+ }
+
+ return this.inter.remove(tag);
+ }
}
diff --git a/src/main/java/net/cryptic_game/microservice/model/Model.java b/src/main/java/net/cryptic_game/microservice/model/Model.java
index 1dd313d..405e4b9 100644
--- a/src/main/java/net/cryptic_game/microservice/model/Model.java
+++ b/src/main/java/net/cryptic_game/microservice/model/Model.java
@@ -4,7 +4,7 @@
import net.cryptic_game.microservice.db.Database;
-public abstract class Model {
+public class Model {
protected static Database db = Database.getDatabase();
protected UUID uuid;
diff --git a/src/main/java/net/cryptic_game/microservice/utils/JSONUtils.java b/src/main/java/net/cryptic_game/microservice/utils/JSONUtils.java
new file mode 100644
index 0000000..111f467
--- /dev/null
+++ b/src/main/java/net/cryptic_game/microservice/utils/JSONUtils.java
@@ -0,0 +1,45 @@
+package net.cryptic_game.microservice.utils;
+
+import org.json.simple.JSONObject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class JSONUtils {
+
+ private Map