From 0e9ed16b0a048266b56d1238bd7a8a31e59fdac5 Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Sun, 29 Dec 2019 19:12:48 +0100 Subject: Start running queries with Qurnik --- .../cloudatlas/agent/messages/QurnikMessage.java | 25 +++++ .../agent/messages/RunQueriesMessage.java | 9 ++ .../edu/mimuw/cloudatlas/agent/modules/Module.java | 5 + .../edu/mimuw/cloudatlas/agent/modules/Qurnik.java | 102 +++++++++++++++++++++ .../pl/edu/mimuw/cloudatlas/model/ValueUtils.java | 7 ++ 5 files changed, 148 insertions(+) create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java new file mode 100644 index 0000000..0161a37 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java @@ -0,0 +1,25 @@ +package pl.edu.mimuw.cloudatlas.agent.messages; + +import pl.edu.mimuw.cloudatlas.agent.modules.Module; +import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType; + +public abstract class QurnikMessage extends AgentMessage { + public enum Type { + RUN_QUERIES + } + + private Type type; + + public QurnikMessage(String messageId, long timestamp, Type type) { + super(messageId, ModuleType.QUERY, timestamp); + this.type = type; + } + + public Type getType() { + return type; + } + + public void callMe(Module module) throws InterruptedException, Module.InvalidMessageType { + module.handleTyped(this); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java new file mode 100644 index 0000000..35f7819 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java @@ -0,0 +1,9 @@ +package pl.edu.mimuw.cloudatlas.agent.messages; + +import pl.edu.mimuw.cloudatlas.agent.modules.ModuleType; + +public class RunQueriesMessage extends QurnikMessage { + public RunQueriesMessage(String messageId, long timestamp) { + super(messageId, timestamp, Type.RUN_QUERIES); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java index d0bf083..ba5e1d1 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java @@ -3,6 +3,7 @@ package pl.edu.mimuw.cloudatlas.agent.modules; import pl.edu.mimuw.cloudatlas.agent.Executor; import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage; import pl.edu.mimuw.cloudatlas.agent.messages.TimerSchedulerMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.QurnikMessage; import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage; import pl.edu.mimuw.cloudatlas.agent.messages.RMIMessage; import pl.edu.mimuw.cloudatlas.agent.messages.StanikMessage; @@ -32,6 +33,10 @@ public abstract class Module { throw new InvalidMessageType("Got a TimerSchedulerMessage in module " + moduleType.toString()); } + public void handleTyped(QurnikMessage message) throws InterruptedException, InvalidMessageType { + throw new InvalidMessageType("Got a QurnikMessage in module " + moduleType.toString()); + } + public void handleTyped(RMIMessage message) throws InterruptedException, InvalidMessageType { throw new InvalidMessageType("Got an RMIMessage in module " + moduleType.toString()); } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java new file mode 100644 index 0000000..3864aba --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java @@ -0,0 +1,102 @@ +package pl.edu.mimuw.cloudatlas.agent.modules; + +import java.util.List; +import java.util.LinkedList; +import java.util.Map.Entry; + +import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.QurnikMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.ResponseMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.RunQueriesMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.StateMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.UpdateAttributesMessage; +import pl.edu.mimuw.cloudatlas.interpreter.Interpreter; +import pl.edu.mimuw.cloudatlas.interpreter.InterpreterException; +import pl.edu.mimuw.cloudatlas.interpreter.QueryResult; +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.TypePrimitive; +import pl.edu.mimuw.cloudatlas.model.Value; +import pl.edu.mimuw.cloudatlas.model.ValueQuery; +import pl.edu.mimuw.cloudatlas.model.ValueString; +import pl.edu.mimuw.cloudatlas.model.ValueTime; +import pl.edu.mimuw.cloudatlas.model.ValueUtils; +import pl.edu.mimuw.cloudatlas.model.ZMI; + +public class Qurnik extends Module { + public Qurnik() { + super(ModuleType.QUERY); + } + + @Override + public void handleTyped(QurnikMessage message) throws InterruptedException, InvalidMessageType { + switch (message.getType()) { + case RUN_QUERIES: + handleRunQueries((RunQueriesMessage) message); + break; + default: + throw new InvalidMessageType("This type of message cannot be handled by Qurnik"); + } + } + + @Override + public void handleTyped(ResponseMessage message) throws InterruptedException, InvalidMessageType { + switch (message.getType()) { + case STATE: + runQueriesOnState((StateMessage) message); + break; + default: + throw new InvalidMessageType("This type of message cannot be handled by Qurnik"); + } + } + + private void handleRunQueries(RunQueriesMessage message) throws InterruptedException { + GetStateMessage getStateMessage = new GetStateMessage("", 0, ModuleType.QUERY, 0); + sendMessage(getStateMessage); + } + + private void runQueriesOnState(StateMessage message) throws InterruptedException { + List queries = new LinkedList(); + for (Entry timestampedQuery : message.getQueries().values()) { + queries.add(timestampedQuery.getKey()); + } + executeAllQueries(message.getZMI(), queries, PathName.ROOT); + } + + private void executeAllQueries(ZMI zmi, List queries, PathName currentPath) throws InterruptedException { + if(!zmi.getSons().isEmpty()) { + for(ZMI son : zmi.getSons()) { + Value sonName = son.getAttributes().getOrNull("name"); + if (ValueUtils.valueNonNullOfType(sonName, TypePrimitive.STRING)) { + String sonNameString = ((ValueString) sonName).getValue(); + executeAllQueries(son, queries, currentPath.levelDown(sonNameString)); + } else { + System.out.println("ERROR: zone without a name attribute found while executing queries"); + } + } + + Interpreter interpreter = new Interpreter(zmi); + AttributesMap newAttributes = new AttributesMap(); + for (ValueQuery query : queries) { + try { + List result = interpreter.interpretProgram(query.getQuery()); + for(QueryResult r : result) { + newAttributes.addOrChange(r.getName(), r.getValue()); + } + } catch(InterpreterException exception) { + System.out.println("ERROR: thrown while running interpreter: " + exception.getMessage()); + } + } + + if (!currentPath.toString().equals("/")) { + newAttributes.add("name", new ValueString(currentPath.getSingletonName())); + } + long currentTime = System.currentTimeMillis() / 1000; + newAttributes.add("timestamp", new ValueTime(currentTime)); + + UpdateAttributesMessage message = new UpdateAttributesMessage("", currentTime, currentPath.toString(), newAttributes); + sendMessage(message); + } + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java new file mode 100644 index 0000000..01a45b5 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java @@ -0,0 +1,7 @@ +package pl.edu.mimuw.cloudatlas.model; + +public class ValueUtils { + public static boolean valueNonNullOfType(Value value, Type type) { + return value != null && !value.isNull() && value.getType().isCompatible(type); + } +} -- cgit v1.2.3