m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2020-01-06 23:01:16 +0100
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2020-01-06 23:01:16 +0100
commitce76dbc406da1a8fe839b1e311ed699f9d5c7498 (patch)
treec4fb83075b1155c95230008b44afc1a28711771d /src
parent7b6d9a490cd07a6ffaf4b69df501a72c538621de (diff)
Start implementing gossip initiator path
Diffstat (limited to 'src')
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/AttributesMessage.java31
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java5
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java32
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/InitiateGossipMessage.java17
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java50
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RemoteGossipGirlMessage.java28
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java108
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java112
8 files changed, 380 insertions, 3 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/AttributesMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/AttributesMessage.java
new file mode 100644
index 0000000..49bda14
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/AttributesMessage.java
@@ -0,0 +1,31 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import java.util.Map;
+
+import pl.edu.mimuw.cloudatlas.model.AttributesMap;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+
+public class AttributesMessage extends RemoteGossipGirlMessage {
+ private PathName path;
+ private AttributesMap attributes;
+ private long receiverGossipId;
+
+ public AttributesMessage(String messageId, long timestamp, PathName path, AttributesMap attributes, long receiverGossipId) {
+ super(messageId, timestamp, Type.ATTRIBUTES);
+ this.path = path;
+ this.attributes = attributes;
+ this.receiverGossipId = receiverGossipId;
+ }
+
+ public PathName getPath() {
+ return path;
+ }
+
+ public AttributesMap getAttributes() {
+ return attributes;
+ }
+
+ public long getReceiverGossipId() {
+ return receiverGossipId;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java
index 705d64a..2016447 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java
@@ -5,7 +5,10 @@ import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
public abstract class GossipGirlMessage extends AgentMessage {
public enum Type {
- INITIATE
+ ATTRIBUTES,
+ HEJKA,
+ INITIATE,
+ NO_CO_TAM
}
private Type type;
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java
new file mode 100644
index 0000000..340d939
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java
@@ -0,0 +1,32 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import java.util.Map;
+
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.ValueTime;
+
+public class HejkaMessage extends RemoteGossipGirlMessage {
+ private long senderGossipId;
+ private Map<PathName, ValueTime> zoneTimestamps;
+ private Map<Attribute, ValueTime> queryTimestamps;
+
+ public HejkaMessage(String messageId, long timestamp, long senderGossipId, Map<PathName, ValueTime> zoneTimestamps, Map<Attribute, ValueTime> queryTimestamps) {
+ super(messageId, timestamp, Type.HEJKA);
+ this.senderGossipId = senderGossipId;
+ this.zoneTimestamps = zoneTimestamps;
+ this.queryTimestamps = queryTimestamps;
+ }
+
+ public long getSenderGossipId() {
+ return senderGossipId;
+ }
+
+ public Map<PathName, ValueTime> getZoneTimestamps() {
+ return zoneTimestamps;
+ }
+
+ public Map<Attribute, ValueTime> getQueryTimestamps() {
+ return queryTimestamps;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/InitiateGossipMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/InitiateGossipMessage.java
index d216d59..955570e 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/InitiateGossipMessage.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/InitiateGossipMessage.java
@@ -1,11 +1,24 @@
package pl.edu.mimuw.cloudatlas.agent.messages;
import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.ValueContact;
public class InitiateGossipMessage extends GossipGirlMessage {
- private long nextGossipId = 0;
+ private PathName ourPath;
+ private ValueContact theirContact;
- public InitiateGossipMessage(String messageId, long timestamp) {
+ public InitiateGossipMessage(String messageId, long timestamp, PathName ourPath, ValueContact theirContact) {
super(messageId, timestamp, Type.INITIATE);
+ this.ourPath = ourPath;
+ this.theirContact = theirContact;
+ }
+
+ public PathName getOurPath() {
+ return ourPath;
+ }
+
+ public ValueContact getTheirContact() {
+ return theirContact;
}
}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java
new file mode 100644
index 0000000..3dd0c4d
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java
@@ -0,0 +1,50 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import java.util.Map;
+
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.ValueTime;
+
+public class NoCoTamMessage extends RemoteGossipGirlMessage {
+ private long receiverGossipId;
+ private long senderGossipId;
+ private Map<PathName, ValueTime> zoneTimestamps;
+ private Map<Attribute, ValueTime> queryTimestamps;
+ private ValueTime hejkaSendTimestamp;
+ private ValueTime hejkaReceiveTimestamp;
+
+ public NoCoTamMessage(String messageId, long timestamp, long receiverGossipId, long senderGossipId, Map<PathName, ValueTime> zoneTimestamps, Map<Attribute, ValueTime> queryTimestamps, ValueTime hejkaSendTimestamp, ValueTime hejkaReceiveTimestamp) {
+ super(messageId, timestamp, Type.NO_CO_TAM);
+ this.receiverGossipId = receiverGossipId;
+ this.senderGossipId = senderGossipId;
+ this.zoneTimestamps = zoneTimestamps;
+ this.queryTimestamps = queryTimestamps;
+ this.hejkaSendTimestamp = hejkaSendTimestamp;
+ this.hejkaReceiveTimestamp = hejkaReceiveTimestamp;
+ }
+
+ public long getReceiverGossipId() {
+ return receiverGossipId;
+ }
+
+ public long getSenderGossipId() {
+ return senderGossipId;
+ }
+
+ public Map<PathName, ValueTime> getZoneTimestamps() {
+ return zoneTimestamps;
+ }
+
+ public Map<Attribute, ValueTime> getQueryTimestamps() {
+ return queryTimestamps;
+ }
+
+ public ValueTime getHejkaSendTimestamp() {
+ return hejkaSendTimestamp;
+ }
+
+ public ValueTime getHejkaReceiveTimestamp() {
+ return hejkaReceiveTimestamp;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RemoteGossipGirlMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RemoteGossipGirlMessage.java
new file mode 100644
index 0000000..0a3a868
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RemoteGossipGirlMessage.java
@@ -0,0 +1,28 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.model.ValueTime;
+
+public class RemoteGossipGirlMessage extends GossipGirlMessage {
+ private ValueTime sentTimestamp;
+ private ValueTime receivedTimestamp;
+
+ public RemoteGossipGirlMessage(String messageId, long timestamp, Type type) {
+ super(messageId, timestamp, type);
+ }
+
+ public void setSentTimestamp(ValueTime sentTimestamp) {
+ this.sentTimestamp = sentTimestamp;
+ }
+
+ public void setReceivedTimestamp(ValueTime receivedTimestamp) {
+ this.receivedTimestamp = receivedTimestamp;
+ }
+
+ public ValueTime getSentTimestamp() {
+ return sentTimestamp;
+ }
+
+ public ValueTime getReceivedTimestamp() {
+ return receivedTimestamp;
+ }
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java
new file mode 100644
index 0000000..01119bf
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java
@@ -0,0 +1,108 @@
+package pl.edu.mimuw.cloudatlas.agent.modules;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import pl.edu.mimuw.cloudatlas.agent.messages.AttributesMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.GossipGirlMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.HejkaMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.InitiateGossipMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.NoCoTamMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.StateMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.UDUPMessage;
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.AttributesMap;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.ValueQuery;
+import pl.edu.mimuw.cloudatlas.model.ValueTime;
+import pl.edu.mimuw.cloudatlas.model.ZMI;
+
+public class GossipGirl extends Module {
+ private long nextGossipId = 0;
+
+ private Map<Long, GossipGirlState> gossipStates;
+ public GossipGirl() {
+ super(ModuleType.GOSSIP);
+ gossipStates = new HashMap();
+ }
+
+ public void handleTyped(GossipGirlMessage message) throws InterruptedException, InvalidMessageType {
+ switch(message.getType()) {
+ case INITIATE:
+ initiateGossip((InitiateGossipMessage) message);
+ break;
+ case NO_CO_TAM:
+ handleNoCoTam((NoCoTamMessage) message);
+ default:
+ throw new InvalidMessageType("This type of message cannot be handled by GossipGirl");
+ }
+ }
+
+ public void handleTyped(ResponseMessage message) throws InterruptedException, InvalidMessageType {
+ switch(message.getType()) {
+ case STATE:
+ setState((StateMessage) message);
+ break;
+ default:
+ throw new InvalidMessageType("This type of message cannot be handled by GossipGirl");
+ }
+ }
+
+ private void initiateGossip(InitiateGossipMessage message) throws InterruptedException {
+ Long gossipId = nextGossipId;
+ nextGossipId++;
+ gossipStates.put(gossipId, new GossipGirlState(gossipId, message.getOurPath(), message.getTheirContact(), true));
+
+ GetStateMessage getState = new GetStateMessage("", 0, ModuleType.GOSSIP, gossipId);
+ sendMessage(getState);
+ }
+
+ private void setState(StateMessage message) throws InterruptedException {
+ GossipGirlState state = gossipStates.get(message.getRequestId());
+ if (state != null) {
+ state.setState(message.getZMI(), message.getQueries());
+ if (state.state == GossipGirlState.State.SEND_HEJKA) {
+ HejkaMessage hejka = new HejkaMessage(
+ "",
+ 0,
+ state.gossipId,
+ getZoneTimestamps(message.getZMI()),
+ getQueryTimestamps(message.getQueries())
+ );
+ UDUPMessage udupMessage = new UDUPMessage("", 0, state.theirContact, hejka);
+ sendMessage(udupMessage);
+ state.sentHejka();
+ }
+ } else {
+ System.out.println("ERROR: GossipGirl got state for a nonexistent gossip");
+ }
+ }
+
+ private void handleNoCoTam(NoCoTamMessage message) throws InterruptedException {
+ GossipGirlState state = gossipStates.get(message.getReceiverGossipId());
+ if (state != null) {
+ state.handleNoCoTam(message);
+ for (ZMI zmi : state.getZMIsToSend()) {
+ AttributesMessage attributesMessage = new AttributesMessage("", 0, zmi.getPathName(), zmi.getAttributes(), state.theirGossipId);
+ UDUPMessage udupMessage = new UDUPMessage("", 0, state.theirContact, attributesMessage);
+ sendMessage(udupMessage);
+ }
+ // TODO: send queries
+ state.sentInfo();
+ } else {
+ System.out.println("ERROR: GossipGirl got state for a nonexistent gossip");
+ }
+ }
+
+ public Map<PathName, ValueTime> getZoneTimestamps(ZMI root) {
+ return new HashMap();
+ }
+
+ public Map<Attribute, ValueTime> getQueryTimestamps(Map<Attribute, Entry<ValueQuery, ValueTime>> queries) {
+ return new HashMap();
+ }
+
+}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
new file mode 100644
index 0000000..726a9b2
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
@@ -0,0 +1,112 @@
+package pl.edu.mimuw.cloudatlas.agent.modules;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import pl.edu.mimuw.cloudatlas.agent.messages.NoCoTamMessage;
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.ValueContact;
+import pl.edu.mimuw.cloudatlas.model.ValueQuery;
+import pl.edu.mimuw.cloudatlas.model.ValueTime;
+import pl.edu.mimuw.cloudatlas.model.ZMI;
+
+public class GossipGirlState {
+ public enum State {
+ WAIT_FOR_STATE_INITIALIZER,
+ WAIT_FOR_STATE_RESPONDER,
+ SEND_HEJKA,
+ SEND_INFO,
+ WAIT_FOR_NO_CO_TAM,
+ WAIT_FOR_FIRST_INFO,
+ WAIT_FOR_INFO,
+ ERROR
+ }
+ public PathName ourPath;
+ public ValueContact theirContact;
+ public long gossipId;
+ public long theirGossipId;
+ public long timeOffest;
+ public State state;
+ public ZMI hierarchy;
+ public Map<Attribute, Entry<ValueQuery, ValueTime>> queries;
+ public ValueTime hejkaSendTimestamp;
+ public ValueTime hejkaReceiveTimestamp;
+ public ValueTime noCoTamSendTimestamp;
+ public ValueTime noCoTamSendReceiveTimestamp;
+ private Map<PathName, ValueTime> theirZoneTimestamps;
+ private Map<Attribute, ValueTime> theirQueryTimestamps;
+
+ public GossipGirlState(long gossipId, PathName ourPath, ValueContact theirContact, boolean initiating) {
+ this.gossipId = gossipId;
+ this.ourPath = ourPath;
+ this.theirContact = theirContact;
+ if (initiating) {
+ state = State.WAIT_FOR_STATE_INITIALIZER;
+ } else {
+ state = State.WAIT_FOR_STATE_RESPONDER;
+ }
+ }
+
+ public void setState(ZMI hierarchy, Map<Attribute, Entry<ValueQuery, ValueTime>> queries) {
+ switch (state) {
+ case WAIT_FOR_STATE_INITIALIZER:
+ this.hierarchy = hierarchy;
+ this.queries = queries;
+ state = State.SEND_HEJKA;
+ break;
+ case WAIT_FOR_STATE_RESPONDER:
+ this.hierarchy = hierarchy;
+ this.queries = queries;
+ state = State.WAIT_FOR_FIRST_INFO;
+ break;
+ default:
+ System.out.println("ERROR: tried to set gossip state when not expected");
+ state = State.ERROR;
+ }
+ }
+
+ public void sentHejka() {
+ switch (state) {
+ case SEND_HEJKA:
+ state = state.WAIT_FOR_NO_CO_TAM;
+ break;
+ default:
+ System.out.println("ERROR: tried to set gossip state when not expected");
+ state = State.ERROR;
+ }
+ }
+
+ public void handleNoCoTam(NoCoTamMessage message) {
+ switch (state) {
+ case WAIT_FOR_NO_CO_TAM:
+ theirGossipId = message.getSenderGossipId();
+ theirZoneTimestamps = message.getZoneTimestamps();
+ theirQueryTimestamps = message.getQueryTimestamps();
+ hejkaSendTimestamp = message.getHejkaSendTimestamp();
+ hejkaReceiveTimestamp = message.getHejkaReceiveTimestamp();
+ state = State.SEND_INFO;
+ break;
+ default:
+ System.out.println("ERROR: tried to set gossip state when not expected");
+ state = State.ERROR;
+ }
+ }
+
+ public List<ZMI> getZMIsToSend() {
+ return new LinkedList();
+ }
+
+ public void sentInfo() {
+ switch (state) {
+ case SEND_INFO:
+ state = State.WAIT_FOR_INFO;
+ break;
+ default:
+ System.out.println("ERROR: tried to set gossip state when not expected");
+ state = State.ERROR;
+ }
+ }
+}