blob: 92b345cfd9dcf6f704ec434610b301f4d23eacf3 [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 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
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 Koshibec4047702014-10-07 14:43:52 -0700101 MastershipEvent event = null;
102 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
111 public MastershipRole requestRoleFor(DeviceId deviceId) {
112 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
130 public MastershipTermService requestTermService() {
131 return new InternalMastershipTermService();
132 }
133
Ayaka Koshibe16609692014-09-23 12:46:15 -0700134 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700135 public void addListener(MastershipListener listener) {
136 checkNotNull(listener);
137 listenerRegistry.addListener(listener);
138 }
139
140 @Override
141 public void removeListener(MastershipListener listener) {
142 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.
149 private void post(MastershipEvent event) {
150 if (event != null && eventDispatcher != null) {
151 eventDispatcher.post(event);
152 }
153 }
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -0700154
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700155 private class InternalMastershipTermService implements MastershipTermService {
156
157 @Override
158 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
159 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
alshabib339a3d92014-09-26 17:54:32 -0700184 public class InternalDelegate implements MastershipStoreDelegate {
185
186 @Override
187 public void notify(MastershipEvent event) {
188 log.info("dispatching mastership event {}", event);
189 eventDispatcher.post(event);
190 }
191
192 }
193
Ayaka Koshibe16609692014-09-23 12:46:15 -0700194}