m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin <marcin.j.chrzanowski@gmail.com>2020-01-12 22:32:59 +0100
committerGitHub <noreply@github.com>2020-01-12 22:32:59 +0100
commit0f31d1f5c267f893d765ccd848b95fc111009de5 (patch)
treecf54497163b95e32fc8932b0ba13acc3fe2ca503
parent32bfe8f7efc1f4fb99ddf827a19ab466724dac06 (diff)
parentcd247e8d64b2ef0aed7f0afdccd711008cd60fcd (diff)
Merge pull request #116 from m-chrzan/required-attributes
Required attributes
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/AgentConfig.java4
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java21
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java45
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java22
-rw-r--r--src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java36
5 files changed, 99 insertions, 29 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/AgentConfig.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/AgentConfig.java
index 38d764a..e9bbf4e 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/AgentConfig.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/AgentConfig.java
@@ -3,6 +3,7 @@ package pl.edu.mimuw.cloudatlas.agent;
import pl.edu.mimuw.cloudatlas.agent.modules.*;
import pl.edu.mimuw.cloudatlas.agent.modules.Module;
import pl.edu.mimuw.cloudatlas.api.Api;
+import pl.edu.mimuw.cloudatlas.model.PathName;
import java.net.InetAddress;
import java.net.SocketException;
@@ -43,11 +44,12 @@ public class AgentConfig {
Integer timeout = Integer.getInteger("UDUPServer.timeout");
Integer bufsize = Integer.getInteger("UDUPServer.bufsize");
InetAddress serverAddr = InetAddress.getByName(System.getProperty("UDUPServer.hostname"));
+ String ourPath = System.getProperty("zone_path");
HashMap<ModuleType, Module> modules = new HashMap<ModuleType, Module>();
modules.put(ModuleType.TIMER_SCHEDULER, new TimerScheduler(ModuleType.TIMER_SCHEDULER));
modules.put(ModuleType.RMI, new Remik());
- modules.put(ModuleType.STATE, new Stanik(freshnessPeriod));
+ modules.put(ModuleType.STATE, new Stanik(new PathName(ourPath), freshnessPeriod));
modules.put(ModuleType.QUERY, new Qurnik());
modules.put(ModuleType.GOSSIP, new GossipGirl());
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 251d8b3..0525f41 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
@@ -280,26 +280,7 @@ public class GossipGirlState {
}
public boolean interestedIn(PathName recipientPath, PathName zmiPath) {
- return isPrefix(zmiPath.levelUp(), recipientPath) && !isPrefix(zmiPath, recipientPath);
- }
-
- public boolean isPrefix(PathName prefix, PathName path) {
- List<String> prefixComponents = prefix.getComponents();
- List<String> pathComponents = path.getComponents();
-
- if (prefixComponents.size() > pathComponents.size()) {
- return false;
- }
-
- Iterator<String> prefixIterator = prefixComponents.iterator();
- Iterator<String> pathIterator = pathComponents.iterator();
-
- while (prefixIterator.hasNext()) {
- if (!prefixIterator.next().equals(pathIterator.next())) {
- return false;
- }
- }
- return true;
+ return ValueUtils.isPrefix(zmiPath.levelUp(), recipientPath) && !ValueUtils.isPrefix(zmiPath, recipientPath);
}
public void sentInfo() {
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 999c193..6e7d4dc 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
@@ -2,6 +2,7 @@ package pl.edu.mimuw.cloudatlas.agent.modules;
import java.nio.file.Path;
import java.util.*;
+import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map.Entry;
import pl.edu.mimuw.cloudatlas.agent.messages.*;
@@ -19,19 +20,39 @@ public class Stanik extends Module {
private long freshnessPeriod;
private Set<ValueContact> contacts;
private ValueTime contactsTimestamp;
+ private PathName ourPath;
- public Stanik(long freshnessPeriod) {
+ public Stanik(PathName ourPath, long freshnessPeriod) {
super(ModuleType.STATE);
+ this.ourPath = ourPath;
hierarchy = new ZMI();
queries = new HashMap<Attribute, Entry<ValueQuery, ValueTime>>();
hierarchy.getAttributes().add("timestamp", new ValueTime(0l));
this.freshnessPeriod = freshnessPeriod;
this.contactsTimestamp = ValueUtils.currentTime();
this.contacts = new HashSet<>();
+ setDefaultQueries();
}
- public Stanik() {
- this(60 * 1000);
+ private void setDefaultQueries() {
+ String cardinalityQuery = "SELECT sum(cardinality) AS cardinality";
+ String contactsQuery = "SELECT random(5, unfold(contacts)) AS contacts";
+
+ setDefaultQuery("&cardinality", cardinalityQuery);
+ setDefaultQuery("&contacts", contactsQuery);
+ }
+
+ private void setDefaultQuery(String name, String query) {
+ try {
+ ValueQuery queryValue = new ValueQuery(query);
+ queries.put(new Attribute(name), new SimpleImmutableEntry(queryValue, new ValueTime(0l)));
+ } catch (Exception e) {
+ System.out.println("ERROR: failed to compile default query");
+ }
+ }
+
+ public Stanik(PathName ourPath) {
+ this(ourPath, 60 * 1000);
}
public void handleTyped(StanikMessage message) throws InterruptedException, InvalidMessageType {
@@ -61,6 +82,7 @@ public class Stanik extends Module {
public void handleGetState(GetStateMessage message) throws InterruptedException {
pruneHierarchy();
+ addValues();
StateMessage response = new StateMessage(
"",
message.getRequestingModule(),
@@ -78,6 +100,23 @@ public class Stanik extends Module {
pruneZMI(hierarchy, now);
}
+ private void addValues() {
+ addValuesRecursive(hierarchy, 0);
+ }
+
+ private void addValuesRecursive(ZMI zmi, long level) {
+ zmi.getAttributes().addOrChange("level", new ValueInt(level));
+ if (ValueUtils.isPrefix(zmi.getPathName(), ourPath)) {
+ zmi.getAttributes().addOrChange("owner", new ValueString(ourPath.toString()));
+ }
+ if (zmi.getPathName().equals(ourPath)) {
+ zmi.getAttributes().addOrChange("cardinality", new ValueInt(1l));
+ }
+ for (ZMI son : zmi.getSons()) {
+ addValuesRecursive(son, level + 1);
+ }
+ }
+
private boolean pruneZMI(ZMI zmi, ValueTime time) {
Value timestamp = zmi.getAttributes().get("timestamp");
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java
index 866349f..20d6600 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java
@@ -1,5 +1,8 @@
package pl.edu.mimuw.cloudatlas.model;
+import java.util.List;
+import java.util.Iterator;
+
public class ValueUtils {
public static boolean valueNonNullOfType(Value value, Type type) {
return value != null && !value.isNull() && value.getType().isCompatible(type);
@@ -16,4 +19,23 @@ public class ValueUtils {
public static ValueTime addToTime(ValueTime time, long millis) {
return time.addValue(new ValueDuration(millis));
}
+
+ public static boolean isPrefix(PathName prefix, PathName path) {
+ List<String> prefixComponents = prefix.getComponents();
+ List<String> pathComponents = path.getComponents();
+
+ if (prefixComponents.size() > pathComponents.size()) {
+ return false;
+ }
+
+ Iterator<String> prefixIterator = prefixComponents.iterator();
+ Iterator<String> pathIterator = pathComponents.iterator();
+
+ while (prefixIterator.hasNext()) {
+ if (!prefixIterator.next().equals(pathIterator.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
}
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 f3ea0b0..92ba051 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
@@ -39,7 +39,7 @@ public class StanikTest {
@Before
public void setupLocals() {
- stanik = new Stanik(freshnessPeriod);
+ stanik = new Stanik(new PathName("/new"), freshnessPeriod);
executor = new MockExecutor(stanik);
testTime = ValueUtils.currentTime();
}
@@ -57,9 +57,11 @@ public class StanikTest {
ZMI zmi = stateMessage.getZMI();
assertNull(zmi.getFather());
assertTrue(zmi.getSons().isEmpty());
- assertEquals(1, TestUtil.iterableSize(zmi.getAttributes()));
+ assertEquals(3, TestUtil.iterableSize(zmi.getAttributes()));
+ assertEquals(new ValueInt(0l), zmi.getAttributes().getOrNull("level"));
+ assertEquals(new ValueString("/new"), zmi.getAttributes().getOrNull("owner"));
Map<Attribute, Entry<ValueQuery, ValueTime>> queries = stateMessage.getQueries();
- assertEquals(0, TestUtil.iterableSize(queries.keySet()));
+ assertEquals(2, TestUtil.iterableSize(queries.keySet()));
}
@Test
@@ -112,6 +114,30 @@ public class StanikTest {
}
@Test
+ public void newZoneHasNewLevel() throws Exception {
+ AttributesMap attributes = new AttributesMap();
+ attributes.add("foo", new ValueInt(1337l));
+ attributes.add("bar", new ValueString("baz"));
+ attributes.add("name", new ValueString("new"));
+ attributes.add("timestamp", testTime);
+ UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);
+ stanik.handleTyped(message);
+ GetStateMessage newMessage = new GetStateMessage("test_msg2", 123, ModuleType.TEST, 43);
+ stanik.handleTyped(newMessage);
+
+ StateMessage newReceivedMessage = (StateMessage) executor.messagesToPass.poll();
+ AttributesMap actualAttributes = newReceivedMessage.getZMI().findDescendant("/new").getAttributes();
+ assertEquals(7, TestUtil.iterableSize(actualAttributes));
+ assertEquals(new ValueInt(1337l), actualAttributes.getOrNull("foo"));
+ assertEquals(new ValueString("baz"), actualAttributes.getOrNull("bar"));
+ assertEquals(new ValueString("new"), actualAttributes.getOrNull("name"));
+ assertEquals(new ValueString("/new"), actualAttributes.getOrNull("owner"));
+ assertEquals(new ValueInt(1l), actualAttributes.getOrNull("cardinality"));
+ assertEquals(testTime, actualAttributes.getOrNull("timestamp"));
+ assertEquals(new ValueInt(1l), actualAttributes.getOrNull("level"));
+ }
+
+ @Test
public void updateWithRemovedAttributes() throws Exception {
AttributesMap attributes = new AttributesMap();
attributes.add("foo", new ValueInt(1337l));
@@ -198,7 +224,7 @@ public class StanikTest {
stanik.handleTyped(message);
HashMap<Attribute, Entry<ValueQuery, ValueTime>> actualQueries = stanik.getQueries();
- assertEquals(1, TestUtil.iterableSize(actualQueries.keySet()));
+ assertEquals(3, TestUtil.iterableSize(actualQueries.keySet()));
assertTrue(actualQueries.containsKey(new Attribute("&query")));
Entry<ValueQuery, ValueTime> timestampedQuery = actualQueries.get(new Attribute("&query"));
assertEquals(new ValueTime(42l), timestampedQuery.getValue());
@@ -222,7 +248,7 @@ public class StanikTest {
stanik.handleTyped(otherMessage);
HashMap<Attribute, Entry<ValueQuery, ValueTime>> actualQueries = stanik.getQueries();
- assertEquals(4, TestUtil.iterableSize(actualQueries.keySet()));
+ assertEquals(6, TestUtil.iterableSize(actualQueries.keySet()));
assertTrue(actualQueries.containsKey(new Attribute("&query1")));
assertTrue(actualQueries.containsKey(new Attribute("&query2")));
assertTrue(actualQueries.containsKey(new Attribute("&query3")));