m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java3
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/UpdateAttributesMessage.java23
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java48
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java17
-rw-r--r--src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java38
5 files changed, 128 insertions, 1 deletions
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
index d2b3064..8661c90 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/StanikMessage.java
@@ -5,7 +5,8 @@ import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
public abstract class StanikMessage extends AgentMessage {
public enum Type {
- GET_HIERARCHY
+ GET_HIERARCHY,
+ UPDATE_ATTRIBUTES
}
private Type type;
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/UpdateAttributesMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/UpdateAttributesMessage.java
new file mode 100644
index 0000000..7e41631
--- /dev/null
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/UpdateAttributesMessage.java
@@ -0,0 +1,23 @@
+package pl.edu.mimuw.cloudatlas.agent.messages;
+
+import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType;
+import pl.edu.mimuw.cloudatlas.model.AttributesMap;
+
+public class UpdateAttributesMessage extends StanikMessage {
+ private String pathName;
+ private AttributesMap attributes;
+
+ public UpdateAttributesMessage(String messageId, long timestamp, String pathName, AttributesMap attributes) {
+ super(messageId, timestamp, Type.UPDATE_ATTRIBUTES);
+ this.pathName = pathName;
+ this.attributes = attributes;
+ }
+
+ public String getPathName() {
+ return pathName;
+ }
+
+ public AttributesMap getAttributes() {
+ return attributes;
+ }
+}
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
index b8db08a..a457a94 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java
@@ -1,9 +1,17 @@
package pl.edu.mimuw.cloudatlas.agent.modules;
+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.StanikMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage;
+import pl.edu.mimuw.cloudatlas.model.AttributesMap;
+import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.PathName;
+import pl.edu.mimuw.cloudatlas.model.Value;
+import pl.edu.mimuw.cloudatlas.model.ValueString;
import pl.edu.mimuw.cloudatlas.model.ZMI;
public class Stanik extends Module {
@@ -19,6 +27,9 @@ public class Stanik extends Module {
case GET_HIERARCHY:
handleGetHierarchy((GetHierarchyMessage) message);
break;
+ case UPDATE_ATTRIBUTES:
+ handleUpdateAttributes((UpdateAttributesMessage) message);
+ break;
default:
throw new InvalidMessageType("This type of message cannot be handled by Stanik");
}
@@ -28,4 +39,41 @@ public class Stanik extends Module {
HierarchyMessage response = new HierarchyMessage("", message.getRequestingModule(), 0, message.getRequestId(), hierarchy.clone());
sendMessage(response);
}
+
+ public void handleUpdateAttributes(UpdateAttributesMessage message) {
+ try {
+ addMissingZones(new PathName(message.getPathName()));
+ ZMI zone = hierarchy.findDescendant(message.getPathName());
+ for (Entry<Attribute, Value> entry : zone.getAttributes()) {
+ Attribute attribute = entry.getKey();
+ Value newValue = message.getAttributes().getOrNull(attribute);
+ if (newValue == null) {
+ zone.getAttributes().remove(attribute);
+ }
+ }
+ for (Entry<Attribute, Value> entry : message.getAttributes()) {
+ zone.getAttributes().addOrChange(entry.getKey(), entry.getValue());
+ }
+ } catch (ZMI.NoSuchZoneException e) {
+ System.out.println("ERROR: zone should exist after being added");
+ }
+ }
+
+ private void addMissingZones(PathName path) {
+ try {
+ if (!hierarchy.descendantExists(path)) {
+ addMissingZones(path.levelUp());
+ ZMI parent = hierarchy.findDescendant(path.levelUp());
+ ZMI newSon = new ZMI(parent);
+ newSon.getAttributes().add("name", new ValueString(path.getSingletonName()));
+ parent.addSon(newSon);
+ }
+ } catch (ZMI.NoSuchZoneException e) {
+ System.out.println("ERROR: zone should exist after being added");
+ }
+ }
+
+ public ZMI getHierarchy() {
+ return hierarchy;
+ }
}
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java
index 7f2f604..54fbf43 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java
@@ -111,6 +111,23 @@ public class ZMI implements Cloneable, Serializable {
return descendant;
}
+ public boolean descendantExists(PathName path) {
+ try {
+ findDescendant(path);
+ return true;
+ } catch (NoSuchZoneException e) {
+ return false;
+ }
+ }
+
+ /*
+ * Convenient version of findDescendant that takes String representation of
+ * path.
+ */
+ public ZMI findDescendant(String pathString) throws NoSuchZoneException {
+ return findDescendant(new PathName(pathString));
+ }
+
/**
* Gets the list of sons of this ZMI. Modifying a value in the returned list will cause an exception.
*
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
index 1c1e216..31b701d 100644
--- a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java
+++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java
@@ -7,11 +7,13 @@ 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.messages.UpdateAttributesMessage;
import pl.edu.mimuw.cloudatlas.agent.MockExecutor;
import pl.edu.mimuw.cloudatlas.model.Attribute;
import pl.edu.mimuw.cloudatlas.model.AttributesMap;
import pl.edu.mimuw.cloudatlas.model.Value;
import pl.edu.mimuw.cloudatlas.model.ValueInt;
+import pl.edu.mimuw.cloudatlas.model.ValueString;
import pl.edu.mimuw.cloudatlas.model.ZMI;
import org.junit.Before;
@@ -65,4 +67,40 @@ public class StanikTest {
AttributesMap newAttributes = newReceivedMessage.getZMI().getAttributes();
assertNull(newAttributes.getOrNull("foo"));
}
+
+ @Test
+ public void updateRootAttributes() throws Exception {
+ AttributesMap attributes = new AttributesMap();
+ attributes.add("foo", new ValueInt(1337l));
+ attributes.add("bar", new ValueString("baz"));
+ UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/", attributes);
+ stanik.handleTyped(message);
+ AttributesMap actualAttributes = stanik.getHierarchy().getAttributes();
+ assertEquals(2, countAttributes(actualAttributes));
+ assertEquals(new ValueInt(1337l), actualAttributes.get("foo"));
+ assertEquals(new ValueString("baz"), actualAttributes.get("bar"));
+ }
+
+ @Test
+ public void updateWithNewZone() throws Exception {
+ AttributesMap attributes = new AttributesMap();
+ attributes.add("foo", new ValueInt(1337l));
+ attributes.add("bar", new ValueString("baz"));
+ attributes.add("name", new ValueString("new"));
+ UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
+ stanik.handleTyped(message);
+ AttributesMap actualAttributes = stanik.getHierarchy().findDescendant("/new").getAttributes();
+ assertEquals(3, countAttributes(actualAttributes));
+ assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
+ assertEquals(new ValueString("baz"), actualAttributes.getOrNull("bar"));
+ }
+
+ public int countAttributes(AttributesMap attributes) {
+ int count = 0;
+ for (Entry<Attribute, Value> attribute : attributes) {
+ count++;
+ }
+
+ return count;
+ }
}