tom

Initial check-in for new p2p cluster messaging; to be refactored.

...@@ -28,10 +28,6 @@ ...@@ -28,10 +28,6 @@
28 <version>${project.version}</version> 28 <version>${project.version}</version>
29 </dependency> 29 </dependency>
30 <dependency> 30 <dependency>
31 - <groupId>org.livetribe.slp</groupId>
32 - <artifactId>livetribe-slp</artifactId>
33 - </dependency>
34 - <dependency>
35 <groupId>org.apache.karaf.shell</groupId> 31 <groupId>org.apache.karaf.shell</groupId>
36 <artifactId>org.apache.karaf.shell.console</artifactId> 32 <artifactId>org.apache.karaf.shell.console</artifactId>
37 </dependency> 33 </dependency>
......
...@@ -26,6 +26,23 @@ ...@@ -26,6 +26,23 @@
26 <artifactId>onos-core-serializers</artifactId> 26 <artifactId>onos-core-serializers</artifactId>
27 <version>${project.version}</version> 27 <version>${project.version}</version>
28 </dependency> 28 </dependency>
29 +
30 +
31 + <dependency>
32 + <groupId>org.onlab.onos</groupId>
33 + <artifactId>onlab-nio</artifactId>
34 + <version>${project.version}</version>
35 + </dependency>
36 +
37 + <dependency>
38 + <groupId>com.fasterxml.jackson.core</groupId>
39 + <artifactId>jackson-databind</artifactId>
40 + </dependency>
41 + <dependency>
42 + <groupId>com.fasterxml.jackson.core</groupId>
43 + <artifactId>jackson-annotations</artifactId>
44 + </dependency>
45 +
29 <dependency> 46 <dependency>
30 <groupId>org.apache.felix</groupId> 47 <groupId>org.apache.felix</groupId>
31 <artifactId>org.apache.felix.scr.annotations</artifactId> 48 <artifactId>org.apache.felix.scr.annotations</artifactId>
......
1 +package org.onlab.onos.store.cluster.impl;
2 +
3 +import com.fasterxml.jackson.core.JsonEncoding;
4 +import com.fasterxml.jackson.core.JsonFactory;
5 +import com.fasterxml.jackson.databind.JsonNode;
6 +import com.fasterxml.jackson.databind.ObjectMapper;
7 +import com.fasterxml.jackson.databind.node.ArrayNode;
8 +import com.fasterxml.jackson.databind.node.ObjectNode;
9 +import org.onlab.onos.cluster.DefaultControllerNode;
10 +import org.onlab.onos.cluster.NodeId;
11 +import org.onlab.packet.IpPrefix;
12 +
13 +import java.io.File;
14 +import java.io.IOException;
15 +import java.util.HashSet;
16 +import java.util.Iterator;
17 +import java.util.Set;
18 +
19 +/**
20 + * Allows for reading and writing cluster definition as a JSON file.
21 + */
22 +public class ClusterDefinitionStore {
23 +
24 + private final File file;
25 +
26 + /**
27 + * Creates a reader/writer of the cluster definition file.
28 + *
29 + * @param filePath location of the definition file
30 + */
31 + public ClusterDefinitionStore(String filePath) {
32 + file = new File(filePath);
33 + }
34 +
35 + /**
36 + * Returns set of the controller nodes, including self.
37 + *
38 + * @return set of controller nodes
39 + */
40 + public Set<DefaultControllerNode> read() throws IOException {
41 + Set<DefaultControllerNode> nodes = new HashSet<>();
42 + ObjectMapper mapper = new ObjectMapper();
43 + ObjectNode clusterNodeDef = (ObjectNode) mapper.readTree(file);
44 + Iterator<JsonNode> it = ((ArrayNode) clusterNodeDef.get("nodes")).elements();
45 + while (it.hasNext()) {
46 + ObjectNode nodeDef = (ObjectNode) it.next();
47 + nodes.add(new DefaultControllerNode(new NodeId(nodeDef.get("id").asText()),
48 + IpPrefix.valueOf(nodeDef.get("ip").asText()),
49 + nodeDef.get("tcpPort").asInt(9876)));
50 + }
51 + return nodes;
52 + }
53 +
54 + /**
55 + * Writes the given set of the controller nodes.
56 + *
57 + * @param nodes set of controller nodes
58 + */
59 + public void write(Set<DefaultControllerNode> nodes) throws IOException {
60 + ObjectMapper mapper = new ObjectMapper();
61 + ObjectNode clusterNodeDef = mapper.createObjectNode();
62 + ArrayNode nodeDefs = mapper.createArrayNode();
63 + clusterNodeDef.set("nodes", nodeDefs);
64 + for (DefaultControllerNode node : nodes) {
65 + ObjectNode nodeDef = mapper.createObjectNode();
66 + nodeDef.put("id", node.id().toString())
67 + .put("ip", node.ip().toString())
68 + .put("tcpPort", node.tcpPort());
69 + nodeDefs.add(nodeDef);
70 + }
71 + mapper.writeTree(new JsonFactory().createGenerator(file, JsonEncoding.UTF8),
72 + clusterNodeDef);
73 + }
74 +
75 +}
1 -package org.onlab.onos.ccc; 1 +package org.onlab.onos.store.cluster.impl;
2 2
3 import org.onlab.nio.AbstractMessage; 3 import org.onlab.nio.AbstractMessage;
4 4
...@@ -12,17 +12,16 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -12,17 +12,16 @@ import static com.google.common.base.MoreObjects.toStringHelper;
12 public class TLVMessage extends AbstractMessage { 12 public class TLVMessage extends AbstractMessage {
13 13
14 private final int type; 14 private final int type;
15 - private final Object data; 15 + private final byte[] data;
16 16
17 /** 17 /**
18 * Creates an immutable TLV message. 18 * Creates an immutable TLV message.
19 * 19 *
20 * @param type message type 20 * @param type message type
21 - * @param length message length 21 + * @param data message data bytes
22 - * @param data message data
23 */ 22 */
24 - public TLVMessage(int type, int length, Object data) { 23 + public TLVMessage(int type, byte[] data) {
25 - this.length = length; 24 + this.length = data.length + TLVMessageStream.METADATA_LENGTH;
26 this.type = type; 25 this.type = type;
27 this.data = data; 26 this.data = data;
28 } 27 }
...@@ -37,11 +36,11 @@ public class TLVMessage extends AbstractMessage { ...@@ -37,11 +36,11 @@ public class TLVMessage extends AbstractMessage {
37 } 36 }
38 37
39 /** 38 /**
40 - * Returns the data object. 39 + * Returns the data bytes.
41 * 40 *
42 * @return message data 41 * @return message data
43 */ 42 */
44 - public Object data() { 43 + public byte[] data() {
45 return data; 44 return data;
46 } 45 }
47 46
......
1 -package org.onlab.onos.ccc; 1 +package org.onlab.onos.store.cluster.impl;
2 2
3 import org.onlab.nio.IOLoop; 3 import org.onlab.nio.IOLoop;
4 import org.onlab.nio.MessageStream; 4 import org.onlab.nio.MessageStream;
5 +import org.onlab.onos.cluster.DefaultControllerNode;
5 6
6 import java.nio.ByteBuffer; 7 import java.nio.ByteBuffer;
7 import java.nio.channels.ByteChannel; 8 import java.nio.channels.ByteChannel;
...@@ -13,8 +14,13 @@ import static com.google.common.base.Preconditions.checkState; ...@@ -13,8 +14,13 @@ import static com.google.common.base.Preconditions.checkState;
13 */ 14 */
14 public class TLVMessageStream extends MessageStream<TLVMessage> { 15 public class TLVMessageStream extends MessageStream<TLVMessage> {
15 16
17 + public static final int METADATA_LENGTH = 16; // 8 + 4 + 4
18 +
19 + private static final int LENGTH_OFFSET = 12;
16 private static final long MARKER = 0xfeedcafecafefeedL; 20 private static final long MARKER = 0xfeedcafecafefeedL;
17 21
22 + private DefaultControllerNode node;
23 +
18 /** 24 /**
19 * Creates a message stream associated with the specified IO loop and 25 * Creates a message stream associated with the specified IO loop and
20 * backed by the given byte channel. 26 * backed by the given byte channel.
...@@ -29,17 +35,51 @@ public class TLVMessageStream extends MessageStream<TLVMessage> { ...@@ -29,17 +35,51 @@ public class TLVMessageStream extends MessageStream<TLVMessage> {
29 super(loop, byteChannel, bufferSize, maxIdleMillis); 35 super(loop, byteChannel, bufferSize, maxIdleMillis);
30 } 36 }
31 37
38 + /**
39 + * Returns the node with which this stream is associated.
40 + *
41 + * @return controller node
42 + */
43 + DefaultControllerNode node() {
44 + return node;
45 + }
46 +
47 + /**
48 + * Sets the node with which this stream is affiliated.
49 + *
50 + * @param node controller node
51 + */
52 + void setNode(DefaultControllerNode node) {
53 + checkState(this.node == null, "Stream is already bound to a node");
54 + this.node = node;
55 + }
56 +
32 @Override 57 @Override
33 protected TLVMessage read(ByteBuffer buffer) { 58 protected TLVMessage read(ByteBuffer buffer) {
59 + // Do we have enough bytes to read the header? If not, bail.
60 + if (buffer.remaining() < METADATA_LENGTH) {
61 + return null;
62 + }
63 +
64 + // Peek at the length and if we have enough to read the entire message
65 + // go ahead, otherwise bail.
66 + int length = buffer.getInt(buffer.position() + LENGTH_OFFSET);
67 + if (buffer.remaining() < length) {
68 + return null;
69 + }
70 +
71 + // At this point, we have enough data to read a complete message.
34 long marker = buffer.getLong(); 72 long marker = buffer.getLong();
35 checkState(marker == MARKER, "Incorrect message marker"); 73 checkState(marker == MARKER, "Incorrect message marker");
36 74
37 int type = buffer.getInt(); 75 int type = buffer.getInt();
38 - int length = buffer.getInt(); 76 + length = buffer.getInt();
39 77
40 // TODO: add deserialization hook here 78 // TODO: add deserialization hook here
79 + byte[] data = new byte[length - METADATA_LENGTH];
80 + buffer.get(data);
41 81
42 - return new TLVMessage(type, length, null); 82 + return new TLVMessage(type, data);
43 } 83 }
44 84
45 @Override 85 @Override
...@@ -49,5 +89,7 @@ public class TLVMessageStream extends MessageStream<TLVMessage> { ...@@ -49,5 +89,7 @@ public class TLVMessageStream extends MessageStream<TLVMessage> {
49 buffer.putInt(message.length()); 89 buffer.putInt(message.length());
50 90
51 // TODO: add serialization hook here 91 // TODO: add serialization hook here
92 + buffer.put(message.data());
52 } 93 }
94 +
53 } 95 }
......
...@@ -48,14 +48,11 @@ ...@@ -48,14 +48,11 @@
48 description="ONOS core components"> 48 description="ONOS core components">
49 <feature>onos-api</feature> 49 <feature>onos-api</feature>
50 <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle> 50 <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle>
51 - <bundle>mvn:org.onlab.onos/onos-core-hz-common/1.0.0-SNAPSHOT</bundle> 51 + <bundle>mvn:org.onlab.onos/onos-core-dist/1.0.0-SNAPSHOT</bundle>
52 - <bundle>mvn:org.onlab.onos/onos-core-serializers/1.0.0-SNAPSHOT</bundle>
53 - <bundle>mvn:org.onlab.onos/onos-core-hz-cluster/1.0.0-SNAPSHOT</bundle>
54 - <bundle>mvn:org.onlab.onos/onos-core-hz-net/1.0.0-SNAPSHOT</bundle>
55 </feature> 52 </feature>
56 53
57 - <feature name="onos-core-dist" version="1.0.0" 54 + <feature name="onos-core-hazelcast" version="1.0.0"
58 - description="ONOS core components"> 55 + description="ONOS core components built on hazelcast">
59 <feature>onos-api</feature> 56 <feature>onos-api</feature>
60 <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle> 57 <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle>
61 <bundle>mvn:org.onlab.onos/onos-core-hz-common/1.0.0-SNAPSHOT</bundle> 58 <bundle>mvn:org.onlab.onos/onos-core-hz-common/1.0.0-SNAPSHOT</bundle>
......
...@@ -170,7 +170,7 @@ public abstract class MessageStream<M extends Message> { ...@@ -170,7 +170,7 @@ public abstract class MessageStream<M extends Message> {
170 } 170 }
171 171
172 /** 172 /**
173 - * Reads, withouth blocking, a list of messages from the stream. 173 + * Reads, without blocking, a list of messages from the stream.
174 * The list will be empty if there were not messages pending. 174 * The list will be empty if there were not messages pending.
175 * 175 *
176 * @return list of messages or null if backing channel has been closed 176 * @return list of messages or null if backing channel has been closed
......