blob: b54e468dfee515d0577e8fd3483eed7e1e717dfe [file] [log] [blame]
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.group.impl;
17
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070018import static org.slf4j.LoggerFactory.getLogger;
19
20import java.util.Collection;
21import java.util.Collections;
22
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
28import org.apache.felix.scr.annotations.Service;
29import org.onosproject.core.ApplicationId;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080030import org.onosproject.event.EventDeliveryService;
Simon Huntff663742015-05-14 13:33:05 -070031import org.onosproject.event.ListenerRegistry;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080032import org.onosproject.net.DeviceId;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080033import org.onosproject.net.device.DeviceEvent;
34import org.onosproject.net.device.DeviceListener;
35import org.onosproject.net.device.DeviceService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080036import org.onosproject.net.group.Group;
37import org.onosproject.net.group.GroupBuckets;
38import org.onosproject.net.group.GroupDescription;
39import org.onosproject.net.group.GroupEvent;
40import org.onosproject.net.group.GroupKey;
41import org.onosproject.net.group.GroupListener;
42import org.onosproject.net.group.GroupOperation;
43import org.onosproject.net.group.GroupOperations;
44import org.onosproject.net.group.GroupProvider;
45import org.onosproject.net.group.GroupProviderRegistry;
46import org.onosproject.net.group.GroupProviderService;
47import org.onosproject.net.group.GroupService;
48import org.onosproject.net.group.GroupStore;
49import org.onosproject.net.group.GroupStore.UpdateType;
50import org.onosproject.net.group.GroupStoreDelegate;
51import org.onosproject.net.provider.AbstractProviderRegistry;
52import org.onosproject.net.provider.AbstractProviderService;
53import org.slf4j.Logger;
54
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080055/**
56 * Provides implementation of the group service APIs.
57 */
58@Component(immediate = true)
59@Service
60public class GroupManager
61 extends AbstractProviderRegistry<GroupProvider, GroupProviderService>
62 implements GroupService, GroupProviderRegistry {
63
64 private final Logger log = getLogger(getClass());
65
Simon Huntff663742015-05-14 13:33:05 -070066 private final ListenerRegistry<GroupEvent, GroupListener>
67 listenerRegistry = new ListenerRegistry<>();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080068 private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080069 private final DeviceListener deviceListener = new InternalDeviceListener();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080070
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected GroupStore store;
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080075 protected DeviceService deviceService;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080078 protected EventDeliveryService eventDispatcher;
79
80 @Activate
81 public void activate() {
82 store.setDelegate(delegate);
83 eventDispatcher.addSink(GroupEvent.class, listenerRegistry);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080084 deviceService.addListener(deviceListener);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080085 log.info("Started");
86 }
87
88 @Deactivate
89 public void deactivate() {
90 store.unsetDelegate(delegate);
91 eventDispatcher.removeSink(GroupEvent.class);
92 log.info("Stopped");
93 }
94
95 /**
96 * Create a group in the specified device with the provided parameters.
97 *
98 * @param groupDesc group creation parameters
99 *
100 */
101 @Override
102 public void addGroup(GroupDescription groupDesc) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700103 log.trace("In addGroup API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800104 store.storeGroupDescription(groupDesc);
105 }
106
107 /**
108 * Return a group object associated to an application cookie.
109 *
110 * NOTE1: The presence of group object in the system does not
111 * guarantee that the "group" is actually created in device.
112 * GROUP_ADDED notification would confirm the creation of
113 * this group in data plane.
114 *
115 * @param deviceId device identifier
116 * @param appCookie application cookie to be used for lookup
117 * @return group associated with the application cookie or
118 * NULL if Group is not found for the provided cookie
119 */
120 @Override
121 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700122 log.trace("In getGroup API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800123 return store.getGroup(deviceId, appCookie);
124 }
125
126 /**
127 * Append buckets to existing group. The caller can optionally
128 * associate a new cookie during this updation. GROUP_UPDATED or
129 * GROUP_UPDATE_FAILED notifications would be provided along with
130 * cookie depending on the result of the operation on the device.
131 *
132 * @param deviceId device identifier
133 * @param oldCookie cookie to be used to retrieve the existing group
134 * @param buckets immutable list of group bucket to be added
135 * @param newCookie immutable cookie to be used post update operation
136 * @param appId Application Id
137 */
138 @Override
139 public void addBucketsToGroup(DeviceId deviceId,
140 GroupKey oldCookie,
141 GroupBuckets buckets,
142 GroupKey newCookie,
143 ApplicationId appId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700144 log.trace("In addBucketsToGroup API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800145 store.updateGroupDescription(deviceId,
146 oldCookie,
147 UpdateType.ADD,
148 buckets,
149 newCookie);
150 }
151
152 /**
153 * Remove buckets from existing group. The caller can optionally
154 * associate a new cookie during this updation. GROUP_UPDATED or
155 * GROUP_UPDATE_FAILED notifications would be provided along with
156 * cookie depending on the result of the operation on the device.
157 *
158 * @param deviceId device identifier
159 * @param oldCookie cookie to be used to retrieve the existing group
160 * @param buckets immutable list of group bucket to be removed
161 * @param newCookie immutable cookie to be used post update operation
162 * @param appId Application Id
163 */
164 @Override
165 public void removeBucketsFromGroup(DeviceId deviceId,
166 GroupKey oldCookie,
167 GroupBuckets buckets,
168 GroupKey newCookie,
169 ApplicationId appId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700170 log.trace("In removeBucketsFromGroup API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800171 store.updateGroupDescription(deviceId,
172 oldCookie,
173 UpdateType.REMOVE,
174 buckets,
175 newCookie);
176 }
177
178 /**
179 * Delete a group associated to an application cookie.
180 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
181 * provided along with cookie depending on the result of the
182 * operation on the device.
183 *
184 * @param deviceId device identifier
185 * @param appCookie application cookie to be used for lookup
186 * @param appId Application Id
187 */
188 @Override
189 public void removeGroup(DeviceId deviceId,
190 GroupKey appCookie,
191 ApplicationId appId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700192 log.trace("In removeGroup API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800193 store.deleteGroupDescription(deviceId, appCookie);
194 }
195
196 /**
197 * Retrieve all groups created by an application in the specified device
198 * as seen by current controller instance.
199 *
200 * @param deviceId device identifier
201 * @param appId application id
202 * @return collection of immutable group objects created by the application
203 */
204 @Override
205 public Iterable<Group> getGroups(DeviceId deviceId,
206 ApplicationId appId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700207 log.trace("In getGroups API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800208 return store.getGroups(deviceId);
209 }
210
Jonathan Hart32600692015-03-09 10:38:40 -0700211 @Override
212 public Iterable<Group> getGroups(DeviceId deviceId) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700213 log.trace("In getGroups API");
Jonathan Hart32600692015-03-09 10:38:40 -0700214 return store.getGroups(deviceId);
215 }
216
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800217 /**
218 * Adds the specified group listener.
219 *
220 * @param listener group listener
221 */
222 @Override
223 public void addListener(GroupListener listener) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700224 log.trace("In addListener API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800225 listenerRegistry.addListener(listener);
226 }
227
228 /**
229 * Removes the specified group listener.
230 *
231 * @param listener group listener
232 */
233 @Override
234 public void removeListener(GroupListener listener) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700235 log.trace("In removeListener API");
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800236 listenerRegistry.removeListener(listener);
237 }
238
239 @Override
240 protected GroupProviderService createProviderService(GroupProvider provider) {
241 return new InternalGroupProviderService(provider);
242 }
243
244 private class InternalGroupStoreDelegate implements GroupStoreDelegate {
245 @Override
246 public void notify(GroupEvent event) {
247 final Group group = event.subject();
248 GroupProvider groupProvider =
249 getProvider(group.deviceId());
250 GroupOperations groupOps = null;
251 switch (event.type()) {
252 case GROUP_ADD_REQUESTED:
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800253 log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
254 group.id(), group.deviceId());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800255 GroupOperation groupAddOp = GroupOperation.
256 createAddGroupOperation(group.id(),
257 group.type(),
258 group.buckets());
259 groupOps = new GroupOperations(
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700260 Collections.singletonList(groupAddOp));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800261 groupProvider.performGroupOperation(group.deviceId(), groupOps);
262 break;
263
264 case GROUP_UPDATE_REQUESTED:
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800265 log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
266 group.id(), group.deviceId());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800267 GroupOperation groupModifyOp = GroupOperation.
268 createModifyGroupOperation(group.id(),
269 group.type(),
270 group.buckets());
271 groupOps = new GroupOperations(
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700272 Collections.singletonList(groupModifyOp));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800273 groupProvider.performGroupOperation(group.deviceId(), groupOps);
274 break;
275
276 case GROUP_REMOVE_REQUESTED:
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800277 log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
278 group.id(), group.deviceId());
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800279 GroupOperation groupDeleteOp = GroupOperation.
280 createDeleteGroupOperation(group.id(),
281 group.type());
282 groupOps = new GroupOperations(
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700283 Collections.singletonList(groupDeleteOp));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800284 groupProvider.performGroupOperation(group.deviceId(), groupOps);
285 break;
286
287 case GROUP_ADDED:
288 case GROUP_UPDATED:
289 case GROUP_REMOVED:
sangho7ff01812015-02-09 16:21:53 -0800290 case GROUP_ADD_FAILED:
291 case GROUP_UPDATE_FAILED:
292 case GROUP_REMOVE_FAILED:
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800293 eventDispatcher.post(event);
294 break;
295
296 default:
297 break;
298 }
299 }
300 }
301
302 private class InternalGroupProviderService
303 extends AbstractProviderService<GroupProvider>
304 implements GroupProviderService {
305
306 protected InternalGroupProviderService(GroupProvider provider) {
307 super(provider);
308 }
309
310 @Override
sangho7ff01812015-02-09 16:21:53 -0800311 public void groupOperationFailed(DeviceId deviceId,
312 GroupOperation operation) {
313 store.groupOperationFailed(deviceId, operation);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800314 }
315
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800316 @Override
317 public void pushGroupMetrics(DeviceId deviceId,
318 Collection<Group> groupEntries) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800319 log.trace("Received group metrics from device {}",
320 deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700321 checkValidity();
322 store.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800323 }
324 }
325
326 private class InternalDeviceListener implements DeviceListener {
327
328 @Override
329 public void event(DeviceEvent event) {
330 switch (event.type()) {
331 case DEVICE_REMOVED:
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700332 case DEVICE_AVAILABILITY_CHANGED:
333 if (!deviceService.isAvailable(event.subject().id())) {
334 log.debug("GroupService DeviceListener: Received event {}."
335 + "Device is no more available."
336 + "Clearing device {} initial "
337 + "AUDIT completed status",
338 event.type(),
339 event.subject().id());
340 store.deviceInitialAuditCompleted(event.subject().id(), false);
341 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800342 break;
343
344 default:
345 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800346 }
347 }
348 }
349}