m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/pl/edu/mimuw/cloudatlas
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/pl/edu/mimuw/cloudatlas')
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/QurnikMessage.java25
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/RunQueriesMessage.java9
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Module.java5
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/Qurnik.java102
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/model/ValueUtils.java7
5 files changed, 148 insertions, 0 deletions
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<ValueQuery> queries = new LinkedList();
+ for (Entry<ValueQuery, ValueTime> timestampedQuery : message.getQueries().values()) {
+ queries.add(timestampedQuery.getKey());
+ }
+ executeAllQueries(message.getZMI(), queries, PathName.ROOT);
+ }
+
+ private void executeAllQueries(ZMI zmi, List<ValueQuery> 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<QueryResult> 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);
+ }
+}