tom

Further simplified the store & connection manager relationship.

Showing 16 changed files with 129 additions and 250 deletions
1 -package org.onlab.onos.ccc;
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.store.cluster.impl;
2 +
3 +import org.onlab.onos.cluster.DefaultControllerNode;
4 +
5 +/**
6 + * Service for administering communications manager.
7 + */
8 +public interface ClusterCommunicationAdminService {
9 +
10 + /**
11 + * Adds the node to the list of monitored nodes.
12 + *
13 + * @param node node to be added
14 + */
15 + void addNode(DefaultControllerNode node);
16 +
17 + /**
18 + * Removes the node from the list of monitored nodes.
19 + *
20 + * @param node node to be removed
21 + */
22 + void removeNode(DefaultControllerNode node);
23 +
24 + /**
25 + * Starts-up the communications engine.
26 + *
27 + * @param localNode local controller node
28 + * @param delegate nodes delegate
29 + */
30 + void startUp(DefaultControllerNode localNode, ClusterNodesDelegate delegate);
31 +
32 +}
...@@ -23,12 +23,12 @@ public class ClusterConnectionListener extends AcceptorLoop { ...@@ -23,12 +23,12 @@ public class ClusterConnectionListener extends AcceptorLoop {
23 private static final int SO_SEND_BUFFER_SIZE = COMM_BUFFER_SIZE; 23 private static final int SO_SEND_BUFFER_SIZE = COMM_BUFFER_SIZE;
24 private static final int SO_RCV_BUFFER_SIZE = COMM_BUFFER_SIZE; 24 private static final int SO_RCV_BUFFER_SIZE = COMM_BUFFER_SIZE;
25 25
26 - private final WorkerFinder workerFinder; 26 + private final ClusterCommunicationManager manager;
27 27
28 - ClusterConnectionListener(IpPrefix ip, int tcpPort, 28 + ClusterConnectionListener(ClusterCommunicationManager manager,
29 - WorkerFinder workerFinder) throws IOException { 29 + IpPrefix ip, int tcpPort) throws IOException {
30 super(SELECT_TIMEOUT, new InetSocketAddress(getByAddress(ip.toOctets()), tcpPort)); 30 super(SELECT_TIMEOUT, new InetSocketAddress(getByAddress(ip.toOctets()), tcpPort));
31 - this.workerFinder = workerFinder; 31 + this.manager = manager;
32 } 32 }
33 33
34 @Override 34 @Override
...@@ -41,7 +41,7 @@ public class ClusterConnectionListener extends AcceptorLoop { ...@@ -41,7 +41,7 @@ public class ClusterConnectionListener extends AcceptorLoop {
41 so.setReceiveBufferSize(SO_RCV_BUFFER_SIZE); 41 so.setReceiveBufferSize(SO_RCV_BUFFER_SIZE);
42 so.setSendBufferSize(SO_SEND_BUFFER_SIZE); 42 so.setSendBufferSize(SO_SEND_BUFFER_SIZE);
43 43
44 - workerFinder.findWorker().acceptStream(sc); 44 + manager.findWorker().acceptStream(sc);
45 } 45 }
46 46
47 } 47 }
......
...@@ -3,8 +3,10 @@ package org.onlab.onos.store.cluster.impl; ...@@ -3,8 +3,10 @@ package org.onlab.onos.store.cluster.impl;
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 import org.onlab.onos.cluster.DefaultControllerNode;
6 +import org.onlab.onos.cluster.NodeId;
6 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 7 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
7 import org.onlab.onos.store.cluster.messaging.ClusterMessageStream; 8 import org.onlab.onos.store.cluster.messaging.ClusterMessageStream;
9 +import org.onlab.onos.store.cluster.messaging.HelloMessage;
8 import org.onlab.onos.store.cluster.messaging.SerializationService; 10 import org.onlab.onos.store.cluster.messaging.SerializationService;
9 import org.slf4j.Logger; 11 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
...@@ -29,27 +31,23 @@ public class ClusterIOWorker extends ...@@ -29,27 +31,23 @@ public class ClusterIOWorker extends
29 31
30 private static final long SELECT_TIMEOUT = 50; 32 private static final long SELECT_TIMEOUT = 50;
31 33
32 - private final ConnectionManager connectionManager; 34 + private final ClusterCommunicationManager manager;
33 - private final CommunicationsDelegate commsDelegate;
34 private final SerializationService serializationService; 35 private final SerializationService serializationService;
35 private final ClusterMessage helloMessage; 36 private final ClusterMessage helloMessage;
36 37
37 /** 38 /**
38 * Creates a new cluster IO worker. 39 * Creates a new cluster IO worker.
39 * 40 *
40 - * @param connectionManager parent connection manager 41 + * @param manager parent comms manager
41 - * @param commsDelegate communications delegate for dispatching
42 * @param serializationService serialization service for encode/decode 42 * @param serializationService serialization service for encode/decode
43 * @param helloMessage hello message for greeting peers 43 * @param helloMessage hello message for greeting peers
44 * @throws IOException if errors occur during IO loop ignition 44 * @throws IOException if errors occur during IO loop ignition
45 */ 45 */
46 - ClusterIOWorker(ConnectionManager connectionManager, 46 + ClusterIOWorker(ClusterCommunicationManager manager,
47 - CommunicationsDelegate commsDelegate,
48 SerializationService serializationService, 47 SerializationService serializationService,
49 ClusterMessage helloMessage) throws IOException { 48 ClusterMessage helloMessage) throws IOException {
50 super(SELECT_TIMEOUT); 49 super(SELECT_TIMEOUT);
51 - this.connectionManager = connectionManager; 50 + this.manager = manager;
52 - this.commsDelegate = commsDelegate;
53 this.serializationService = serializationService; 51 this.serializationService = serializationService;
54 this.helloMessage = helloMessage; 52 this.helloMessage = helloMessage;
55 } 53 }
...@@ -61,11 +59,27 @@ public class ClusterIOWorker extends ...@@ -61,11 +59,27 @@ public class ClusterIOWorker extends
61 59
62 @Override 60 @Override
63 protected void processMessages(List<ClusterMessage> messages, MessageStream<ClusterMessage> stream) { 61 protected void processMessages(List<ClusterMessage> messages, MessageStream<ClusterMessage> stream) {
62 + NodeId nodeId = getNodeId(messages, (ClusterMessageStream) stream);
64 for (ClusterMessage message : messages) { 63 for (ClusterMessage message : messages) {
65 - commsDelegate.dispatch(message); 64 + manager.dispatch(message, nodeId);
66 } 65 }
67 } 66 }
68 67
68 + // Retrieves the node from the stream. If one is not bound, it attempts
69 + // to bind it using the knowledge that the first message must be a hello.
70 + private NodeId getNodeId(List<ClusterMessage> messages, ClusterMessageStream stream) {
71 + DefaultControllerNode node = stream.node();
72 + if (node == null && !messages.isEmpty()) {
73 + ClusterMessage firstMessage = messages.get(0);
74 + if (firstMessage instanceof HelloMessage) {
75 + HelloMessage hello = (HelloMessage) firstMessage;
76 + node = manager.addNodeStream(hello.nodeId(), hello.ipAddress(),
77 + hello.tcpPort(), stream);
78 + }
79 + }
80 + return node != null ? node.id() : null;
81 + }
82 +
69 @Override 83 @Override
70 public ClusterMessageStream acceptStream(SocketChannel channel) { 84 public ClusterMessageStream acceptStream(SocketChannel channel) {
71 ClusterMessageStream stream = super.acceptStream(channel); 85 ClusterMessageStream stream = super.acceptStream(channel);
...@@ -99,7 +113,7 @@ public class ClusterIOWorker extends ...@@ -99,7 +113,7 @@ public class ClusterIOWorker extends
99 DefaultControllerNode node = ((ClusterMessageStream) stream).node(); 113 DefaultControllerNode node = ((ClusterMessageStream) stream).node();
100 if (node != null) { 114 if (node != null) {
101 log.info("Closed connection to node {}", node.id()); 115 log.info("Closed connection to node {}", node.id());
102 - connectionManager.removeNodeStream(node); 116 + manager.removeNodeStream(node);
103 } 117 }
104 super.removeStream(stream); 118 super.removeStream(stream);
105 } 119 }
......
1 package org.onlab.onos.store.cluster.impl; 1 package org.onlab.onos.store.cluster.impl;
2 2
3 import org.onlab.onos.cluster.DefaultControllerNode; 3 import org.onlab.onos.cluster.DefaultControllerNode;
4 +import org.onlab.onos.cluster.NodeId;
5 +import org.onlab.packet.IpPrefix;
4 6
5 /** 7 /**
6 * Simple back interface through which connection manager can interact with 8 * Simple back interface through which connection manager can interact with
...@@ -9,17 +11,20 @@ import org.onlab.onos.cluster.DefaultControllerNode; ...@@ -9,17 +11,20 @@ import org.onlab.onos.cluster.DefaultControllerNode;
9 public interface ClusterNodesDelegate { 11 public interface ClusterNodesDelegate {
10 12
11 /** 13 /**
12 - * Notifies about a new cluster node being detected. 14 + * Notifies about cluster node coming online.
13 * 15 *
14 - * @param node newly detected cluster node 16 + * @param nodeId newly detected cluster node id
17 + * @param ip node IP listen address
18 + * @param tcpPort node TCP listen port
19 + * @return the controller node
15 */ 20 */
16 - void nodeDetected(DefaultControllerNode node); 21 + DefaultControllerNode nodeDetected(NodeId nodeId, IpPrefix ip, int tcpPort);
17 22
18 /** 23 /**
19 * Notifies about cluster node going offline. 24 * Notifies about cluster node going offline.
20 * 25 *
21 - * @param node cluster node that vanished 26 + * @param nodeId identifier of the cluster node that vanished
22 */ 27 */
23 - void nodeVanished(DefaultControllerNode node); 28 + void nodeVanished(NodeId nodeId);
24 29
25 } 30 }
......
1 -package org.onlab.onos.store.cluster.impl;
2 -
3 -import org.onlab.onos.store.cluster.messaging.ClusterMessage;
4 -
5 -/**
6 - * Simple back interface for interacting with the communications service.
7 - */
8 -public interface CommunicationsDelegate {
9 -
10 - /**
11 - * Dispatches the specified message to all registered subscribers.
12 - *
13 - * @param message message to be dispatched
14 - */
15 - void dispatch(ClusterMessage message);
16 -
17 - /**
18 - * Sets the sender.
19 - *
20 - * @param messageSender message sender
21 - */
22 - void setSender(MessageSender messageSender);
23 -
24 -}
...@@ -14,7 +14,6 @@ import org.onlab.onos.cluster.ControllerNode; ...@@ -14,7 +14,6 @@ import org.onlab.onos.cluster.ControllerNode;
14 import org.onlab.onos.cluster.DefaultControllerNode; 14 import org.onlab.onos.cluster.DefaultControllerNode;
15 import org.onlab.onos.cluster.NodeId; 15 import org.onlab.onos.cluster.NodeId;
16 import org.onlab.onos.store.AbstractStore; 16 import org.onlab.onos.store.AbstractStore;
17 -import org.onlab.onos.store.cluster.messaging.SerializationService;
18 import org.onlab.packet.IpPrefix; 17 import org.onlab.packet.IpPrefix;
19 import org.slf4j.Logger; 18 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory; 19 import org.slf4j.LoggerFactory;
...@@ -43,20 +42,20 @@ public class DistributedClusterStore ...@@ -43,20 +42,20 @@ public class DistributedClusterStore
43 private final Map<NodeId, State> states = new ConcurrentHashMap<>(); 42 private final Map<NodeId, State> states = new ConcurrentHashMap<>();
44 43
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 - private CommunicationsDelegate commsDelegate; 45 + private ClusterCommunicationAdminService communicationAdminService;
47 -
48 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 - private SerializationService serializationService;
50 46
51 private final ClusterNodesDelegate nodesDelegate = new InnerNodesDelegate(); 47 private final ClusterNodesDelegate nodesDelegate = new InnerNodesDelegate();
52 - private ConnectionManager connectionManager;
53 48
54 @Activate 49 @Activate
55 public void activate() { 50 public void activate() {
56 loadClusterDefinition(); 51 loadClusterDefinition();
57 establishSelfIdentity(); 52 establishSelfIdentity();
58 - connectionManager = new ConnectionManager(localNode, nodesDelegate, 53 +
59 - commsDelegate, serializationService); 54 + // Start-up the comm service and prime it with the loaded nodes.
55 + communicationAdminService.startUp(localNode, nodesDelegate);
56 + for (DefaultControllerNode node : nodes.values()) {
57 + communicationAdminService.addNode(node);
58 + }
60 log.info("Started"); 59 log.info("Started");
61 } 60 }
62 61
...@@ -92,8 +91,8 @@ public class DistributedClusterStore ...@@ -92,8 +91,8 @@ public class DistributedClusterStore
92 if (localNode == null) { 91 if (localNode == null) {
93 localNode = new DefaultControllerNode(new NodeId(ip.toString()), ip); 92 localNode = new DefaultControllerNode(new NodeId(ip.toString()), ip);
94 nodes.put(localNode.id(), localNode); 93 nodes.put(localNode.id(), localNode);
95 - states.put(localNode.id(), State.ACTIVE);
96 } 94 }
95 + states.put(localNode.id(), State.ACTIVE);
97 } 96 }
98 97
99 @Override 98 @Override
...@@ -122,7 +121,7 @@ public class DistributedClusterStore ...@@ -122,7 +121,7 @@ public class DistributedClusterStore
122 public ControllerNode addNode(NodeId nodeId, IpPrefix ip, int tcpPort) { 121 public ControllerNode addNode(NodeId nodeId, IpPrefix ip, int tcpPort) {
123 DefaultControllerNode node = new DefaultControllerNode(nodeId, ip, tcpPort); 122 DefaultControllerNode node = new DefaultControllerNode(nodeId, ip, tcpPort);
124 nodes.put(nodeId, node); 123 nodes.put(nodeId, node);
125 - connectionManager.addNode(node); 124 + communicationAdminService.addNode(node);
126 return node; 125 return node;
127 } 126 }
128 127
...@@ -130,21 +129,25 @@ public class DistributedClusterStore ...@@ -130,21 +129,25 @@ public class DistributedClusterStore
130 public void removeNode(NodeId nodeId) { 129 public void removeNode(NodeId nodeId) {
131 DefaultControllerNode node = nodes.remove(nodeId); 130 DefaultControllerNode node = nodes.remove(nodeId);
132 if (node != null) { 131 if (node != null) {
133 - connectionManager.removeNode(node); 132 + communicationAdminService.removeNode(node);
134 } 133 }
135 } 134 }
136 135
137 // Entity to handle back calls from the connection manager. 136 // Entity to handle back calls from the connection manager.
138 private class InnerNodesDelegate implements ClusterNodesDelegate { 137 private class InnerNodesDelegate implements ClusterNodesDelegate {
139 @Override 138 @Override
140 - public void nodeDetected(DefaultControllerNode node) { 139 + public DefaultControllerNode nodeDetected(NodeId nodeId, IpPrefix ip, int tcpPort) {
141 - nodes.put(node.id(), node); 140 + DefaultControllerNode node = nodes.get(nodeId);
142 - states.put(node.id(), State.ACTIVE); 141 + if (node == null) {
142 + node = (DefaultControllerNode) addNode(nodeId, ip, tcpPort);
143 + }
144 + states.put(nodeId, State.ACTIVE);
145 + return node;
143 } 146 }
144 -
145 @Override 147 @Override
146 - public void nodeVanished(DefaultControllerNode node) { 148 + public void nodeVanished(NodeId nodeId) {
147 - states.put(node.id(), State.INACTIVE); 149 + states.put(nodeId, State.INACTIVE);
148 } 150 }
149 } 151 }
152 +
150 } 153 }
......
1 -package org.onlab.onos.store.cluster.impl;
2 -
3 -import org.onlab.onos.cluster.NodeId;
4 -import org.onlab.onos.store.cluster.messaging.ClusterMessage;
5 -
6 -/**
7 - * Created by tom on 9/29/14.
8 - */
9 -public interface MessageSender {
10 -
11 - /**
12 - * Sends the specified message to the given cluster node.
13 - *
14 - * @param nodeId node identifier
15 - * @param message mesage to send
16 - * @return true if the message was sent sucessfully; false if there is
17 - * no stream or if there was an error
18 - */
19 - boolean send(NodeId nodeId, ClusterMessage message);
20 -
21 -}
1 -package org.onlab.onos.store.cluster.impl;
2 -
3 -/**
4 - * Provides means to find a worker IO loop.
5 - */
6 -public interface WorkerFinder {
7 -
8 - /**
9 - * Finds a suitable worker.
10 - *
11 - * @return available worker
12 - */
13 - ClusterIOWorker findWorker();
14 -}
...@@ -29,9 +29,9 @@ public class HelloMessage extends ClusterMessage { ...@@ -29,9 +29,9 @@ public class HelloMessage extends ClusterMessage {
29 */ 29 */
30 public HelloMessage(NodeId nodeId, IpPrefix ipAddress, int tcpPort) { 30 public HelloMessage(NodeId nodeId, IpPrefix ipAddress, int tcpPort) {
31 super(MessageSubject.HELLO); 31 super(MessageSubject.HELLO);
32 - nodeId = nodeId; 32 + this.nodeId = nodeId;
33 - ipAddress = ipAddress; 33 + this.ipAddress = ipAddress;
34 - tcpPort = tcpPort; 34 + this.tcpPort = tcpPort;
35 } 35 }
36 36
37 /** 37 /**
...@@ -60,4 +60,5 @@ public class HelloMessage extends ClusterMessage { ...@@ -60,4 +60,5 @@ public class HelloMessage extends ClusterMessage {
60 public int tcpPort() { 60 public int tcpPort() {
61 return tcpPort; 61 return tcpPort;
62 } 62 }
63 +
63 } 64 }
......
1 package org.onlab.onos.store.cluster.messaging; 1 package org.onlab.onos.store.cluster.messaging;
2 2
3 +import org.onlab.onos.cluster.NodeId;
4 +
3 /** 5 /**
4 * Represents a message consumer. 6 * Represents a message consumer.
5 */ 7 */
...@@ -8,8 +10,9 @@ public interface MessageSubscriber { ...@@ -8,8 +10,9 @@ public interface MessageSubscriber {
8 /** 10 /**
9 * Receives the specified cluster message. 11 * Receives the specified cluster message.
10 * 12 *
11 - * @param message message to be received 13 + * @param message message to be received
14 + * @param fromNodeId node from which the message was received
12 */ 15 */
13 - void receive(ClusterMessage message); 16 + void receive(ClusterMessage message, NodeId fromNodeId);
14 17
15 } 18 }
......
...@@ -3,12 +3,12 @@ package org.onlab.onos.store.cluster.messaging; ...@@ -3,12 +3,12 @@ package org.onlab.onos.store.cluster.messaging;
3 import java.nio.ByteBuffer; 3 import java.nio.ByteBuffer;
4 4
5 /** 5 /**
6 - * Service for serializing/deserializing intra-cluster messages. 6 + * Service for encoding &amp; decoding intra-cluster messages.
7 */ 7 */
8 public interface SerializationService { 8 public interface SerializationService {
9 9
10 /** 10 /**
11 - * Decodes the specified byte buffer to obtain a message within. 11 + * Decodes the specified byte buffer to obtain the message within.
12 * 12 *
13 * @param buffer byte buffer with message(s) 13 * @param buffer byte buffer with message(s)
14 * @return parsed message 14 * @return parsed message
......
1 -package org.onlab.onos.store.cluster.messaging.impl;
2 -
3 -import com.google.common.collect.HashMultimap;
4 -import com.google.common.collect.ImmutableSet;
5 -import com.google.common.collect.Multimap;
6 -import org.apache.felix.scr.annotations.Component;
7 -import org.apache.felix.scr.annotations.Service;
8 -import org.onlab.onos.cluster.NodeId;
9 -import org.onlab.onos.store.cluster.impl.CommunicationsDelegate;
10 -import org.onlab.onos.store.cluster.impl.MessageSender;
11 -import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
12 -import org.onlab.onos.store.cluster.messaging.ClusterMessage;
13 -import org.onlab.onos.store.cluster.messaging.MessageSubject;
14 -import org.onlab.onos.store.cluster.messaging.MessageSubscriber;
15 -
16 -import java.util.Set;
17 -
18 -/**
19 - * Implements the cluster communication services to use by other stores.
20 - */
21 -@Component(immediate = true)
22 -@Service
23 -public class ClusterCommunicationManager
24 - implements ClusterCommunicationService, CommunicationsDelegate {
25 -
26 - // TODO: use something different that won't require synchronization
27 - private Multimap<MessageSubject, MessageSubscriber> subscribers = HashMultimap.create();
28 - private MessageSender messageSender;
29 -
30 - @Override
31 - public boolean send(ClusterMessage message, NodeId toNodeId) {
32 - return messageSender.send(toNodeId, message);
33 - }
34 -
35 - @Override
36 - public synchronized void addSubscriber(MessageSubject subject, MessageSubscriber subscriber) {
37 - subscribers.put(subject, subscriber);
38 - }
39 -
40 - @Override
41 - public synchronized void removeSubscriber(MessageSubject subject, MessageSubscriber subscriber) {
42 - subscribers.remove(subject, subscriber);
43 - }
44 -
45 - @Override
46 - public Set<MessageSubscriber> getSubscribers(MessageSubject subject) {
47 - return ImmutableSet.copyOf(subscribers.get(subject));
48 - }
49 -
50 - @Override
51 - public void dispatch(ClusterMessage message) {
52 - Set<MessageSubscriber> set = getSubscribers(message.subject());
53 - if (set != null) {
54 - for (MessageSubscriber subscriber : set) {
55 - subscriber.receive(message);
56 - }
57 - }
58 - }
59 -
60 - @Override
61 - public void setSender(MessageSender messageSender) {
62 - this.messageSender = messageSender;
63 - }
64 -}
1 package org.onlab.onos.store.cluster.messaging.impl; 1 package org.onlab.onos.store.cluster.messaging.impl;
2 2
3 +import org.apache.felix.scr.annotations.Component;
4 +import org.apache.felix.scr.annotations.Service;
5 +import org.onlab.onos.cluster.NodeId;
3 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 6 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
7 +import org.onlab.onos.store.cluster.messaging.HelloMessage;
4 import org.onlab.onos.store.cluster.messaging.MessageSubject; 8 import org.onlab.onos.store.cluster.messaging.MessageSubject;
5 import org.onlab.onos.store.cluster.messaging.SerializationService; 9 import org.onlab.onos.store.cluster.messaging.SerializationService;
10 +import org.onlab.packet.IpPrefix;
11 +import org.slf4j.Logger;
12 +import org.slf4j.LoggerFactory;
6 13
7 import java.nio.ByteBuffer; 14 import java.nio.ByteBuffer;
8 15
...@@ -11,8 +18,12 @@ import static com.google.common.base.Preconditions.checkState; ...@@ -11,8 +18,12 @@ import static com.google.common.base.Preconditions.checkState;
11 /** 18 /**
12 * Factory for parsing messages sent between cluster members. 19 * Factory for parsing messages sent between cluster members.
13 */ 20 */
21 +@Component(immediate = true)
22 +@Service
14 public class MessageSerializer implements SerializationService { 23 public class MessageSerializer implements SerializationService {
15 24
25 + private final Logger log = LoggerFactory.getLogger(getClass());
26 +
16 private static final int METADATA_LENGTH = 16; // 8 + 4 + 4 27 private static final int METADATA_LENGTH = 16; // 8 + 4 + 4
17 private static final int LENGTH_OFFSET = 12; 28 private static final int LENGTH_OFFSET = 12;
18 29
...@@ -46,11 +57,12 @@ public class MessageSerializer implements SerializationService { ...@@ -46,11 +57,12 @@ public class MessageSerializer implements SerializationService {
46 buffer.get(data); 57 buffer.get(data);
47 58
48 // TODO: add deserialization hook here; for now this hack 59 // TODO: add deserialization hook here; for now this hack
49 - return null; // actually deserialize 60 + String[] fields = new String(data).split(":");
61 + return new HelloMessage(new NodeId(fields[0]), IpPrefix.valueOf(fields[1]), Integer.parseInt(fields[2]));
50 62
51 } catch (Exception e) { 63 } catch (Exception e) {
52 // TODO: recover from exceptions by forwarding stream to next marker 64 // TODO: recover from exceptions by forwarding stream to next marker
53 - e.printStackTrace(); 65 + log.warn("Unable to decode message due to: " + e);
54 } 66 }
55 return null; 67 return null;
56 } 68 }
...@@ -58,11 +70,18 @@ public class MessageSerializer implements SerializationService { ...@@ -58,11 +70,18 @@ public class MessageSerializer implements SerializationService {
58 @Override 70 @Override
59 public void encode(ClusterMessage message, ByteBuffer buffer) { 71 public void encode(ClusterMessage message, ByteBuffer buffer) {
60 try { 72 try {
61 - int i = 0; 73 + HelloMessage helloMessage = (HelloMessage) message;
62 - // Type based lookup for proper encoder 74 + buffer.putLong(MARKER);
75 + buffer.putInt(message.subject().ordinal());
76 +
77 + String str = helloMessage.nodeId() + ":" + helloMessage.ipAddress() + ":" + helloMessage.tcpPort();
78 + byte[] data = str.getBytes();
79 + buffer.putInt(data.length + METADATA_LENGTH);
80 + buffer.put(data);
81 +
63 } catch (Exception e) { 82 } catch (Exception e) {
64 // TODO: recover from exceptions by forwarding stream to next marker 83 // TODO: recover from exceptions by forwarding stream to next marker
65 - e.printStackTrace(); 84 + log.warn("Unable to encode message due to: " + e);
66 } 85 }
67 } 86 }
68 87
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
2 2
3 export ONOS_NIC=192.168.56.* 3 export ONOS_NIC=192.168.56.*
4 4
5 -export OC1="192.168.56.101" 5 +export OC1="192.168.56.11"
6 -export OC2="192.168.56.102" 6 +export OC2="192.168.56.12"
7 7
8 -export OCN="192.168.56.105" 8 +export OCN="192.168.56.7"
9 9
10 10
......