From 89af38da0b95445180440e85bb8248ab910ef9f8 Mon Sep 17 00:00:00 2001
From: Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com>
Date: Fri, 10 Jan 2020 22:58:32 +0100
Subject: Send NoCoTam when responder gets state

---
 .../cloudatlas/agent/messages/HejkaMessage.java    | 14 +++++++-
 .../cloudatlas/agent/messages/NoCoTamMessage.java  |  2 +-
 .../mimuw/cloudatlas/agent/modules/GossipGirl.java | 37 ++++++++++++++++++++++
 .../cloudatlas/agent/modules/GossipGirlState.java  | 35 ++++++++++++++++++--
 4 files changed, 84 insertions(+), 4 deletions(-)

(limited to 'src/main/java')

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
index 340d939..62554a5 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/HejkaMessage.java
@@ -8,12 +8,16 @@ import pl.edu.mimuw.cloudatlas.model.ValueTime;
 
 public class HejkaMessage extends RemoteGossipGirlMessage {
     private long senderGossipId;
+    private PathName senderPath;
+    private PathName receiverPath;
     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) {
+    public HejkaMessage(String messageId, long timestamp, long senderGossipId, PathName senderPath, PathName receiverPath, Map<PathName, ValueTime> zoneTimestamps, Map<Attribute, ValueTime> queryTimestamps) {
         super(messageId, timestamp, Type.HEJKA);
         this.senderGossipId = senderGossipId;
+        this.senderPath = senderPath;
+        this.receiverPath = receiverPath;
         this.zoneTimestamps = zoneTimestamps;
         this.queryTimestamps = queryTimestamps;
     }
@@ -22,6 +26,14 @@ public class HejkaMessage extends RemoteGossipGirlMessage {
         return senderGossipId;
     }
 
+    public PathName getSenderPath() {
+        return senderPath;
+    }
+
+    public PathName getReceiverPath() {
+        return receiverPath;
+    }
+
     public Map<PathName, ValueTime> getZoneTimestamps() {
         return zoneTimestamps;
     }
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
index 3dd0c4d..c23722c 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/NoCoTamMessage.java
@@ -14,7 +14,7 @@ public class NoCoTamMessage extends RemoteGossipGirlMessage {
     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) {
+    public NoCoTamMessage(String messageId, long timestamp, long senderGossipId, long receiverGossipId, 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;
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
index e7bd227..0c02f1f 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java
@@ -20,6 +20,7 @@ import pl.edu.mimuw.cloudatlas.agent.messages.UpdateQueriesMessage;
 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.ValueContact;
 import pl.edu.mimuw.cloudatlas.model.ValueQuery;
 import pl.edu.mimuw.cloudatlas.model.ValueTime;
 import pl.edu.mimuw.cloudatlas.model.ZMI;
@@ -38,6 +39,9 @@ public class GossipGirl extends Module {
             case INITIATE:
                 initiateGossip((InitiateGossipMessage) message);
                 break;
+            case HEJKA:
+                receiveGossip((HejkaMessage) message);
+                break;
             case NO_CO_TAM:
                 handleNoCoTam((NoCoTamMessage) message);
                 break;
@@ -71,6 +75,23 @@ public class GossipGirl extends Module {
         sendMessage(getState);
     }
 
+    private void receiveGossip(HejkaMessage message) throws InterruptedException {
+        Long gossipId = nextGossipId;
+        nextGossipId++;
+        gossipStates.put(gossipId, new GossipGirlState(
+                    gossipId,
+                    message.getReceiverPath(),
+                    new ValueContact(message.getSenderPath(), message.getSenderAddress()),
+                    false
+                )
+        );
+
+        gossipStates.get(gossipId).handleHejka(message);
+
+        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) {
@@ -80,12 +101,28 @@ public class GossipGirl extends Module {
                         "",
                         0,
                         state.gossipId,
+                        state.ourPath,
+                        state.theirContact.getName(),
                         state.getZoneTimestampsToSend(),
                         state.getQueryTimestampsToSend()
                 );
                 UDUPMessage udupMessage = new UDUPMessage("", 0, state.theirContact, hejka);
                 sendMessage(udupMessage);
                 state.sentHejka();
+            } else if (state.state == GossipGirlState.State.SEND_NO_CO_TAM) {
+                NoCoTamMessage noCoTam = new NoCoTamMessage(
+                        "",
+                        0,
+                        state.gossipId,
+                        state.theirGossipId,
+                        state.getZoneTimestampsToSend(),
+                        state.getQueryTimestampsToSend(),
+                        state.hejkaSendTimestamp,
+                        state.hejkaReceiveTimestamp
+                );
+                UDUPMessage udupMessage = new UDUPMessage("", 0, state.theirContact, noCoTam);
+                sendMessage(udupMessage);
+                state.sentNoCoTam();
             }
         } else {
             System.out.println("ERROR: GossipGirl got state for a nonexistent gossip");
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
index 8b0711e..1629914 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
@@ -10,6 +10,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import pl.edu.mimuw.cloudatlas.agent.messages.HejkaMessage;
 import pl.edu.mimuw.cloudatlas.agent.messages.NoCoTamMessage;
 import pl.edu.mimuw.cloudatlas.model.Attribute;
 import pl.edu.mimuw.cloudatlas.model.PathName;
@@ -22,8 +23,10 @@ import pl.edu.mimuw.cloudatlas.model.ZMI;
 public class GossipGirlState {
     public enum State {
         WAIT_FOR_STATE_INITIALIZER,
+        APPLY_HEJKA,
         WAIT_FOR_STATE_RESPONDER,
         SEND_HEJKA,
+        SEND_NO_CO_TAM,
         SEND_INFO,
         WAIT_FOR_NO_CO_TAM,
         WAIT_FOR_FIRST_INFO,
@@ -57,7 +60,7 @@ public class GossipGirlState {
         if (initiating) {
             state = State.WAIT_FOR_STATE_INITIALIZER;
         } else {
-            state = State.WAIT_FOR_STATE_RESPONDER;
+            state = State.APPLY_HEJKA;
         }
     }
 
@@ -71,7 +74,7 @@ public class GossipGirlState {
             case WAIT_FOR_STATE_RESPONDER:
                 this.hierarchy = hierarchy;
                 this.queries = queries;
-                state = State.WAIT_FOR_FIRST_INFO;
+                state = State.SEND_NO_CO_TAM;
                 break;
             default:
                 System.out.println("ERROR: tried to set gossip state when not expected");
@@ -90,6 +93,34 @@ public class GossipGirlState {
         }
     }
 
+    public void sentNoCoTam() {
+        switch (state) {
+            case SEND_NO_CO_TAM:
+                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 handleHejka(HejkaMessage message) {
+        switch (state) {
+            case APPLY_HEJKA:
+                System.out.println("setting sender gossip id to " + message.getSenderGossipId());
+                theirGossipId = message.getSenderGossipId();
+                theirZoneTimestamps = message.getZoneTimestamps();
+                theirQueryTimestamps = message.getQueryTimestamps();
+                hejkaSendTimestamp = message.getSentTimestamp();
+                hejkaReceiveTimestamp = message.getReceivedTimestamp();
+                state = State.WAIT_FOR_STATE_RESPONDER;
+                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:
-- 
cgit v1.2.3