blob: 76374789e265e1fd8ede8dc2e3608ba4f5900af4 [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.NodeId;
18import org.onlab.onos.event.AbstractListenerRegistry;
19import org.onlab.onos.event.EventDeliveryService;
20import org.onlab.onos.net.DeviceId;
Madan Jampani58819b42014-10-09 13:48:51 -070021import org.onlab.onos.net.device.DeviceMastershipAdminService;
22import org.onlab.onos.net.device.DeviceMastershipEvent;
23import org.onlab.onos.net.device.DeviceMastershipListener;
Madan Jampani195af6e2014-10-09 15:01:17 -070024import org.onlab.onos.net.device.DeviceMastershipRole;
Madan Jampani58819b42014-10-09 13:48:51 -070025import org.onlab.onos.net.device.DeviceMastershipService;
26import org.onlab.onos.net.device.DeviceMastershipStore;
27import org.onlab.onos.net.device.DeviceMastershipStoreDelegate;
28import org.onlab.onos.net.device.DeviceMastershipTerm;
29import org.onlab.onos.net.device.DeviceMastershipTermService;
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
Madan Jampani58819b42014-10-09 13:48:51 -070035implements DeviceMastershipService, DeviceMastershipAdminService {
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
Madan Jampani58819b42014-10-09 13:48:51 -070043 protected final AbstractListenerRegistry<DeviceMastershipEvent, DeviceMastershipListener>
alshabib339a3d92014-09-26 17:54:32 -070044 listenerRegistry = new AbstractListenerRegistry<>();
45
Madan Jampani58819b42014-10-09 13:48:51 -070046 private final DeviceMastershipStoreDelegate delegate = new InternalDelegate();
Ayaka Koshibe16609692014-09-23 12:46:15 -070047
48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Madan Jampani58819b42014-10-09 13:48:51 -070049 protected DeviceMastershipStore store;
Ayaka Koshibe16609692014-09-23 12:46:15 -070050
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() {
Madan Jampani58819b42014-10-09 13:48:51 -070061 eventDispatcher.addSink(DeviceMastershipEvent.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() {
Madan Jampani58819b42014-10-09 13:48:51 -070069 eventDispatcher.removeSink(DeviceMastershipEvent.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
Madan Jampani195af6e2014-10-09 15:01:17 -070076 public void setRole(NodeId nodeId, DeviceId deviceId, DeviceMastershipRole role) {
Ayaka Koshibe16609692014-09-23 12:46:15 -070077 checkNotNull(nodeId, NODE_ID_NULL);
78 checkNotNull(deviceId, DEVICE_ID_NULL);
79 checkNotNull(role, ROLE_NULL);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070080
Madan Jampani58819b42014-10-09 13:48:51 -070081 DeviceMastershipEvent event = null;
Madan Jampani195af6e2014-10-09 15:01:17 -070082 if (role.equals(DeviceMastershipRole.MASTER)) {
Ayaka Koshibe971a38a2014-09-30 11:56:23 -070083 event = store.setMaster(nodeId, deviceId);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070084 } else {
Ayaka Koshibec4047702014-10-07 14:43:52 -070085 event = store.setStandby(nodeId, deviceId);
Ayaka Koshibe971a38a2014-09-30 11:56:23 -070086 }
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070087
Ayaka Koshibe971a38a2014-09-30 11:56:23 -070088 if (event != null) {
89 post(event);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070090 }
Ayaka Koshibe16609692014-09-23 12:46:15 -070091 }
92
93 @Override
Madan Jampani195af6e2014-10-09 15:01:17 -070094 public DeviceMastershipRole getLocalRole(DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -070095 checkNotNull(deviceId, DEVICE_ID_NULL);
96 return store.getRole(clusterService.getLocalNode().id(), deviceId);
97 }
98
99 @Override
100 public void relinquishMastership(DeviceId deviceId) {
Madan Jampani58819b42014-10-09 13:48:51 -0700101 DeviceMastershipEvent event = null;
Ayaka Koshibe1c292d72014-10-08 17:46:07 -0700102 event = store.relinquishRole(
103 clusterService.getLocalNode().id(), deviceId);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700104
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700105 if (event != null) {
106 post(event);
107 }
tomb41d1ac2014-09-24 01:51:24 -0700108 }
109
110 @Override
Madan Jampani195af6e2014-10-09 15:01:17 -0700111 public DeviceMastershipRole requestRoleFor(DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -0700112 checkNotNull(deviceId, DEVICE_ID_NULL);
113 return store.requestRole(deviceId);
114 }
115
116 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700117 public NodeId getMasterFor(DeviceId deviceId) {
118 checkNotNull(deviceId, DEVICE_ID_NULL);
119 return store.getMaster(deviceId);
120 }
121
122 @Override
123 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
124 checkNotNull(nodeId, NODE_ID_NULL);
125 return store.getDevices(nodeId);
126 }
127
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700128
129 @Override
Madan Jampani58819b42014-10-09 13:48:51 -0700130 public DeviceMastershipTermService requestTermService() {
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700131 return new InternalMastershipTermService();
132 }
133
Ayaka Koshibe16609692014-09-23 12:46:15 -0700134 @Override
Madan Jampani58819b42014-10-09 13:48:51 -0700135 public void addListener(DeviceMastershipListener listener) {
Ayaka Koshibe16609692014-09-23 12:46:15 -0700136 checkNotNull(listener);
137 listenerRegistry.addListener(listener);
138 }
139
140 @Override
Madan Jampani58819b42014-10-09 13:48:51 -0700141 public void removeListener(DeviceMastershipListener listener) {
Ayaka Koshibe16609692014-09-23 12:46:15 -0700142 checkNotNull(listener);
143 listenerRegistry.removeListener(listener);
144 }
145
tomb41d1ac2014-09-24 01:51:24 -0700146 // FIXME: provide wiring to allow events to be triggered by changes within the store
Ayaka Koshibe16609692014-09-23 12:46:15 -0700147
148 // Posts the specified event to the local event dispatcher.
Madan Jampani58819b42014-10-09 13:48:51 -0700149 private void post(DeviceMastershipEvent event) {
Ayaka Koshibe16609692014-09-23 12:46:15 -0700150 if (event != null && eventDispatcher != null) {
151 eventDispatcher.post(event);
152 }
153 }
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -0700154
Madan Jampani58819b42014-10-09 13:48:51 -0700155 private class InternalMastershipTermService implements DeviceMastershipTermService {
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700156
157 @Override
Madan Jampani58819b42014-10-09 13:48:51 -0700158 public DeviceMastershipTerm getMastershipTerm(DeviceId deviceId) {
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700159 return store.getTermFor(deviceId);
160 }
161
162 }
163
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700164 //callback for reacting to cluster events
165 private class InternalClusterEventListener implements ClusterEventListener {
166
167 @Override
168 public void event(ClusterEvent event) {
169 switch (event.type()) {
170 //FIXME: worry about addition when the time comes
171 case INSTANCE_ADDED:
172 case INSTANCE_ACTIVATED:
173 break;
174 case INSTANCE_REMOVED:
175 case INSTANCE_DEACTIVATED:
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700176 break;
177 default:
178 log.warn("unknown cluster event {}", event);
179 }
180 }
181
182 }
Ayaka Koshibe65efaef2014-09-29 18:21:56 -0700183
Madan Jampani58819b42014-10-09 13:48:51 -0700184 public class InternalDelegate implements DeviceMastershipStoreDelegate {
alshabib339a3d92014-09-26 17:54:32 -0700185
186 @Override
Madan Jampani58819b42014-10-09 13:48:51 -0700187 public void notify(DeviceMastershipEvent event) {
alshabib339a3d92014-09-26 17:54:32 -0700188 log.info("dispatching mastership event {}", event);
189 eventDispatcher.post(event);
190 }
191
192 }
193
Ayaka Koshibe16609692014-09-23 12:46:15 -0700194}