blob: d0eae2da003c3defb7e63cf72bf33e755e10d0ac [file] [log] [blame]
Yuta HIGUCHI80912e62014-10-12 00:15:47 -07001package org.onlab.onos.store.mastership.impl;
tomb41d1ac2014-09-24 01:51:24 -07002
Yuta HIGUCHI80912e62014-10-12 00:15:47 -07003import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
alshabib339a3d92014-09-26 17:54:32 -07004
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -07005import java.util.Collections;
Ayaka Koshibe45503ce2014-10-14 11:26:45 -07006import java.util.LinkedList;
7import java.util.List;
alshabib339a3d92014-09-26 17:54:32 -07008import java.util.Map;
alshabib339a3d92014-09-26 17:54:32 -07009import java.util.Set;
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070010
tomb41d1ac2014-09-24 01:51:24 -070011import org.apache.felix.scr.annotations.Activate;
12import org.apache.felix.scr.annotations.Component;
13import org.apache.felix.scr.annotations.Deactivate;
14import org.apache.felix.scr.annotations.Reference;
15import org.apache.felix.scr.annotations.ReferenceCardinality;
16import org.apache.felix.scr.annotations.Service;
17import org.onlab.onos.cluster.ClusterService;
tomb41d1ac2014-09-24 01:51:24 -070018import org.onlab.onos.cluster.NodeId;
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070019import org.onlab.onos.mastership.MastershipEvent;
20import org.onlab.onos.mastership.MastershipStore;
21import org.onlab.onos.mastership.MastershipStoreDelegate;
22import org.onlab.onos.mastership.MastershipTerm;
tomb41d1ac2014-09-24 01:51:24 -070023import org.onlab.onos.net.DeviceId;
24import org.onlab.onos.net.MastershipRole;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070025import org.onlab.onos.store.common.AbstractHazelcastStore;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070026import org.onlab.onos.store.common.SMap;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070027import org.onlab.onos.store.serializers.KryoPoolUtil;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070028import org.onlab.onos.store.serializers.KryoSerializer;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070029import org.onlab.util.KryoPool;
tomb41d1ac2014-09-24 01:51:24 -070030
alshabib339a3d92014-09-26 17:54:32 -070031import com.google.common.collect.ImmutableSet;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070032import com.hazelcast.core.IAtomicLong;
tomb41d1ac2014-09-24 01:51:24 -070033
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070034import static org.onlab.onos.net.MastershipRole.*;
35
tomb41d1ac2014-09-24 01:51:24 -070036/**
Ayaka Koshibec4047702014-10-07 14:43:52 -070037 * Distributed implementation of the mastership store. The store is
38 * responsible for the master selection process.
tomb41d1ac2014-09-24 01:51:24 -070039 */
40@Component(immediate = true)
41@Service
tom0755a362014-09-24 11:54:43 -070042public class DistributedMastershipStore
Yuta HIGUCHI2e963892014-09-27 13:00:39 -070043extends AbstractHazelcastStore<MastershipEvent, MastershipStoreDelegate>
alshabib339a3d92014-09-26 17:54:32 -070044implements MastershipStore {
tomb41d1ac2014-09-24 01:51:24 -070045
Ayaka Koshibec4047702014-10-07 14:43:52 -070046 //initial term/TTL value
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070047 private static final Integer INIT = 0;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070048
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070049 //device to node roles
50 protected SMap<DeviceId, RoleValue> roleMap;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070051 //devices to terms
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070052 protected SMap<DeviceId, Integer> terms;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070053 //last-known cluster size, used for tie-breaking when partitioning occurs
54 protected IAtomicLong clusterSize;
55
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070056
tomb41d1ac2014-09-24 01:51:24 -070057 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected ClusterService clusterService;
59
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070060 @SuppressWarnings({ "unchecked", "rawtypes" })
Ayaka Koshibe406d0102014-09-24 16:08:12 -070061 @Override
tomb41d1ac2014-09-24 01:51:24 -070062 @Activate
63 public void activate() {
64 super.activate();
65
Ayaka Koshibee8e45352014-10-16 00:37:19 -070066 this.serializer = new KryoSerializer() {
67 @Override
68 protected void setupKryoPool() {
69 serializerPool = KryoPool.newBuilder()
70 .register(KryoPoolUtil.API)
71
72 .register(RoleValue.class, new RoleValueSerializer())
73 .build()
74 .populate(1);
75 }
76 };
77
78 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
79 terms = new SMap(theInstance.getMap("terms"), this.serializer);
80 clusterSize = theInstance.getAtomicLong("clustersize");
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070081 // roleMap.addEntryListener(new RemoteMasterShipEventHandler(), true);
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070082
tomb41d1ac2014-09-24 01:51:24 -070083 log.info("Started");
84 }
85
86 @Deactivate
87 public void deactivate() {
88 log.info("Stopped");
89 }
90
91 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -070092 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070093 NodeId current = getNode(MASTER, deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -070094 if (current == null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070095 if (isRole(STANDBY, nodeId, deviceId)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -070096 //was previously standby, or set to standby from master
97 return MastershipRole.STANDBY;
98 } else {
99 return MastershipRole.NONE;
100 }
101 } else {
102 if (current.equals(nodeId)) {
103 //*should* be in unusable, not always
104 return MastershipRole.MASTER;
105 } else {
106 //may be in backups or unusable from earlier retirement
107 return MastershipRole.STANDBY;
108 }
109 }
110 }
111
112 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700113 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -0700114
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700115 MastershipRole role = getRole(nodeId, deviceId);
116 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700117 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700118 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700119 switch (role) {
120 case MASTER:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700121 //reinforce mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700122 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700123 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700124 return null;
125 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700126 NodeId current = rv.get(MASTER);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700127 if (current != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700128 //backup and replace current master
129 rv.reassign(nodeId, NONE, STANDBY);
130 rv.replace(current, nodeId, MASTER);
131 } else {
132 //no master before so just add.
133 rv.add(MASTER, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700134 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700135 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700136 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700137 updateTerm(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700138 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
139 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700140 rv.add(MASTER, nodeId);
141 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700142 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700143 updateTerm(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700144 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700145 default:
146 log.warn("unknown Mastership Role {}", role);
147 return null;
148 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700149 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700150 roleMap.unlock(deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700151 }
152 }
153
154 @Override
155 public NodeId getMaster(DeviceId deviceId) {
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700156 return getNode(MASTER, deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700157 }
158
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700159
160 @Override
161 public List<NodeId> getNodes(DeviceId deviceId) {
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700162 List<NodeId> nodes = new LinkedList<>();
163
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700164 //add current master to head - if there is one.
165 roleMap.lock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700166 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700167 RoleValue rv = getRoleValue(deviceId);
168 NodeId master = rv.get(MASTER);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700169 if (master != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700170 nodes.add(master);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700171 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700172 //We ignore NONE nodes.
173 nodes.addAll(rv.nodesOfRole(STANDBY));
174 return Collections.unmodifiableList(nodes);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700175 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700176 roleMap.unlock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700177 }
178 }
179
tomb41d1ac2014-09-24 01:51:24 -0700180 @Override
181 public Set<DeviceId> getDevices(NodeId nodeId) {
182 ImmutableSet.Builder<DeviceId> builder = ImmutableSet.builder();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700183
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700184 for (Map.Entry<DeviceId, RoleValue> el : roleMap.entrySet()) {
185 if (nodeId.equals(el.getValue().get(MASTER))) {
186 builder.add(el.getKey());
tomb41d1ac2014-09-24 01:51:24 -0700187 }
188 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700189
tomb41d1ac2014-09-24 01:51:24 -0700190 return builder.build();
191 }
192
193 @Override
194 public MastershipRole requestRole(DeviceId deviceId) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700195 NodeId local = clusterService.getLocalNode().id();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700196
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700197 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700198 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700199 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700200 MastershipRole role = getRole(local, deviceId);
201 switch (role) {
202 case MASTER:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700203 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700204 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700205 break;
206 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700207 rv.reassign(local, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700208 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700209 terms.putIfAbsent(deviceId, INIT);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700210 break;
211 case NONE:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700212 //claim mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700213 rv.add(MASTER, local);
214 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700215 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700216 updateTerm(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700217 role = MastershipRole.MASTER;
218 break;
219 default:
220 log.warn("unknown Mastership Role {}", role);
221 }
222 return role;
223 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700224 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700225 }
tomb41d1ac2014-09-24 01:51:24 -0700226 }
227
228 @Override
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700229 public MastershipTerm getTermFor(DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700230 RoleValue rv = getRoleValue(deviceId);
231 if ((rv.get(MASTER) == null) || (terms.get(deviceId) == null)) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700232 return null;
233 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700234 return MastershipTerm.of(rv.get(MASTER), terms.get(deviceId));
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700235 }
236
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700237 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -0700238 public MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700239 MastershipEvent event = null;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700240
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700241 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700242 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700243 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700244 MastershipRole role = getRole(nodeId, deviceId);
245 switch (role) {
246 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700247 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700248 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700249 case STANDBY:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700250 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700251 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700252 rv.reassign(nodeId, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700253 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700254 break;
255 default:
256 log.warn("unknown Mastership Role {}", role);
257 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700258 return event;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700259 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700260 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700261 }
262 }
263
Ayaka Koshibec4047702014-10-07 14:43:52 -0700264 @Override
265 public MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700266 MastershipEvent event = null;
Ayaka Koshibe25fd23a2014-10-03 15:50:43 -0700267
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700268 roleMap.lock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700269 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700270 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700271 MastershipRole role = getRole(nodeId, deviceId);
272 switch (role) {
273 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700274 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700275 //fall through to reinforce relinquishment
Ayaka Koshibec4047702014-10-07 14:43:52 -0700276 case STANDBY:
277 //fall through to reinforce relinquishment
278 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700279 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700280 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700281 break;
282 default:
283 log.warn("unknown Mastership Role {}", role);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700284 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700285 return event;
286 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700287 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700288 }
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700289 }
290
Ayaka Koshibec4047702014-10-07 14:43:52 -0700291 //helper to fetch a new master candidate for a given device.
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700292 private MastershipEvent reelect(NodeId current, DeviceId deviceId, RoleValue rv) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700293
294 //if this is an queue it'd be neater.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700295 NodeId backup = null;
296 for (NodeId n : rv.nodesOfRole(STANDBY)) {
297 if (!current.equals(n)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700298 backup = n;
299 break;
300 }
301 }
302
303 if (backup == null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700304 rv.remove(MASTER, current);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700305 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700306 return null;
307 } else {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700308 rv.replace(current, backup, MASTER);
309 rv.reassign(backup, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700310 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700311 Integer term = terms.get(deviceId);
312 terms.put(deviceId, ++term);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700313 return new MastershipEvent(
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700314 MASTER_CHANGED, deviceId, backup);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700315 }
316 }
317
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700318 //return the RoleValue structure for a device, or create one
319 private RoleValue getRoleValue(DeviceId deviceId) {
320 RoleValue value = roleMap.get(deviceId);
321 if (value == null) {
322 value = new RoleValue();
323 roleMap.put(deviceId, value);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700324 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700325 return value;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700326 }
327
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700328 //get first applicable node out of store-unique structure.
329 private NodeId getNode(MastershipRole role, DeviceId deviceId) {
330 RoleValue value = roleMap.get(deviceId);
331 if (value != null) {
332 return value.get(role);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700333 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700334 return null;
335 }
336
337 //check if node is a certain role given a device
338 private boolean isRole(
339 MastershipRole role, NodeId nodeId, DeviceId deviceId) {
340 RoleValue value = roleMap.get(deviceId);
341 if (value != null) {
342 return value.contains(role, nodeId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700343 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700344 return false;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700345 }
346
347 //adds or updates term information.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700348 private void updateTerm(DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700349 Integer term = terms.get(deviceId);
350 if (term == null) {
351 terms.put(deviceId, INIT);
352 } else {
353 terms.put(deviceId, ++term);
354 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700355 }
356
Ayaka Koshibe5c0f2372014-10-02 17:59:04 -0700357 private class RemoteMasterShipEventHandler extends RemoteEventHandler<DeviceId, NodeId> {
alshabib339a3d92014-09-26 17:54:32 -0700358
359 @Override
360 protected void onAdd(DeviceId deviceId, NodeId nodeId) {
361 notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
362 }
363
364 @Override
365 protected void onRemove(DeviceId deviceId, NodeId nodeId) {
Ayaka Koshibe5c0f2372014-10-02 17:59:04 -0700366 //notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
alshabib339a3d92014-09-26 17:54:32 -0700367 }
368
369 @Override
370 protected void onUpdate(DeviceId deviceId, NodeId oldNodeId, NodeId nodeId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700371 //only addition indicates a change in mastership
Ayaka Koshibe5c0f2372014-10-02 17:59:04 -0700372 //notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
alshabib339a3d92014-09-26 17:54:32 -0700373 }
374 }
375
tomb41d1ac2014-09-24 01:51:24 -0700376}