diff options
| -rw-r--r-- | src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Stanik.java | 44 | ||||
| -rw-r--r-- | src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/StanikTest.java | 29 | 
2 files changed, 69 insertions, 4 deletions
| 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 1b1824f..6c0f380 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,6 +1,8 @@  package pl.edu.mimuw.cloudatlas.agent.modules;  import java.util.HashMap; +import java.util.LinkedList; +import java.util.List;  import java.util.Map.Entry;  import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage; @@ -19,6 +21,7 @@ import pl.edu.mimuw.cloudatlas.model.Type;  import pl.edu.mimuw.cloudatlas.model.TypePrimitive;  import pl.edu.mimuw.cloudatlas.model.Value;  import pl.edu.mimuw.cloudatlas.model.ValueBoolean; +import pl.edu.mimuw.cloudatlas.model.ValueDuration;  import pl.edu.mimuw.cloudatlas.model.ValueQuery;  import pl.edu.mimuw.cloudatlas.model.ValueString;  import pl.edu.mimuw.cloudatlas.model.ValueTime; @@ -36,12 +39,16 @@ public class Stanik extends Module {      private HashMap<Attribute, Entry<ValueQuery, ValueTime>> queries;      private long freshnessPeriod; -    public Stanik() { +    public Stanik(long freshnessPeriod) {          super(ModuleType.STATE);          hierarchy = new ZMI();          queries = new HashMap<Attribute, Entry<ValueQuery, ValueTime>>();          hierarchy.getAttributes().add("timestamp", new ValueTime(0l)); -        freshnessPeriod = 60 * 1000; +        this.freshnessPeriod = freshnessPeriod; +    } + +    public Stanik() { +        this(60 * 1000);      }      public void handleTyped(StanikMessage message) throws InterruptedException, InvalidMessageType { @@ -67,6 +74,7 @@ public class Stanik extends Module {      }      public void handleGetState(GetStateMessage message) throws InterruptedException { +        pruneHierarchy();          StateMessage response = new StateMessage(              "",              message.getRequestingModule(), @@ -78,6 +86,38 @@ public class Stanik extends Module {          sendMessage(response);      } +    private void pruneHierarchy() { +        ValueTime now = ValueUtils.currentTime(); +        pruneZMI(hierarchy, now); +    } + +    private boolean pruneZMI(ZMI zmi, ValueTime time) { +        Value timestamp = zmi.getAttributes().get("timestamp"); + +        List<ZMI> sonsToRemove = new LinkedList(); +        if (ValueUtils.valueLower(timestamp, time.subtract(new ValueDuration(freshnessPeriod)))) { +            if (zmi.getFather() != null) { +                return true; +            } +        } else { +            for (ZMI son : zmi.getSons()) { +                if (pruneZMI(son, time)) { +                    sonsToRemove.add(son); +                } +            } +        } + +        for (ZMI son : sonsToRemove) { +            zmi.removeSon(son); +        } + +        if (zmi.getSons().isEmpty()) { +            return true; +        } + +        return false; +    } +      public void handleRemoveZMI(RemoveZMIMessage message) {          try {              ZMI zmi = hierarchy.findDescendant(new PathName(message.getPathName())); 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 1ca8608..f3ea0b0 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 @@ -35,10 +35,11 @@ public class StanikTest {      private Stanik stanik;      private MockExecutor executor;      private ValueTime testTime; +    private static final long freshnessPeriod = 1000;      @Before      public void setupLocals() { -        stanik = new Stanik(); +        stanik = new Stanik(freshnessPeriod);          executor = new MockExecutor(stanik);          testTime = ValueUtils.currentTime();      } @@ -157,7 +158,7 @@ public class StanikTest {      public void dontApplyWithStaleTimestamp() throws Exception {          AttributesMap attributes = new AttributesMap();          attributes.add("foo", new ValueInt(1337l)); -        attributes.add("timestamp", (ValueTime) testTime.subtract(new ValueDuration(61 * 1000l))); +        attributes.add("timestamp", (ValueTime) testTime.subtract(new ValueDuration(freshnessPeriod + 100)));          attributes.add("name", new ValueString("new"));          UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes);          stanik.handleTyped(message); @@ -166,6 +167,30 @@ public class StanikTest {      }      @Test +    public void zoneRemovedAfterFreshnessPeriod() throws Exception { +        AttributesMap attributes = new AttributesMap(); +        attributes.add("foo", new ValueInt(1337l)); +        attributes.add("timestamp", testTime); +        attributes.add("name", new ValueString("new")); +        UpdateAttributesMessage message = new UpdateAttributesMessage("test_msg", 0, "/new", attributes); +        stanik.handleTyped(message); +        Thread.sleep(freshnessPeriod + 100); + +        AttributesMap attributes2 = new AttributesMap(); +        attributes2.add("timestamp", ValueUtils.currentTime()); +        UpdateAttributesMessage message2 = new UpdateAttributesMessage("test_msg", 0, "/", attributes2); +        stanik.handleTyped(message2); + +        GetStateMessage getStateMessage = new GetStateMessage("", 0, ModuleType.TEST, 0); +        stanik.handleTyped(getStateMessage); + +        StateMessage newReceivedMessage = (StateMessage) executor.messagesToPass.poll(); +        assertNotNull(newReceivedMessage); +        assertFalse(newReceivedMessage.getZMI().descendantExists(new PathName("/new"))); +        assertFalse(stanik.getHierarchy().descendantExists(new PathName("/new"))); +    } + +    @Test      public void addQuery() throws Exception {          HashMap<Attribute, Entry<ValueQuery, ValueTime>> queries = new HashMap<Attribute, Entry<ValueQuery, ValueTime>>();          queries.put(new Attribute("&query"), new SimpleImmutableEntry(new ValueQuery("SELECT 1 AS one"), new ValueTime(42l))); |