blob: 46bf6afc1b49be1f682a35aa5d5b28b8613fb444 [file] [log] [blame]
tomb41d1ac2014-09-24 01:51:24 -07001package org.onlab.onos.store.cluster.impl;
2
3import com.google.common.base.Optional;
4import com.google.common.cache.LoadingCache;
5import com.google.common.collect.ImmutableSet;
6import com.hazelcast.core.IMap;
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -07007
tomb41d1ac2014-09-24 01:51:24 -07008import org.apache.felix.scr.annotations.Activate;
9import org.apache.felix.scr.annotations.Component;
10import org.apache.felix.scr.annotations.Deactivate;
11import org.apache.felix.scr.annotations.Reference;
12import org.apache.felix.scr.annotations.ReferenceCardinality;
13import org.apache.felix.scr.annotations.Service;
14import org.onlab.onos.cluster.ClusterService;
15import org.onlab.onos.cluster.MastershipEvent;
16import org.onlab.onos.cluster.MastershipStore;
tom0755a362014-09-24 11:54:43 -070017import org.onlab.onos.cluster.MastershipStoreDelegate;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070018import org.onlab.onos.cluster.MastershipTerm;
tomb41d1ac2014-09-24 01:51:24 -070019import org.onlab.onos.cluster.NodeId;
20import org.onlab.onos.net.DeviceId;
21import org.onlab.onos.net.MastershipRole;
22import org.onlab.onos.store.impl.AbsentInvalidatingLoadingCache;
23import org.onlab.onos.store.impl.AbstractDistributedStore;
24import org.onlab.onos.store.impl.OptionalCacheLoader;
25
26import java.util.Map;
27import java.util.Objects;
28import java.util.Set;
29
30import static com.google.common.cache.CacheBuilder.newBuilder;
31
32/**
33 * Distributed implementation of the cluster nodes store.
34 */
35@Component(immediate = true)
36@Service
tom0755a362014-09-24 11:54:43 -070037public class DistributedMastershipStore
38 extends AbstractDistributedStore<MastershipEvent, MastershipStoreDelegate>
tomb41d1ac2014-09-24 01:51:24 -070039 implements MastershipStore {
40
41 private IMap<byte[], byte[]> rawMasters;
42 private LoadingCache<DeviceId, Optional<NodeId>> masters;
43
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 protected ClusterService clusterService;
46
Ayaka Koshibe406d0102014-09-24 16:08:12 -070047 @Override
tomb41d1ac2014-09-24 01:51:24 -070048 @Activate
49 public void activate() {
50 super.activate();
51
52 rawMasters = theInstance.getMap("masters");
53 OptionalCacheLoader<DeviceId, NodeId> nodeLoader
54 = new OptionalCacheLoader<>(storeService, rawMasters);
55 masters = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader));
56 rawMasters.addEntryListener(new RemoteEventHandler<>(masters), true);
57
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070058 loadMasters();
59
tomb41d1ac2014-09-24 01:51:24 -070060 log.info("Started");
61 }
62
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070063 private void loadMasters() {
64 for (byte[] keyBytes : rawMasters.keySet()) {
65 final DeviceId id = deserialize(keyBytes);
66 masters.refresh(id);
67 }
68 }
69
tomb41d1ac2014-09-24 01:51:24 -070070 @Deactivate
71 public void deactivate() {
72 log.info("Stopped");
73 }
74
75 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -070076 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -070077 synchronized (this) {
78 NodeId currentMaster = getMaster(deviceId);
Ayaka Koshibe406d0102014-09-24 16:08:12 -070079 if (Objects.equals(currentMaster, nodeId)) {
tomb41d1ac2014-09-24 01:51:24 -070080 return null;
81 }
82
83 // FIXME: for now implementing semantics of setMaster
84 rawMasters.put(serialize(deviceId), serialize(nodeId));
85 masters.put(deviceId, Optional.of(nodeId));
86 return new MastershipEvent(MastershipEvent.Type.MASTER_CHANGED, deviceId, nodeId);
87 }
88 }
89
90 @Override
91 public NodeId getMaster(DeviceId deviceId) {
92 return masters.getUnchecked(deviceId).orNull();
93 }
94
95 @Override
96 public Set<DeviceId> getDevices(NodeId nodeId) {
97 ImmutableSet.Builder<DeviceId> builder = ImmutableSet.builder();
98 for (Map.Entry<DeviceId, Optional<NodeId>> entry : masters.asMap().entrySet()) {
99 if (nodeId.equals(entry.getValue().get())) {
100 builder.add(entry.getKey());
101 }
102 }
103 return builder.build();
104 }
105
106 @Override
107 public MastershipRole requestRole(DeviceId deviceId) {
108 // FIXME: for now we are 'selecting' as master whoever asks
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700109 setMaster(clusterService.getLocalNode().id(), deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700110 return MastershipRole.MASTER;
111 }
112
113 @Override
114 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
115 NodeId master = masters.getUnchecked(deviceId).orNull();
116 return nodeId.equals(master) ? MastershipRole.MASTER : MastershipRole.STANDBY;
117 }
118
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700119 @Override
120 public MastershipTerm getTermFor(DeviceId deviceId) {
121 // TODO Auto-generated method stub
122 return null;
123 }
124
tomb41d1ac2014-09-24 01:51:24 -0700125}