summaryrefslogtreecommitdiff
path: root/same
diff options
context:
space:
mode:
authorKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-01-13 12:12:37 +0100
committerKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-01-13 12:12:37 +0100
commit008f40dcd76f7eedc0360f94dd42d2d12e3a8793 (patch)
tree0a8ebfb744a3d9f3b937ad0834458993c1204899 /same
parent2413c4cf76f82983dc1bde5fb3dc2ce3e1afdf15 (diff)
Add support for JSON state.
Use Jackson for serialization and deserialization of JSON objects.
Diffstat (limited to 'same')
-rw-r--r--same/src/main/java/com/orbekk/same/MasterServiceImpl.java21
-rw-r--r--same/src/main/java/com/orbekk/same/State.java179
-rw-r--r--same/src/test/java/com/orbekk/same/MasterServiceImplTest.java22
3 files changed, 146 insertions, 76 deletions
diff --git a/same/src/main/java/com/orbekk/same/MasterServiceImpl.java b/same/src/main/java/com/orbekk/same/MasterServiceImpl.java
index 64cde2f..50a5607 100644
--- a/same/src/main/java/com/orbekk/same/MasterServiceImpl.java
+++ b/same/src/main/java/com/orbekk/same/MasterServiceImpl.java
@@ -1,5 +1,7 @@
package com.orbekk.same;
+import java.util.List;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -12,9 +14,22 @@ public class MasterServiceImpl implements MasterService, UrlReceiver {
}
@Override
- public void joinNetworkRequest(String networkName, String clientUrl) {
- // TODO Auto-generated method stub
-
+ public synchronized void joinNetworkRequest(String networkName, String clientUrl) {
+ if (networkName.equals(state.getDataOf(".networkName"))) {
+ List<String> participants = state.getList(".participants");
+ if (!participants.contains(clientUrl)) {
+ participants.add(clientUrl);
+ } else {
+ logger.warn("Client {} already part of network. " +
+ "Ignoring participation request", clientUrl);
+ }
+ state.updateFromObject(".participants", participants,
+ state.getRevision(".participants"));
+ } else {
+ logger.warn("Client {} tried to join {}, but network name is {}",
+ new Object[]{ clientUrl, networkName,
+ state.getDataOf(".networkName") });
+ }
}
@Override
diff --git a/same/src/main/java/com/orbekk/same/State.java b/same/src/main/java/com/orbekk/same/State.java
index 6b7c824..303caca 100644
--- a/same/src/main/java/com/orbekk/same/State.java
+++ b/same/src/main/java/com/orbekk/same/State.java
@@ -1,17 +1,29 @@
package com.orbekk.same;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.HashMap;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
public class State {
+ private Logger logger = LoggerFactory.getLogger(getClass());
private Map<String, Component> state = new HashMap<String, Component>();
-
- private long stateIteration = 0;
- private Map<String, String> participants = new HashMap<String, String>();
- private String networkName = "";
- private String masterId = "";
- private String data = "";
+ private ObjectMapper mapper = new ObjectMapper();
+ public State(String networkName) {
+ update(".networkName", networkName, 0);
+ updateFromObject(".participants", new ArrayList<String>(), 0);
+ }
+
public boolean update(String componentName, String data, long revision) {
Component component = null;
if (!state.containsKey(componentName)) {
@@ -39,6 +51,65 @@ public class State {
}
}
+ public long getRevision(String componentName) {
+ Component component = state.get(componentName);
+ if (component != null) {
+ return component.getRevision();
+ } else {
+ logger.warn("getRevision: Unknown component {}. Returning 0",
+ componentName);
+ return 0;
+ }
+ }
+
+ /**
+ * Parses a JSON value using Jackson ObjectMapper.
+ */
+ public <T> T getParsedData(String componentName, TypeReference<T> type) {
+ String data = getDataOf(componentName);
+ if (data != null) {
+ try {
+ return mapper.readValue(data, type);
+ } catch (JsonParseException e) {
+ logger.warn("Failed to parse value {} ", data);
+ logger.warn("Parse exception: {}", e);
+ } catch (JsonMappingException e) {
+ logger.warn("Failed to parse value {} ", data);
+ logger.warn("Parse exception: {}", e);
+
+ } catch (IOException e) {
+ logger.warn("Failed to parse value {} ", data);
+ logger.warn("Parse exception: {}", e);
+ }
+ }
+ return null;
+ }
+
+ public List<String> getList(String componentName) {
+ return getParsedData(componentName,
+ new TypeReference<List<String>>(){});
+ }
+
+ public boolean updateFromObject(String componentName, Object data, long revision) {
+ String dataS;
+ try {
+ dataS = mapper.writeValueAsString(data);
+ return update(componentName, dataS, revision);
+ } catch (JsonGenerationException e) {
+ logger.warn("Failed to convert to JSON: {} ", data);
+ logger.warn("Parse exception: {}", e);
+ return false;
+ } catch (JsonMappingException e) {
+ logger.warn("Failed to convert to JSON: {} ", data);
+ logger.warn("Parse exception: {}", e);
+ return false;
+ } catch (IOException e) {
+ logger.warn("Failed to convert to JSON: {} ", data);
+ logger.warn("Parse exception: {}", e);
+ return false;
+ }
+ }
+
public static class Component {
private long revision;
private String data;
@@ -66,70 +137,34 @@ public class State {
return this.data + " @" + revision;
}
}
-
- public long getStateIteration() {
- return stateIteration;
- }
-
- public void setStateIteration(long stateIteration) {
- this.stateIteration = stateIteration;
- }
-
- public Map<String, String> getParticipants() {
- return participants;
- }
-
- public String getNetworkName() {
- return networkName;
- }
-
- public void setNetworkName(String networkName) {
- this.networkName = networkName;
- }
-
- public String getMasterId() {
- return masterId;
- }
-
- public void setMasterId(String masterId) {
- this.masterId = masterId;
- }
-
- public String getData() {
- return data;
- }
-
- public void setData(String data) {
- this.data = data;
- }
-
- @Override
- public String toString() {
- StringBuilder participantsString = new StringBuilder();
- participantsString.append("[");
- boolean first = true;
- for (Map.Entry<String, String> e : participants.entrySet()) {
- if (!first) {
- participantsString.append(", ");
- }
- first = false;
- participantsString.append(e.getKey())
- .append("(")
- .append(e.getValue())
- .append(")");
- String clientId = e.getKey();
- String url = e.getValue();
- }
- participantsString.append("]");
-
- return String.format(
- "State( \n" +
- " stateIteration = %d,\n" +
- " networkName = %s,\n" +
- " masterId = %s,\n" +
- " data = %s,\n" +
- " participants = %s\n" +
- ")", stateIteration, networkName, masterId, data,
- participantsString);
- }
+//
+// @Override
+// public String toString() {
+// StringBuilder participantsString = new StringBuilder();
+// participantsString.append("[");
+// boolean first = true;
+// for (Map.Entry<String, String> e : participants.entrySet()) {
+// if (!first) {
+// participantsString.append(", ");
+// }
+// first = false;
+// participantsString.append(e.getKey())
+// .append("(")
+// .append(e.getValue())
+// .append(")");
+// String clientId = e.getKey();
+// String url = e.getValue();
+// }
+// participantsString.append("]");
+//
+// return String.format(
+// "State( \n" +
+// " stateIteration = %d,\n" +
+// " networkName = %s,\n" +
+// " masterId = %s,\n" +
+// " data = %s,\n" +
+// " participants = %s\n" +
+// ")", stateIteration, networkName, masterId, data,
+// participantsString);
+// }
}
diff --git a/same/src/test/java/com/orbekk/same/MasterServiceImplTest.java b/same/src/test/java/com/orbekk/same/MasterServiceImplTest.java
index 826471e..9d8a134 100644
--- a/same/src/test/java/com/orbekk/same/MasterServiceImplTest.java
+++ b/same/src/test/java/com/orbekk/same/MasterServiceImplTest.java
@@ -2,10 +2,13 @@ package com.orbekk.same;
import static org.junit.Assert.*;
+import java.util.List;
+
+import org.codehaus.jackson.type.TypeReference;
import org.junit.Test;
public class MasterServiceImplTest {
- private State state = new State();
+ private State state = new State("TestNetwork");
private MasterServiceImpl master = new MasterServiceImpl(state);
@Test
@@ -14,4 +17,21 @@ public class MasterServiceImplTest {
assertEquals("http://10.0.0.54:10050/MasterService.json",
state.getDataOf(".masterUrl"));
}
+
+ @Test
+ public void testJsonState() {
+ List<String> participants =
+ state.getParsedData(".participants",
+ new TypeReference<List<String>>() { });
+ assertEquals(participants.size(), 0);
+ participants.add("http://SomeUrl/");
+ state.updateFromObject(".participants", participants, 1);
+ }
+
+ @Test
+ public void joinNetworkAddsClient() {
+ master.joinNetworkRequest("TestNetwork", "http://clientUrl");
+ List<String> participants = state.getList(".participants");
+ assertTrue(participants.contains("http://clientUrl"));
+ }
}