blob: 8dd337997ac694d624d613e0841ccc3ce093eaff [file] [log] [blame]
Ayaka Koshibe16609692014-09-23 12:46:15 -07001package org.onlab.onos.cluster.impl;
2
Ayaka Koshibe16609692014-09-23 12:46:15 -07003import org.apache.felix.scr.annotations.Activate;
tom4a5d1712014-09-23 17:49:39 -07004import org.apache.felix.scr.annotations.Component;
Ayaka Koshibe16609692014-09-23 12:46:15 -07005import org.apache.felix.scr.annotations.Deactivate;
6import org.apache.felix.scr.annotations.Reference;
7import org.apache.felix.scr.annotations.ReferenceCardinality;
tom4a5d1712014-09-23 17:49:39 -07008import org.apache.felix.scr.annotations.Service;
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -07009import org.onlab.onos.cluster.ClusterEvent;
10import org.onlab.onos.cluster.ClusterEventListener;
tom4a5d1712014-09-23 17:49:39 -070011import org.onlab.onos.cluster.ClusterService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070012import org.onlab.onos.cluster.MastershipAdminService;
13import org.onlab.onos.cluster.MastershipEvent;
14import org.onlab.onos.cluster.MastershipListener;
Ayaka Koshibe16609692014-09-23 12:46:15 -070015import org.onlab.onos.cluster.MastershipService;
16import org.onlab.onos.cluster.MastershipStore;
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -070017import org.onlab.onos.cluster.MastershipTerm;
18import org.onlab.onos.cluster.MastershipTermService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070019import org.onlab.onos.cluster.NodeId;
20import org.onlab.onos.event.AbstractListenerRegistry;
21import org.onlab.onos.event.EventDeliveryService;
22import org.onlab.onos.net.DeviceId;
23import org.onlab.onos.net.MastershipRole;
Ayaka Koshibe16609692014-09-23 12:46:15 -070024import org.slf4j.Logger;
25
tomb41d1ac2014-09-24 01:51:24 -070026import java.util.Set;
27
Ayaka Koshibe16609692014-09-23 12:46:15 -070028import static com.google.common.base.Preconditions.checkNotNull;
tomb41d1ac2014-09-24 01:51:24 -070029import static org.slf4j.LoggerFactory.getLogger;
Ayaka Koshibe16609692014-09-23 12:46:15 -070030
tom4a5d1712014-09-23 17:49:39 -070031@Component(immediate = true)
32@Service
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -070033public class MastershipManager
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -070034 implements MastershipService, MastershipAdminService {
Ayaka Koshibe16609692014-09-23 12:46:15 -070035
36 private static final String NODE_ID_NULL = "Node ID cannot be null";
37 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
38 private static final String ROLE_NULL = "Mastership role cannot be null";
39
40 private final Logger log = getLogger(getClass());
41
42 protected final AbstractListenerRegistry<MastershipEvent, MastershipListener>
43 listenerRegistry = new AbstractListenerRegistry<>();
44
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 protected MastershipStore store;
47
48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 protected EventDeliveryService eventDispatcher;
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom4a5d1712014-09-23 17:49:39 -070052 protected ClusterService clusterService;
Ayaka Koshibe16609692014-09-23 12:46:15 -070053
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070054 private ClusterEventListener clusterListener = new InternalClusterEventListener();
55
Ayaka Koshibe16609692014-09-23 12:46:15 -070056 @Activate
57 public void activate() {
58 eventDispatcher.addSink(MastershipEvent.class, listenerRegistry);
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070059 clusterService.addListener(clusterListener);
Ayaka Koshibe16609692014-09-23 12:46:15 -070060 log.info("Started");
61 }
62
63 @Deactivate
64 public void deactivate() {
65 eventDispatcher.removeSink(MastershipEvent.class);
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -070066 clusterService.removeListener(clusterListener);
Ayaka Koshibe16609692014-09-23 12:46:15 -070067 log.info("Stopped");
68 }
69
Ayaka Koshibe16609692014-09-23 12:46:15 -070070 @Override
71 public void setRole(NodeId nodeId, DeviceId deviceId, MastershipRole role) {
72 checkNotNull(nodeId, NODE_ID_NULL);
73 checkNotNull(deviceId, DEVICE_ID_NULL);
74 checkNotNull(role, ROLE_NULL);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -070075
76 MastershipRole current = store.getRole(nodeId, deviceId);
77 if (role.equals(current)) {
78 return;
79 } else {
80 MastershipEvent event = null;
81 if (role.equals(MastershipRole.MASTER)) {
82 //current was STANDBY, wanted MASTER
83 event = store.setMaster(nodeId, deviceId);
84 } else {
85 //current was MASTER, wanted STANDBY
86 event = store.unsetMaster(nodeId, deviceId);
87 }
88
Ayaka Koshibe406d0102014-09-24 16:08:12 -070089 if (event != null) {
90 post(event);
91 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070092 }
Ayaka Koshibe16609692014-09-23 12:46:15 -070093 }
94
95 @Override
tomb41d1ac2014-09-24 01:51:24 -070096 public MastershipRole getLocalRole(DeviceId deviceId) {
97 checkNotNull(deviceId, DEVICE_ID_NULL);
98 return store.getRole(clusterService.getLocalNode().id(), deviceId);
99 }
100
101 @Override
102 public void relinquishMastership(DeviceId deviceId) {
103 checkNotNull(deviceId, DEVICE_ID_NULL);
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700104
105 MastershipRole role = store.getRole(
106 clusterService.getLocalNode().id(), deviceId);
107 if (!role.equals(MastershipRole.MASTER)) {
108 return;
109 }
110
111 MastershipEvent event = store.unsetMaster(
112 clusterService.getLocalNode().id(), deviceId);
113 if (event != null) {
114 post(event);
115 }
tomb41d1ac2014-09-24 01:51:24 -0700116 }
117
118 @Override
119 public MastershipRole requestRoleFor(DeviceId deviceId) {
120 checkNotNull(deviceId, DEVICE_ID_NULL);
121 return store.requestRole(deviceId);
122 }
123
124 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700125 public NodeId getMasterFor(DeviceId deviceId) {
126 checkNotNull(deviceId, DEVICE_ID_NULL);
127 return store.getMaster(deviceId);
128 }
129
130 @Override
131 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
132 checkNotNull(nodeId, NODE_ID_NULL);
133 return store.getDevices(nodeId);
134 }
135
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700136
137 @Override
138 public MastershipTermService requestTermService() {
139 return new InternalMastershipTermService();
140 }
141
Ayaka Koshibe16609692014-09-23 12:46:15 -0700142 @Override
Ayaka Koshibe16609692014-09-23 12:46:15 -0700143 public void addListener(MastershipListener listener) {
144 checkNotNull(listener);
145 listenerRegistry.addListener(listener);
146 }
147
148 @Override
149 public void removeListener(MastershipListener listener) {
150 checkNotNull(listener);
151 listenerRegistry.removeListener(listener);
152 }
153
tomb41d1ac2014-09-24 01:51:24 -0700154 // FIXME: provide wiring to allow events to be triggered by changes within the store
Ayaka Koshibe16609692014-09-23 12:46:15 -0700155
156 // Posts the specified event to the local event dispatcher.
157 private void post(MastershipEvent event) {
158 if (event != null && eventDispatcher != null) {
159 eventDispatcher.post(event);
160 }
161 }
Ayaka Koshibe3eed2b02014-09-23 13:28:05 -0700162
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700163 private class InternalMastershipTermService implements MastershipTermService {
164
165 @Override
166 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
167 return store.getTermFor(deviceId);
168 }
169
170 }
171
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700172 //callback for reacting to cluster events
173 private class InternalClusterEventListener implements ClusterEventListener {
174
175 @Override
176 public void event(ClusterEvent event) {
177 switch (event.type()) {
178 //FIXME: worry about addition when the time comes
179 case INSTANCE_ADDED:
180 case INSTANCE_ACTIVATED:
181 break;
182 case INSTANCE_REMOVED:
183 case INSTANCE_DEACTIVATED:
Ayaka Koshibe3de43ca2014-09-26 16:40:23 -0700184 break;
185 default:
186 log.warn("unknown cluster event {}", event);
187 }
188 }
189
190 }
Ayaka Koshibe16609692014-09-23 12:46:15 -0700191}