blob: a0da87c56f09be68df1925c9cbb5967cea9d233b [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
Ayaka Koshibe971a38a2014-09-30 11:56:23 -070081 MastershipEvent event = null;
82 if (role.equals(MastershipRole.MASTER)) {
83 event = store.setMaster(nodeId, deviceId);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070084 } else {
Ayaka Koshibe971a38a2014-09-30 11:56:23 -070085 event = store.unsetMaster(nodeId, deviceId);
86 }
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
tomb41d1ac2014-09-24 01:51:24 -070094 public MastershipRole getLocalRole(DeviceId deviceId) {
95 checkNotNull(deviceId, DEVICE_ID_NULL);
96 return store.getRole(clusterService.getLocalNode().id(), deviceId);
97 }
98
99 @Override
100 public void relinquishMastership(DeviceId deviceId) {
Ayaka Koshibe971a38a2014-09-30 11:56:23 -0700101 MastershipRole role = getLocalRole(deviceId);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700102 if (!role.equals(MastershipRole.MASTER)) {
103 return;
104 }
105
106 MastershipEvent event = store.unsetMaster(
107 clusterService.getLocalNode().id(), deviceId);
108 if (event != null) {
109 post(event);
110 }
tomb41d1ac2014-09-24 01:51:24 -0700111 }
112
113 @Override
114 public MastershipRole requestRoleFor(DeviceId deviceId) {
115 checkNotNull(deviceId, DEVICE_ID_NULL);
116 return store.requestRole(deviceId);
117 }
118
119 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700120 public NodeId getMasterFor(DeviceId deviceId) {
121 checkNotNull(deviceId, DEVICE_ID_NULL);
122 return store.getMaster(deviceId);
123 }
124
125 @Override
126 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
127 checkNotNull(nodeId, NODE_ID_NULL);
128 return store.getDevices(nodeId);
129 }
130
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700131
132 @Override
133 public MastershipTermService requestTermService() {
134 return new InternalMastershipTermService();
135 }
136
Ayaka Koshibe16609692014-09-23 12:46:15 -0700137 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700138 public void addListener(MastershipListener listener) {
139 checkNotNull(listener);
140 listenerRegistry.addListener(listener);
141 }
142
143 @Override
144 public void removeListener(MastershipListener listener) {
145 checkNotNull(listener);
146 listenerRegistry.removeListener(listener);
147 }
148
tomb41d1ac2014-09-24 01:51:24 -0700149 // FIXME: provide wiring to allow events to be triggered by changes within the store
Ayaka Koshibe16609692014-09-23 12:46:15 -0700150
151 // Posts the specified event to the local event dispatcher.
152 private void post(MastershipEvent event) {
153 if (event != null && eventDispatcher != null) {
154 eventDispatcher.post(event);
155 }
156 }
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -0700157
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700158 private class InternalMastershipTermService implements MastershipTermService {
159
160 @Override
161 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
162 return store.getTermFor(deviceId);
163 }
164
165 }
166
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700167 //callback for reacting to cluster events
168 private class InternalClusterEventListener implements ClusterEventListener {
169
170 @Override
171 public void event(ClusterEvent event) {
172 switch (event.type()) {
173 //FIXME: worry about addition when the time comes
174 case INSTANCE_ADDED:
175 case INSTANCE_ACTIVATED:
176 break;
177 case INSTANCE_REMOVED:
178 case INSTANCE_DEACTIVATED:
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700179 break;
180 default:
181 log.warn("unknown cluster event {}", event);
182 }
183 }
184
185 }
Ayaka Koshibe65efaef2014-09-29 18:21:56 -0700186
alshabib339a3d92014-09-26 17:54:32 -0700187 public class InternalDelegate implements MastershipStoreDelegate {
188
189 @Override
190 public void notify(MastershipEvent event) {
191 log.info("dispatching mastership event {}", event);
192 eventDispatcher.post(event);
193 }
194
195 }
196
Ayaka Koshibe16609692014-09-23 12:46:15 -0700197}