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 jsonMap; + + private JSONUtils() { + this.jsonMap = new HashMap<>(); + } + + public JSONUtils add(Object key, Object value) { + this.jsonMap.put(key, value); + return this; + } + + public JSONObject build() { + return new JSONObject(jsonMap); + } + + public static JSONUtils json() { + return new JSONUtils(); + } + + public static JSONObject error(String message) { + return simple("error", message); + } + + public static JSONObject simple(Object key, Object value) { + JSONUtils jsonUtils = new JSONUtils(); + + jsonUtils.add(key, value); + + return jsonUtils.build(); + } + + public static JSONObject empty() { + return new JSONObject(new HashMap()); + } + +} diff --git a/src/main/java/net/cryptic_game/microservice/utils/Tuple.java b/src/main/java/net/cryptic_game/microservice/utils/Tuple.java index 54d6af0..87df73e 100644 --- a/src/main/java/net/cryptic_game/microservice/utils/Tuple.java +++ b/src/main/java/net/cryptic_game/microservice/utils/Tuple.java @@ -2,20 +2,19 @@ public class Tuple { - private A a; - private B b; - - public Tuple(A a, B b) { - this.a = a; - this.b = b; - } - - public A getA() { - return a; - } - - public B getB() { - return b; - } - + private A a; + private B b; + + public Tuple(A a, B b) { + this.a = a; + this.b = b; + } + + public A getA() { + return a; + } + + public B getB() { + return b; + } } diff --git a/src/test/java/net/cryptic_game/microservice/Echo.java b/src/test/java/net/cryptic_game/microservice/Echo.java deleted file mode 100644 index a87f8bf..0000000 --- a/src/test/java/net/cryptic_game/microservice/Echo.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.cryptic_game.microservice; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.UUID; - -import net.cryptic_game.microservice.db.Database; -import net.cryptic_game.microservice.model.Model; - -public class Echo extends Model { - - static { - Database.getDatabase().update("CREATE TABLE IF NOT EXISTS `echo` (uuid VARCHAR(36), " - + "message VARCHAR(255), PRIMARY KEY(uuid));"); - } - - private String message; - - private Echo(UUID uuid, String message) { - super("echo"); - this.uuid = uuid; - this.message = message; - } - - public String getMessage() { - return message; - } - - public static Echo create(String message) { - UUID uuid = UUID.randomUUID(); - - Echo echo = new Echo(uuid, message); - - db.update("INSERT INTO `echo` (`uuid`, `message`) VALUES (?, ?)", uuid.toString(), message); - - return echo; - } - - public static Echo get(UUID uuid) { - ResultSet rs = db.getResult("SELECT * FROM `echo` WHERE `uuid`=?", uuid.toString()); - - try { - if(rs.next()) { - return new Echo(uuid, rs.getString("message")); - } - } catch (SQLException e) { - } - - return null; - } - -} diff --git a/src/test/java/net/cryptic_game/microservice/EchoEndpoint.java b/src/test/java/net/cryptic_game/microservice/EchoEndpoint.java index 3ae2011..e69de29 100644 --- a/src/test/java/net/cryptic_game/microservice/EchoEndpoint.java +++ b/src/test/java/net/cryptic_game/microservice/EchoEndpoint.java @@ -1,18 +0,0 @@ -package net.cryptic_game.microservice; - -import java.util.UUID; - -import org.json.simple.JSONObject; - -import net.cryptic_game.microservice.endpoint.UserEndpoint; - -public class EchoEndpoint { - - @UserEndpoint(path = { "echo" }, keys = { "message" }, types = { String.class }) - public static JSONObject echo(JSONObject data, UUID user) { - Echo.create((String) data.get("message")); - - return data; - } - -} diff --git a/src/test/java/net/cryptic_game/microservice/EchoMicroService.java b/src/test/java/net/cryptic_game/microservice/EchoMicroService.java index ca0e2be..e69de29 100644 --- a/src/test/java/net/cryptic_game/microservice/EchoMicroService.java +++ b/src/test/java/net/cryptic_game/microservice/EchoMicroService.java @@ -1,18 +0,0 @@ -package net.cryptic_game.microservice; - -import org.apache.log4j.BasicConfigurator; - -public class EchoMicroService extends MicroService { - - public EchoMicroService() { - super("echo"); - } - - public static void main(String[] args) { - BasicConfigurator.configure(); - - new EchoMicroService(); - } - -} - \ No newline at end of file diff --git a/src/test/java/net/cryptic_game/microservice/utils/JSONUtilsTest.java b/src/test/java/net/cryptic_game/microservice/utils/JSONUtilsTest.java new file mode 100644 index 0000000..e0194f6 --- /dev/null +++ b/src/test/java/net/cryptic_game/microservice/utils/JSONUtilsTest.java @@ -0,0 +1,59 @@ +package net.cryptic_game.microservice.utils; + +import org.json.simple.JSONObject; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; + +class JSONUtilsTest { + + @Test + void createRandomJSONObject() { + Map jsonMap = new HashMap<>(); + + JSONUtils jsonUtils = JSONUtils.json(); + + for(int i = 0; i < new Random().nextInt(10); i++) { + String key = UUID.randomUUID().toString(); + String value = UUID.randomUUID().toString(); + + jsonMap.put(key, value); + jsonUtils.add(key, value); + } + + assertEquals(jsonUtils.build(), new JSONObject(jsonMap)); + } + + @Test + void shouldCreateEmptyJSONObject() { + JSONObject empty = new JSONObject(new HashMap()); + + assertEquals(JSONUtils.empty(), empty); + } + + @Test + void shouldCreateErrorJSONObject() { + String errorMessage = "just a test"; + + Map jsonMap = new HashMap<>(); + jsonMap.put("error", errorMessage); + JSONObject error = new JSONObject(jsonMap); + + assertEquals(JSONUtils.error(errorMessage), error); + } + + @Test + void shouldCreateSimpleJSONObject() { + Map jsonMap = new HashMap<>(); + jsonMap.put("abc", "def"); + JSONObject json = new JSONObject(jsonMap); + + assertEquals(JSONUtils.simple("abc", "def"), json); + } + +} \ No newline at end of file diff --git a/src/test/java/net/cryptic_game/microservice/utils/TupleTest.java b/src/test/java/net/cryptic_game/microservice/utils/TupleTest.java new file mode 100644 index 0000000..a0682f3 --- /dev/null +++ b/src/test/java/net/cryptic_game/microservice/utils/TupleTest.java @@ -0,0 +1,16 @@ +package net.cryptic_game.microservice.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class TupleTest { + + private Tuple tuple = new Tuple<>("abc", "def"); + + @Test + void checkOutput() { + assertEquals(tuple.getA(), "abc"); + assertEquals(tuple.getB(), "def"); + } +} \ No newline at end of file