Madan Jampani
Committed by Brian O'Connor

Using ClusterCommunicationService instead of ITopic for notifying cluster member…

…s of leadership events.

Change-Id: I164f30da436f3e4f65c4e938c25bb2aa2faa16c3
...@@ -18,9 +18,6 @@ package org.onosproject.store.cluster.impl; ...@@ -18,9 +18,6 @@ package org.onosproject.store.cluster.impl;
18 import com.google.common.collect.Maps; 18 import com.google.common.collect.Maps;
19 import com.hazelcast.config.TopicConfig; 19 import com.hazelcast.config.TopicConfig;
20 import com.hazelcast.core.IAtomicLong; 20 import com.hazelcast.core.IAtomicLong;
21 -import com.hazelcast.core.ITopic;
22 -import com.hazelcast.core.Message;
23 -import com.hazelcast.core.MessageListener;
24 import org.apache.felix.scr.annotations.Activate; 21 import org.apache.felix.scr.annotations.Activate;
25 import org.apache.felix.scr.annotations.Component; 22 import org.apache.felix.scr.annotations.Component;
26 import org.apache.felix.scr.annotations.Deactivate; 23 import org.apache.felix.scr.annotations.Deactivate;
...@@ -36,6 +33,10 @@ import org.onosproject.cluster.LeadershipService; ...@@ -36,6 +33,10 @@ import org.onosproject.cluster.LeadershipService;
36 import org.onosproject.cluster.NodeId; 33 import org.onosproject.cluster.NodeId;
37 import org.onosproject.event.AbstractListenerRegistry; 34 import org.onosproject.event.AbstractListenerRegistry;
38 import org.onosproject.event.EventDeliveryService; 35 import org.onosproject.event.EventDeliveryService;
36 +import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
37 +import org.onosproject.store.cluster.messaging.ClusterMessage;
38 +import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
39 +import org.onosproject.store.cluster.messaging.MessageSubject;
39 import org.onosproject.store.hz.StoreService; 40 import org.onosproject.store.hz.StoreService;
40 import org.onosproject.store.serializers.KryoNamespaces; 41 import org.onosproject.store.serializers.KryoNamespaces;
41 import org.onosproject.store.serializers.KryoSerializer; 42 import org.onosproject.store.serializers.KryoSerializer;
...@@ -71,8 +72,7 @@ import static org.onlab.util.Tools.namedThreads; ...@@ -71,8 +72,7 @@ import static org.onlab.util.Tools.namedThreads;
71 */ 72 */
72 @Component(immediate = true) 73 @Component(immediate = true)
73 @Service 74 @Service
74 -public class HazelcastLeadershipService implements LeadershipService, 75 +public class HazelcastLeadershipService implements LeadershipService {
75 - MessageListener<byte[]> {
76 private static final Logger log = 76 private static final Logger log =
77 LoggerFactory.getLogger(HazelcastLeadershipService.class); 77 LoggerFactory.getLogger(HazelcastLeadershipService.class);
78 78
...@@ -94,6 +94,9 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -94,6 +94,9 @@ public class HazelcastLeadershipService implements LeadershipService,
94 private static final long NO_TERM = 0; 94 private static final long NO_TERM = 0;
95 95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 + protected ClusterCommunicationService clusterCommunicator;
98 +
99 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected ClusterService clusterService; 100 protected ClusterService clusterService;
98 101
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -107,8 +110,8 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -107,8 +110,8 @@ public class HazelcastLeadershipService implements LeadershipService,
107 private final Map<String, Topic> topics = Maps.newConcurrentMap(); 110 private final Map<String, Topic> topics = Maps.newConcurrentMap();
108 private NodeId localNodeId; 111 private NodeId localNodeId;
109 112
110 - private ITopic<byte[]> leaderTopic; 113 + private static final MessageSubject LEADERSHIP_EVENT_MESSAGE_SUBJECT =
111 - private String leaderTopicRegistrationId; 114 + new MessageSubject("hz-leadership-events");
112 115
113 @Activate 116 @Activate
114 protected void activate() { 117 protected void activate() {
...@@ -120,8 +123,8 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -120,8 +123,8 @@ public class HazelcastLeadershipService implements LeadershipService,
120 topicConfig.setGlobalOrderingEnabled(true); 123 topicConfig.setGlobalOrderingEnabled(true);
121 topicConfig.setName(TOPIC_HZ_ID); 124 topicConfig.setName(TOPIC_HZ_ID);
122 storeService.getHazelcastInstance().getConfig().addTopicConfig(topicConfig); 125 storeService.getHazelcastInstance().getConfig().addTopicConfig(topicConfig);
123 - leaderTopic = storeService.getHazelcastInstance().getTopic(TOPIC_HZ_ID); 126 +
124 - leaderTopicRegistrationId = leaderTopic.addMessageListener(this); 127 + clusterCommunicator.addSubscriber(LEADERSHIP_EVENT_MESSAGE_SUBJECT, new InternalLeadershipEventListener());
125 128
126 log.info("Hazelcast Leadership Service started"); 129 log.info("Hazelcast Leadership Service started");
127 } 130 }
...@@ -129,7 +132,7 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -129,7 +132,7 @@ public class HazelcastLeadershipService implements LeadershipService,
129 @Deactivate 132 @Deactivate
130 protected void deactivate() { 133 protected void deactivate() {
131 eventDispatcher.removeSink(LeadershipEvent.class); 134 eventDispatcher.removeSink(LeadershipEvent.class);
132 - leaderTopic.removeMessageListener(leaderTopicRegistrationId); 135 + clusterCommunicator.removeSubscriber(LEADERSHIP_EVENT_MESSAGE_SUBJECT);
133 136
134 for (Topic topic : topics.values()) { 137 for (Topic topic : topics.values()) {
135 topic.stop(); 138 topic.stop();
...@@ -194,35 +197,6 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -194,35 +197,6 @@ public class HazelcastLeadershipService implements LeadershipService,
194 listenerRegistry.removeListener(listener); 197 listenerRegistry.removeListener(listener);
195 } 198 }
196 199
197 - @Override
198 - public void onMessage(Message<byte[]> message) {
199 - LeadershipEvent leadershipEvent =
200 - SERIALIZER.decode(message.getMessageObject());
201 -
202 - log.trace("Leadership Event: time = {} type = {} event = {}",
203 - leadershipEvent.time(), leadershipEvent.type(),
204 - leadershipEvent);
205 -
206 - //
207 - // If there is no entry for the topic, then create a new one to
208 - // keep track of the leadership, but don't run for leadership itself.
209 - //
210 - String topicName = leadershipEvent.subject().topic();
211 - Topic topic = topics.get(topicName);
212 - if (topic == null) {
213 - topic = new Topic(topicName);
214 - Topic oldTopic = topics.putIfAbsent(topicName, topic);
215 - if (oldTopic == null) {
216 - // encountered new topic, start periodic processing
217 - topic.start();
218 - } else {
219 - topic = oldTopic;
220 - }
221 - }
222 - topic.receivedLeadershipEvent(leadershipEvent);
223 - eventDispatcher.post(leadershipEvent);
224 - }
225 -
226 /** 200 /**
227 * Class for keeping per-topic information. 201 * Class for keeping per-topic information.
228 */ 202 */
...@@ -406,7 +380,12 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -406,7 +380,12 @@ public class HazelcastLeadershipService implements LeadershipService,
406 LeadershipEvent.Type.LEADER_REELECTED, 380 LeadershipEvent.Type.LEADER_REELECTED,
407 new Leadership(topicName, localNodeId, myLastLeaderTerm)); 381 new Leadership(topicName, localNodeId, myLastLeaderTerm));
408 // Dispatch to all instances 382 // Dispatch to all instances
409 - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); 383 +
384 + clusterCommunicator.broadcastIncludeSelf(
385 + new ClusterMessage(
386 + clusterService.getLocalNode().id(),
387 + LEADERSHIP_EVENT_MESSAGE_SUBJECT,
388 + SERIALIZER.encode(leadershipEvent)));
410 } else { 389 } else {
411 // 390 //
412 // Test if time to expire a stale leader 391 // Test if time to expire a stale leader
...@@ -473,7 +452,11 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -473,7 +452,11 @@ public class HazelcastLeadershipService implements LeadershipService,
473 leadershipEvent = new LeadershipEvent( 452 leadershipEvent = new LeadershipEvent(
474 LeadershipEvent.Type.LEADER_ELECTED, 453 LeadershipEvent.Type.LEADER_ELECTED,
475 new Leadership(topicName, localNodeId, myLastLeaderTerm)); 454 new Leadership(topicName, localNodeId, myLastLeaderTerm));
476 - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); 455 + clusterCommunicator.broadcastIncludeSelf(
456 + new ClusterMessage(
457 + clusterService.getLocalNode().id(),
458 + LEADERSHIP_EVENT_MESSAGE_SUBJECT,
459 + SERIALIZER.encode(leadershipEvent)));
477 } 460 }
478 461
479 // Sleep forever until interrupted 462 // Sleep forever until interrupted
...@@ -497,7 +480,11 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -497,7 +480,11 @@ public class HazelcastLeadershipService implements LeadershipService,
497 leadershipEvent = new LeadershipEvent( 480 leadershipEvent = new LeadershipEvent(
498 LeadershipEvent.Type.LEADER_BOOTED, 481 LeadershipEvent.Type.LEADER_BOOTED,
499 new Leadership(topicName, localNodeId, myLastLeaderTerm)); 482 new Leadership(topicName, localNodeId, myLastLeaderTerm));
500 - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); 483 + clusterCommunicator.broadcastIncludeSelf(
484 + new ClusterMessage(
485 + clusterService.getLocalNode().id(),
486 + LEADERSHIP_EVENT_MESSAGE_SUBJECT,
487 + SERIALIZER.encode(leadershipEvent)));
501 leaderLock.unlock(); 488 leaderLock.unlock();
502 } 489 }
503 } 490 }
...@@ -515,4 +502,35 @@ public class HazelcastLeadershipService implements LeadershipService, ...@@ -515,4 +502,35 @@ public class HazelcastLeadershipService implements LeadershipService,
515 oldTerm, newTerm); 502 oldTerm, newTerm);
516 } 503 }
517 } 504 }
505 +
506 + private class InternalLeadershipEventListener implements ClusterMessageHandler {
507 +
508 + @Override
509 + public void handle(ClusterMessage message) {
510 + LeadershipEvent leadershipEvent =
511 + SERIALIZER.decode(message.payload());
512 +
513 + log.trace("Leadership Event: time = {} type = {} event = {}",
514 + leadershipEvent.time(), leadershipEvent.type(),
515 + leadershipEvent);
516 + //
517 + // If there is no entry for the topic, then create a new one to
518 + // keep track of the leadership, but don't run for leadership itself.
519 + //
520 + String topicName = leadershipEvent.subject().topic();
521 + Topic topic = topics.get(topicName);
522 + if (topic == null) {
523 + topic = new Topic(topicName);
524 + Topic oldTopic = topics.putIfAbsent(topicName, topic);
525 + if (oldTopic == null) {
526 + // encountered new topic, start periodic processing
527 + topic.start();
528 + } else {
529 + topic = oldTopic;
530 + }
531 + }
532 + topic.receivedLeadershipEvent(leadershipEvent);
533 + eventDispatcher.post(leadershipEvent);
534 + }
535 + }
518 } 536 }
......