blob: 11577ad0dda6980df02ab9ce6cb7ff3ca067be85 [file] [log] [blame]
Ayaka Koshibea7f044e2014-09-23 16:56:20 -07001package org.onlab.onos.net.trivial.impl;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.Collections;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -07006import java.util.HashMap;
Ayaka Koshibe406d0102014-09-24 16:08:12 -07007import java.util.HashSet;
8import java.util.Map;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -07009import java.util.Set;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070010import java.util.concurrent.atomic.AtomicInteger;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070011
12import org.apache.felix.scr.annotations.Activate;
13import org.apache.felix.scr.annotations.Component;
14import org.apache.felix.scr.annotations.Deactivate;
15import org.apache.felix.scr.annotations.Service;
16import org.onlab.onos.cluster.ControllerNode;
17import org.onlab.onos.cluster.DefaultControllerNode;
18import org.onlab.onos.cluster.MastershipEvent;
19import org.onlab.onos.cluster.MastershipStore;
tomf80c9722014-09-24 14:49:18 -070020import org.onlab.onos.cluster.MastershipStoreDelegate;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070021import org.onlab.onos.cluster.MastershipTerm;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070022import org.onlab.onos.cluster.NodeId;
23import org.onlab.onos.net.DeviceId;
24import org.onlab.onos.net.MastershipRole;
tomf80c9722014-09-24 14:49:18 -070025import org.onlab.onos.store.AbstractStore;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070026import org.onlab.packet.IpPrefix;
27import org.slf4j.Logger;
28
29import static org.onlab.onos.cluster.MastershipEvent.Type.*;
30
31/**
32 * Manages inventory of controller mastership over devices using
Ayaka Koshibe406d0102014-09-24 16:08:12 -070033 * trivial, non-distributed in-memory structures implementation.
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070034 */
35@Component(immediate = true)
36@Service
tomf80c9722014-09-24 14:49:18 -070037public class SimpleMastershipStore
38 extends AbstractStore<MastershipEvent, MastershipStoreDelegate>
39 implements MastershipStore {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070040
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070041 private final Logger log = getLogger(getClass());
42
Ayaka Koshibe406d0102014-09-24 16:08:12 -070043 public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1");
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070044
Ayaka Koshibe406d0102014-09-24 16:08:12 -070045 private ControllerNode instance =
46 new DefaultControllerNode(new NodeId("local"), LOCALHOST);
47
48 //devices mapped to their masters, to emulate multiple nodes
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070049 protected final Map<DeviceId, NodeId> masterMap = new HashMap<>();
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070050 protected final Map<DeviceId, AtomicInteger> termMap = new HashMap<>();
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070051 protected final Set<NodeId> masters = new HashSet<>();
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070052
53 @Activate
54 public void activate() {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070055 log.info("Started");
56 }
57
58 @Deactivate
59 public void deactivate() {
60 log.info("Stopped");
61 }
62
63 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -070064 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
65
66 NodeId node = masterMap.get(deviceId);
67 if (node == null) {
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070068 synchronized (this) {
69 masterMap.put(deviceId, nodeId);
70 termMap.put(deviceId, new AtomicInteger());
71 }
Ayaka Koshibe406d0102014-09-24 16:08:12 -070072 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070073 }
Ayaka Koshibe406d0102014-09-24 16:08:12 -070074
75 if (node.equals(nodeId)) {
76 return null;
77 } else {
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070078 synchronized (this) {
79 masterMap.put(deviceId, nodeId);
80 termMap.get(deviceId).incrementAndGet();
81 return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
82 }
Ayaka Koshibe406d0102014-09-24 16:08:12 -070083 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070084 }
85
86 @Override
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070087 public NodeId getMaster(DeviceId deviceId) {
Ayaka Koshibe406d0102014-09-24 16:08:12 -070088 return masterMap.get(deviceId);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070089 }
90
91 @Override
92 public Set<DeviceId> getDevices(NodeId nodeId) {
Ayaka Koshibe406d0102014-09-24 16:08:12 -070093 Set<DeviceId> ids = new HashSet<>();
94 for (Map.Entry<DeviceId, NodeId> d : masterMap.entrySet()) {
95 if (d.getValue().equals(nodeId)) {
96 ids.add(d.getKey());
97 }
98 }
99 return Collections.unmodifiableSet(ids);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700100 }
101
102 @Override
tomb41d1ac2014-09-24 01:51:24 -0700103 public MastershipRole requestRole(DeviceId deviceId) {
104 return getRole(instance.id(), deviceId);
105 }
106
107 @Override
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700108 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700109 NodeId node = masterMap.get(deviceId);
110 MastershipRole role;
111 if (node != null) {
112 if (node.equals(nodeId)) {
113 role = MastershipRole.MASTER;
114 } else {
115 role = MastershipRole.STANDBY;
116 }
117 } else {
118 //masterMap doesn't contain it.
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700119 role = MastershipRole.MASTER;
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700120 masterMap.put(deviceId, nodeId);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700121 }
122 return role;
123 }
124
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700125 @Override
126 public MastershipTerm getTermFor(DeviceId deviceId) {
127 if (masterMap.get(deviceId) == null) {
128 return null;
129 }
130 return MastershipTerm.of(
131 masterMap.get(deviceId), termMap.get(deviceId).get());
132 }
133
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700134}