blob: 28ba049c3b93db826a698e05d491e0e1adb1e95f [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;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070027import org.onlab.onos.store.serializers.KryoNamespaces;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070028import org.onlab.onos.store.serializers.KryoSerializer;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070029import org.onlab.util.KryoNamespace;
tomb41d1ac2014-09-24 01:51:24 -070030
alshabib339a3d92014-09-26 17:54:32 -070031import com.google.common.collect.ImmutableSet;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070032import com.hazelcast.core.EntryEvent;
33import com.hazelcast.core.EntryListener;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070034import com.hazelcast.core.IAtomicLong;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070035import com.hazelcast.core.MapEvent;
tomb41d1ac2014-09-24 01:51:24 -070036
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070037import static org.onlab.onos.net.MastershipRole.*;
38
tomb41d1ac2014-09-24 01:51:24 -070039/**
Ayaka Koshibec4047702014-10-07 14:43:52 -070040 * Distributed implementation of the mastership store. The store is
41 * responsible for the master selection process.
tomb41d1ac2014-09-24 01:51:24 -070042 */
43@Component(immediate = true)
44@Service
tom0755a362014-09-24 11:54:43 -070045public class DistributedMastershipStore
Yuta HIGUCHI2e963892014-09-27 13:00:39 -070046extends AbstractHazelcastStore<MastershipEvent, MastershipStoreDelegate>
alshabib339a3d92014-09-26 17:54:32 -070047implements MastershipStore {
tomb41d1ac2014-09-24 01:51:24 -070048
Ayaka Koshibec4047702014-10-07 14:43:52 -070049 //initial term/TTL value
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070050 private static final Integer INIT = 0;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070051
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070052 //device to node roles
53 protected SMap<DeviceId, RoleValue> roleMap;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070054 //devices to terms
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070055 protected SMap<DeviceId, Integer> terms;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070056 //last-known cluster size, used for tie-breaking when partitioning occurs
57 protected IAtomicLong clusterSize;
58
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070059
tomb41d1ac2014-09-24 01:51:24 -070060 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected ClusterService clusterService;
62
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070063 @SuppressWarnings({ "unchecked", "rawtypes" })
Ayaka Koshibe406d0102014-09-24 16:08:12 -070064 @Override
tomb41d1ac2014-09-24 01:51:24 -070065 @Activate
66 public void activate() {
67 super.activate();
68
Ayaka Koshibee8e45352014-10-16 00:37:19 -070069 this.serializer = new KryoSerializer() {
70 @Override
71 protected void setupKryoPool() {
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070072 serializerPool = KryoNamespace.newBuilder()
73 .register(KryoNamespaces.API)
Ayaka Koshibee8e45352014-10-16 00:37:19 -070074
75 .register(RoleValue.class, new RoleValueSerializer())
76 .build()
77 .populate(1);
78 }
79 };
80
81 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
Ayaka Koshibe67af1f42014-10-20 15:26:37 -070082 roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
Ayaka Koshibee8e45352014-10-16 00:37:19 -070083 terms = new SMap(theInstance.getMap("terms"), this.serializer);
84 clusterSize = theInstance.getAtomicLong("clustersize");
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070085
tomb41d1ac2014-09-24 01:51:24 -070086 log.info("Started");
87 }
88
89 @Deactivate
90 public void deactivate() {
91 log.info("Stopped");
92 }
93
94 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -070095 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070096 NodeId current = getNode(MASTER, deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -070097 if (current == null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070098 if (isRole(STANDBY, nodeId, deviceId)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -070099 //was previously standby, or set to standby from master
100 return MastershipRole.STANDBY;
101 } else {
102 return MastershipRole.NONE;
103 }
104 } else {
105 if (current.equals(nodeId)) {
106 //*should* be in unusable, not always
107 return MastershipRole.MASTER;
108 } else {
109 //may be in backups or unusable from earlier retirement
110 return MastershipRole.STANDBY;
111 }
112 }
113 }
114
115 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700116 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -0700117
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700118 MastershipRole role = getRole(nodeId, deviceId);
119 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700120 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700121 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700122 switch (role) {
123 case MASTER:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700124 //reinforce mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700125 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700126 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700127 return null;
128 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700129 NodeId current = rv.get(MASTER);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700130 if (current != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700131 //backup and replace current master
132 rv.reassign(nodeId, NONE, STANDBY);
133 rv.replace(current, nodeId, MASTER);
134 } else {
135 //no master before so just add.
136 rv.add(MASTER, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700137 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700138 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700139 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700140 updateTerm(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700141 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
142 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700143 rv.add(MASTER, nodeId);
144 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700145 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700146 updateTerm(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700147 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700148 default:
149 log.warn("unknown Mastership Role {}", role);
150 return null;
151 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700152 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700153 roleMap.unlock(deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700154 }
155 }
156
157 @Override
158 public NodeId getMaster(DeviceId deviceId) {
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700159 return getNode(MASTER, deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700160 }
161
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700162
163 @Override
164 public List<NodeId> getNodes(DeviceId deviceId) {
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700165 List<NodeId> nodes = new LinkedList<>();
166
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700167 //add current master to head - if there is one.
168 roleMap.lock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700169 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700170 RoleValue rv = getRoleValue(deviceId);
171 NodeId master = rv.get(MASTER);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700172 if (master != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700173 nodes.add(master);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700174 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700175 //We ignore NONE nodes.
176 nodes.addAll(rv.nodesOfRole(STANDBY));
177 return Collections.unmodifiableList(nodes);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700178 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700179 roleMap.unlock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700180 }
181 }
182
tomb41d1ac2014-09-24 01:51:24 -0700183 @Override
184 public Set<DeviceId> getDevices(NodeId nodeId) {
185 ImmutableSet.Builder<DeviceId> builder = ImmutableSet.builder();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700186
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700187 for (Map.Entry<DeviceId, RoleValue> el : roleMap.entrySet()) {
188 if (nodeId.equals(el.getValue().get(MASTER))) {
189 builder.add(el.getKey());
tomb41d1ac2014-09-24 01:51:24 -0700190 }
191 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700192
tomb41d1ac2014-09-24 01:51:24 -0700193 return builder.build();
194 }
195
196 @Override
197 public MastershipRole requestRole(DeviceId deviceId) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700198 NodeId local = clusterService.getLocalNode().id();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700199
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700200 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700201 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700202 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700203 MastershipRole role = getRole(local, deviceId);
204 switch (role) {
205 case MASTER:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700206 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700207 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700208 break;
209 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700210 rv.reassign(local, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700211 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700212 terms.putIfAbsent(deviceId, INIT);
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700213
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700214 break;
215 case NONE:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700216 //claim mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700217 rv.add(MASTER, local);
218 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700219 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700220 updateTerm(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700221 role = MastershipRole.MASTER;
222 break;
223 default:
224 log.warn("unknown Mastership Role {}", role);
225 }
226 return role;
227 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700228 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700229 }
tomb41d1ac2014-09-24 01:51:24 -0700230 }
231
232 @Override
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700233 public MastershipTerm getTermFor(DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700234 RoleValue rv = getRoleValue(deviceId);
235 if ((rv.get(MASTER) == null) || (terms.get(deviceId) == null)) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700236 return null;
237 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700238 return MastershipTerm.of(rv.get(MASTER), terms.get(deviceId));
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700239 }
240
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700241 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -0700242 public MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700243 MastershipEvent event = null;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700244
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700245 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700246 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700247 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700248 MastershipRole role = getRole(nodeId, deviceId);
249 switch (role) {
250 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700251 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700252 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700253 case STANDBY:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700254 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700255 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700256 rv.reassign(nodeId, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700257 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700258 break;
259 default:
260 log.warn("unknown Mastership Role {}", role);
261 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700262 return event;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700263 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700264 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700265 }
266 }
267
Ayaka Koshibec4047702014-10-07 14:43:52 -0700268 @Override
269 public MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700270 MastershipEvent event = null;
Ayaka Koshibe25fd23a2014-10-03 15:50:43 -0700271
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700272 roleMap.lock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700273 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700274 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700275 MastershipRole role = getRole(nodeId, deviceId);
276 switch (role) {
277 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700278 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700279 //fall through to reinforce relinquishment
Ayaka Koshibec4047702014-10-07 14:43:52 -0700280 case STANDBY:
281 //fall through to reinforce relinquishment
282 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700283 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700284 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700285 break;
286 default:
287 log.warn("unknown Mastership Role {}", role);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700288 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700289 return event;
290 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700291 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700292 }
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700293 }
294
Ayaka Koshibec4047702014-10-07 14:43:52 -0700295 //helper to fetch a new master candidate for a given device.
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700296 private MastershipEvent reelect(
297 NodeId current, DeviceId deviceId, RoleValue rv) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700298
299 //if this is an queue it'd be neater.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700300 NodeId backup = null;
301 for (NodeId n : rv.nodesOfRole(STANDBY)) {
302 if (!current.equals(n)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700303 backup = n;
304 break;
305 }
306 }
307
308 if (backup == null) {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700309 log.info("{} giving up and going to NONE for {}", current, deviceId);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700310 rv.remove(MASTER, current);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700311 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700312 return null;
313 } else {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700314 log.info("{} trying to pass mastership for {} to {}", current, deviceId, backup);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700315 rv.replace(current, backup, MASTER);
316 rv.reassign(backup, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700317 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700318 Integer term = terms.get(deviceId);
319 terms.put(deviceId, ++term);
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700320 return new MastershipEvent(MASTER_CHANGED, deviceId, backup);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700321 }
322 }
323
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700324 //return the RoleValue structure for a device, or create one
325 private RoleValue getRoleValue(DeviceId deviceId) {
326 RoleValue value = roleMap.get(deviceId);
327 if (value == null) {
328 value = new RoleValue();
329 roleMap.put(deviceId, value);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700330 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700331 return value;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700332 }
333
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700334 //get first applicable node out of store-unique structure.
335 private NodeId getNode(MastershipRole role, DeviceId deviceId) {
336 RoleValue value = roleMap.get(deviceId);
337 if (value != null) {
338 return value.get(role);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700339 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700340 return null;
341 }
342
343 //check if node is a certain role given a device
344 private boolean isRole(
345 MastershipRole role, NodeId nodeId, DeviceId deviceId) {
346 RoleValue value = roleMap.get(deviceId);
347 if (value != null) {
348 return value.contains(role, nodeId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700349 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700350 return false;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700351 }
352
353 //adds or updates term information.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700354 private void updateTerm(DeviceId deviceId) {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700355 terms.lock(deviceId);
356 try {
357 Integer term = terms.get(deviceId);
358 if (term == null) {
359 terms.put(deviceId, INIT);
360 } else {
361 terms.put(deviceId, ++term);
362 }
363 } finally {
364 terms.unlock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700365 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700366 }
367
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700368 private class RemoteMasterShipEventHandler implements EntryListener<DeviceId, RoleValue> {
alshabib339a3d92014-09-26 17:54:32 -0700369
370 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700371 public void entryAdded(EntryEvent<DeviceId, RoleValue> event) {
alshabib339a3d92014-09-26 17:54:32 -0700372 }
373
374 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700375 public void entryRemoved(EntryEvent<DeviceId, RoleValue> event) {
alshabib339a3d92014-09-26 17:54:32 -0700376 }
377
378 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700379 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
380 NodeId myId = clusterService.getLocalNode().id();
381 NodeId node = event.getValue().get(MASTER);
382 if (myId.equals(node)) {
383 // XXX or do we just let it get sent and caught by ourself?
384 return;
385 }
386 notifyDelegate(new MastershipEvent(
387 MASTER_CHANGED, event.getKey(), event.getValue().get(MASTER)));
388 }
389
390 @Override
391 public void entryEvicted(EntryEvent<DeviceId, RoleValue> event) {
392 }
393
394 @Override
395 public void mapEvicted(MapEvent event) {
396 }
397
398 @Override
399 public void mapCleared(MapEvent event) {
alshabib339a3d92014-09-26 17:54:32 -0700400 }
401 }
402
tomb41d1ac2014-09-24 01:51:24 -0700403}