blob: 20ebc409522568a00d1957fa421cf8b240429366 [file] [log] [blame]
Ayaka Koshibe16609692014-09-23 12:46:15 -07001package org.onlab.onos.cluster.impl;
2
alshabib339a3d92014-09-26 17:54:32 -07003import static com.google.common.base.Preconditions.checkNotNull;
4import static org.slf4j.LoggerFactory.getLogger;
5
6import java.util.Set;
7
Ayaka Koshibe16609692014-09-23 12:46:15 -07008import org.apache.felix.scr.annotations.Activate;
tom4a5d1712014-09-23 17:49:39 -07009import org.apache.felix.scr.annotations.Component;
Ayaka Koshibe16609692014-09-23 12:46:15 -070010import org.apache.felix.scr.annotations.Deactivate;
11import org.apache.felix.scr.annotations.Reference;
12import org.apache.felix.scr.annotations.ReferenceCardinality;
tom4a5d1712014-09-23 17:49:39 -070013import org.apache.felix.scr.annotations.Service;
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070014import org.onlab.onos.cluster.ClusterEvent;
15import org.onlab.onos.cluster.ClusterEventListener;
tom4a5d1712014-09-23 17:49:39 -070016import org.onlab.onos.cluster.ClusterService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070017import org.onlab.onos.cluster.MastershipAdminService;
18import org.onlab.onos.cluster.MastershipEvent;
19import org.onlab.onos.cluster.MastershipListener;
Ayaka Koshibe16609692014-09-23 12:46:15 -070020import org.onlab.onos.cluster.MastershipService;
21import org.onlab.onos.cluster.MastershipStore;
alshabib339a3d92014-09-26 17:54:32 -070022import org.onlab.onos.cluster.MastershipStoreDelegate;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070023import org.onlab.onos.cluster.MastershipTerm;
24import org.onlab.onos.cluster.MastershipTermService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070025import org.onlab.onos.cluster.NodeId;
26import org.onlab.onos.event.AbstractListenerRegistry;
27import org.onlab.onos.event.EventDeliveryService;
28import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.MastershipRole;
Ayaka Koshibe16609692014-09-23 12:46:15 -070030import org.slf4j.Logger;
31
tom4a5d1712014-09-23 17:49:39 -070032@Component(immediate = true)
33@Service
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -070034public class MastershipManager
alshabib339a3d92014-09-26 17:54:32 -070035implements MastershipService, MastershipAdminService {
Ayaka Koshibe16609692014-09-23 12:46:15 -070036
37 private static final String NODE_ID_NULL = "Node ID cannot be null";
38 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
39 private static final String ROLE_NULL = "Mastership role cannot be null";
40
41 private final Logger log = getLogger(getClass());
42
43 protected final AbstractListenerRegistry<MastershipEvent, MastershipListener>
alshabib339a3d92014-09-26 17:54:32 -070044 listenerRegistry = new AbstractListenerRegistry<>();
45
46 private final MastershipStoreDelegate delegate = new InternalDelegate();
Ayaka Koshibe16609692014-09-23 12:46:15 -070047
48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 protected MastershipStore store;
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected EventDeliveryService eventDispatcher;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom4a5d1712014-09-23 17:49:39 -070055 protected ClusterService clusterService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070056
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070057 private ClusterEventListener clusterListener = new InternalClusterEventListener();
58
Ayaka Koshibe16609692014-09-23 12:46:15 -070059 @Activate
60 public void activate() {
61 eventDispatcher.addSink(MastershipEvent.class, listenerRegistry);
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070062 clusterService.addListener(clusterListener);
alshabib339a3d92014-09-26 17:54:32 -070063 store.setDelegate(delegate);
Ayaka Koshibe16609692014-09-23 12:46:15 -070064 log.info("Started");
65 }
66
67 @Deactivate
68 public void deactivate() {
69 eventDispatcher.removeSink(MastershipEvent.class);
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070070 clusterService.removeListener(clusterListener);
alshabib339a3d92014-09-26 17:54:32 -070071 store.unsetDelegate(delegate);
Ayaka Koshibe16609692014-09-23 12:46:15 -070072 log.info("Stopped");
73 }
74
Ayaka Koshibe16609692014-09-23 12:46:15 -070075 @Override
76 public void setRole(NodeId nodeId, DeviceId deviceId, MastershipRole role) {
77 checkNotNull(nodeId, NODE_ID_NULL);
78 checkNotNull(deviceId, DEVICE_ID_NULL);
79 checkNotNull(role, ROLE_NULL);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070080
81 MastershipRole current = store.getRole(nodeId, deviceId);
82 if (role.equals(current)) {
83 return;
84 } else {
85 MastershipEvent event = null;
86 if (role.equals(MastershipRole.MASTER)) {
87 //current was STANDBY, wanted MASTER
88 event = store.setMaster(nodeId, deviceId);
89 } else {
90 //current was MASTER, wanted STANDBY
91 event = store.unsetMaster(nodeId, deviceId);
92 }
93
Ayaka Koshibe406d0102014-09-24 16:08:12 -070094 if (event != null) {
95 post(event);
96 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070097 }
Ayaka Koshibe16609692014-09-23 12:46:15 -070098 }
99
100 @Override
tomb41d1ac2014-09-24 01:51:24 -0700101 public MastershipRole getLocalRole(DeviceId deviceId) {
102 checkNotNull(deviceId, DEVICE_ID_NULL);
103 return store.getRole(clusterService.getLocalNode().id(), deviceId);
104 }
105
106 @Override
107 public void relinquishMastership(DeviceId deviceId) {
108 checkNotNull(deviceId, DEVICE_ID_NULL);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700109
110 MastershipRole role = store.getRole(
111 clusterService.getLocalNode().id(), deviceId);
112 if (!role.equals(MastershipRole.MASTER)) {
113 return;
114 }
115
116 MastershipEvent event = store.unsetMaster(
117 clusterService.getLocalNode().id(), deviceId);
118 if (event != null) {
119 post(event);
120 }
tomb41d1ac2014-09-24 01:51:24 -0700121 }
122
123 @Override
124 public MastershipRole requestRoleFor(DeviceId deviceId) {
125 checkNotNull(deviceId, DEVICE_ID_NULL);
126 return store.requestRole(deviceId);
127 }
128
129 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700130 public NodeId getMasterFor(DeviceId deviceId) {
131 checkNotNull(deviceId, DEVICE_ID_NULL);
132 return store.getMaster(deviceId);
133 }
134
135 @Override
136 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
137 checkNotNull(nodeId, NODE_ID_NULL);
138 return store.getDevices(nodeId);
139 }
140
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700141
142 @Override
143 public MastershipTermService requestTermService() {
144 return new InternalMastershipTermService();
145 }
146
Ayaka Koshibe16609692014-09-23 12:46:15 -0700147 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700148 public void addListener(MastershipListener listener) {
149 checkNotNull(listener);
150 listenerRegistry.addListener(listener);
151 }
152
153 @Override
154 public void removeListener(MastershipListener listener) {
155 checkNotNull(listener);
156 listenerRegistry.removeListener(listener);
157 }
158
tomb41d1ac2014-09-24 01:51:24 -0700159 // FIXME: provide wiring to allow events to be triggered by changes within the store
Ayaka Koshibe16609692014-09-23 12:46:15 -0700160
161 // Posts the specified event to the local event dispatcher.
162 private void post(MastershipEvent event) {
163 if (event != null && eventDispatcher != null) {
164 eventDispatcher.post(event);
165 }
166 }
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -0700167
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700168 private class InternalMastershipTermService implements MastershipTermService {
169
170 @Override
171 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
172 return store.getTermFor(deviceId);
173 }
174
175 }
176
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700177 //callback for reacting to cluster events
178 private class InternalClusterEventListener implements ClusterEventListener {
179
180 @Override
181 public void event(ClusterEvent event) {
182 switch (event.type()) {
183 //FIXME: worry about addition when the time comes
184 case INSTANCE_ADDED:
185 case INSTANCE_ACTIVATED:
186 break;
187 case INSTANCE_REMOVED:
188 case INSTANCE_DEACTIVATED:
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700189 break;
190 default:
191 log.warn("unknown cluster event {}", event);
192 }
193 }
194
195 }
Ayaka Koshibe65efaef2014-09-29 18:21:56 -0700196
alshabib339a3d92014-09-26 17:54:32 -0700197 public class InternalDelegate implements MastershipStoreDelegate {
198
199 @Override
200 public void notify(MastershipEvent event) {
201 log.info("dispatching mastership event {}", event);
202 eventDispatcher.post(event);
203 }
204
205 }
206
Ayaka Koshibe16609692014-09-23 12:46:15 -0700207}