m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2019-12-27 11:28:46 +0100
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2019-12-27 11:28:46 +0100
commitafa32431d242d60471e5431d654784ee64b63bbf (patch)
tree5d379373a70c8e828ae0459600dd2195a27eabc2
parent8b076ed54b692381a3c1410b704bdad33ad5ca0b (diff)
Begin Stanik impelementation
* Get cloned hierarchy * Test on empty hierarchy
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GetHierarchyMessage.java22
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HierarchyMessage.java17
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/ResponseMessage.java31
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java25
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java10
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/ModuleType.java4
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java31
-rw-r--r--src/test/java/pl/edu/mimuw/cloudatlas/agent/MockExecutor.java24
-rw-r--r--src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java49
9 files changed, 212 insertions, 1 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GetHierarchyMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GetHierarchyMessage.java
new file mode 100644
index 0000000..d3c749d
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GetHierarchyMessage.java
@@ -0,0 +1,22 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+
+public class GetHierarchyMessage extends StanikMessage {
+ private ModuleType requestingModule;
+ private long requestId;
+
+ public GetHierarchyMessage(String messageId, long timestamp, ModuleType requestingModule, long requestId) {
+ super(messageId, timestamp, Type.GET_HIERARCHY);
+ this.requestingModule = requestingModule;
+ this.requestId = requestId;
+ }
+
+ public ModuleType getRequestingModule() {
+ return requestingModule;
+ }
+
+ public long getRequestId() {
+ return requestId;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HierarchyMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HierarchyMessage.java
new file mode 100644
index 0000000..9f7ca70
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HierarchyMessage.java
@@ -0,0 +1,17 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+import pl.edu.mimuw.cloudatlas.model.ZMI;
+
+public class HierarchyMessage extends ResponseMessage {
+ private ZMI zmi;
+
+ public HierarchyMessage(String messageId, ModuleType destinationModule, long timestamp, long requestId, ZMI zmi) {
+ super(messageId, destinationModule, timestamp, Type.HIERARCHY, requestId);
+ this.zmi = zmi;
+ }
+
+ public ZMI getZMI() {
+ return zmi;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/ResponseMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/ResponseMessage.java
new file mode 100644
index 0000000..171cf07
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/ResponseMessage.java
@@ -0,0 +1,31 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.Module;
+import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+
+public abstract class ResponseMessage extends AgentMessage {
+ public enum Type {
+ HIERARCHY
+ }
+
+ Type type;
+ long requestId;
+
+ public ResponseMessage(String messageId, ModuleType destinationModule, long timestamp, Type type, long requestId) {
+ super(messageId, destinationModule, timestamp);
+ this.type = type;
+ this.requestId = requestId;
+ }
+
+ public void callMe(Module module) throws InterruptedException, Module.InvalidMessageType {
+ module.handleTyped(this);
+ }
+
+ public long getRequestId() {
+ return requestId;
+ }
+
+ public Type getType() {
+ return type;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java
new file mode 100644
index 0000000..d2b3064
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java
@@ -0,0 +1,25 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.Module;
+import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+
+public abstract class StanikMessage extends AgentMessage {
+ public enum Type {
+ GET_HIERARCHY
+ }
+
+ private Type type;
+
+ public StanikMessage(String messageId, long timestamp, Type type) {
+ super(messageId, ModuleType.STATE, timestamp);
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void callMe(Module module) throws InterruptedException, Module.InvalidMessageType {
+ module.handleTyped(this);
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java
index a50a95f..d0bf083 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java
@@ -3,7 +3,9 @@ package pl.edu.mimuw.cloudatlas.agent.modules;
import pl.edu.mimuw.cloudatlas.agent.Executor;
import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.TimerSchedulerMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.RMIMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.StanikMessage;
/*
* A Module is a (potentially stateful) event handler.
@@ -34,6 +36,14 @@ public abstract class Module {
throw new InvalidMessageType("Got an RMIMessage in module " + moduleType.toString());
}
+ public void handleTyped(StanikMessage message) throws InterruptedException, InvalidMessageType {
+ throw new InvalidMessageType("Got a StanikMessage in module " + moduleType.toString());
+ }
+
+ public void handleTyped(ResponseMessage message) throws InterruptedException, InvalidMessageType {
+ throw new InvalidMessageType("Got a ResponseMessage in module " + moduleType.toString());
+ }
+
public void setExecutor(Executor executor) {
this.executor = executor;
}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/ModuleType.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/ModuleType.java
index ff4a92e..d221f06 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/ModuleType.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/ModuleType.java
@@ -8,5 +8,7 @@ public enum ModuleType {
GOSSIP_IN,
GOSSIP_OUT,
STATE,
- QUERY
+ QUERY,
+ // for testing
+ TEST
}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java
new file mode 100644
index 0000000..b8db08a
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java
@@ -0,0 +1,31 @@
+package pl.edu.mimuw.cloudatlas.agent.modules;
+
+import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.GetHierarchyMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.HierarchyMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.StanikMessage;
+import pl.edu.mimuw.cloudatlas.model.ZMI;
+
+public class Stanik extends Module {
+ private ZMI hierarchy;
+
+ public Stanik() {
+ super(ModuleType.STATE);
+ hierarchy = new ZMI();
+ }
+
+ public void handleTyped(StanikMessage message) throws InterruptedException, InvalidMessageType {
+ switch(message.getType()) {
+ case GET_HIERARCHY:
+ handleGetHierarchy((GetHierarchyMessage) message);
+ break;
+ default:
+ throw new InvalidMessageType("This type of message cannot be handled by Stanik");
+ }
+ }
+
+ public void handleGetHierarchy(GetHierarchyMessage message) throws InterruptedException {
+ HierarchyMessage response = new HierarchyMessage("", message.getRequestingModule(), 0, message.getRequestId(), hierarchy.clone());
+ sendMessage(response);
+ }
+}
diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/agent/MockExecutor.java b/src/test/java/pl/edu/mimuw/cloudatlas/agent/MockExecutor.java
new file mode 100644
index 0000000..1da50ad
--- /dev/null
+++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/MockExecutor.java
@@ -0,0 +1,24 @@
+package pl.edu.mimuw.cloudatlas.agent;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.Module;
+import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage;
+
+/*
+ * Instead of passing messages to an EventBus, this one just collects them
+ * locally for inspection in unit tests.
+ */
+public class MockExecutor extends Executor {
+ public LinkedBlockingQueue<AgentMessage> messagesToPass;
+
+ public MockExecutor(Module module) {
+ super(module);
+ messagesToPass = new LinkedBlockingQueue<AgentMessage>();
+ }
+
+ @Override
+ public void passMessage(AgentMessage message) throws InterruptedException {
+ messagesToPass.put(message);
+ }
+}
diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java
new file mode 100644
index 0000000..7c869e7
--- /dev/null
+++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java
@@ -0,0 +1,49 @@
+package pl.edu.mimuw.cloudatlas.agent.modules;
+
+import java.util.List;
+import java.util.Map.Entry;
+
+import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.GetHierarchyMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.HierarchyMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage;
+import pl.edu.mimuw.cloudatlas.agent.MockExecutor;
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.Value;
+import pl.edu.mimuw.cloudatlas.model.ZMI;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class StanikTest {
+ private Stanik stanik;
+ private MockExecutor executor;
+
+ @Before
+ public void setupEventBus() {
+ stanik = new Stanik();
+ executor = new MockExecutor(stanik);
+ }
+
+ @Test
+ public void getEmptyHierarchy() throws Exception {
+ GetHierarchyMessage message = new GetHierarchyMessage("test_msg", 0, ModuleType.TEST, 42);
+ stanik.handleTyped(message);
+ assertEquals(1, executor.messagesToPass.size());
+ ResponseMessage receivedMessage = (ResponseMessage) executor.messagesToPass.take();
+ assertEquals(ModuleType.TEST, receivedMessage.getDestinationModule());
+ assertEquals(ResponseMessage.Type.HIERARCHY, receivedMessage.getType());
+ assertEquals(42, receivedMessage.getRequestId());
+ HierarchyMessage hierarchyMessage = (HierarchyMessage) receivedMessage;
+ ZMI zmi = hierarchyMessage.getZMI();
+ assertNull(zmi.getFather());
+ assertTrue(zmi.getSons().isEmpty());
+ boolean empty = true;
+ for (Entry<Attribute, Value> entry : zmi.getAttributes()) {
+ empty = false;
+ break;
+ }
+ assertTrue(empty);
+ }
+}