blob: 65ec5d31b62587f16bd880f409c11d18ebbce21a [file] [log] [blame]
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -08003 *
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
Carmelo Casconebc7eb852019-04-17 23:10:51 -070018import com.google.common.collect.Iterables;
Jian Lid9b5f552016-03-11 18:15:31 -080019import org.onlab.util.Tools;
Charles Chan0c7c43b2016-01-14 17:39:20 -080020import org.onosproject.cfg.ComponentConfigService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080021import org.onosproject.core.ApplicationId;
Andrea Campanella1ea15102017-09-04 16:00:09 +020022import org.onosproject.mastership.MastershipService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080023import org.onosproject.net.DeviceId;
Andrea Campanella32a9c0b2020-03-27 12:53:46 +010024import org.onosproject.net.config.NetworkConfigRegistry;
25import org.onosproject.net.config.basics.BasicDeviceConfig;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080026import org.onosproject.net.device.DeviceEvent;
27import org.onosproject.net.device.DeviceListener;
28import org.onosproject.net.device.DeviceService;
Jordan Halterman59afc6a2017-10-30 16:12:42 -070029import org.onosproject.net.driver.DriverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080030import org.onosproject.net.group.Group;
31import org.onosproject.net.group.GroupBuckets;
32import org.onosproject.net.group.GroupDescription;
33import org.onosproject.net.group.GroupEvent;
34import org.onosproject.net.group.GroupKey;
35import org.onosproject.net.group.GroupListener;
36import org.onosproject.net.group.GroupOperation;
37import org.onosproject.net.group.GroupOperations;
38import org.onosproject.net.group.GroupProvider;
39import org.onosproject.net.group.GroupProviderRegistry;
40import org.onosproject.net.group.GroupProviderService;
41import org.onosproject.net.group.GroupService;
42import org.onosproject.net.group.GroupStore;
43import org.onosproject.net.group.GroupStore.UpdateType;
44import org.onosproject.net.group.GroupStoreDelegate;
Jian Lid9b5f552016-03-11 18:15:31 -080045import org.onosproject.net.provider.AbstractListenerProviderRegistry;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080046import org.onosproject.net.provider.AbstractProviderService;
Charles Chan0c7c43b2016-01-14 17:39:20 -080047import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070048import org.osgi.service.component.annotations.Activate;
49import org.osgi.service.component.annotations.Component;
50import org.osgi.service.component.annotations.Deactivate;
51import org.osgi.service.component.annotations.Modified;
52import org.osgi.service.component.annotations.Reference;
53import org.osgi.service.component.annotations.ReferenceCardinality;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080054import org.slf4j.Logger;
55
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070056import java.util.Collection;
57import java.util.Collections;
Charles Chan0c7c43b2016-01-14 17:39:20 -080058import java.util.Dictionary;
Carmelo Casconebc7eb852019-04-17 23:10:51 -070059import java.util.Objects;
Charles Chan07f15f22018-05-08 21:35:50 -070060import java.util.concurrent.ExecutorService;
61import java.util.concurrent.Executors;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070062
Andrea Campanella1ea15102017-09-04 16:00:09 +020063import static com.google.common.base.Strings.isNullOrEmpty;
64import static org.onlab.util.Tools.get;
Charles Chan07f15f22018-05-08 21:35:50 -070065import static org.onlab.util.Tools.groupedThreads;
Carmelo Casconebc7eb852019-04-17 23:10:51 -070066import static org.onosproject.net.OsgiPropertyConstants.GM_POLL_FREQUENCY;
67import static org.onosproject.net.OsgiPropertyConstants.GM_POLL_FREQUENCY_DEFAULT;
68import static org.onosproject.net.OsgiPropertyConstants.GM_PURGE_ON_DISCONNECTION;
69import static org.onosproject.net.OsgiPropertyConstants.GM_PURGE_ON_DISCONNECTION_DEFAULT;
Changhoon Yoon541ef712015-05-23 17:18:34 +090070import static org.onosproject.security.AppGuard.checkPermission;
Jian Lid9b5f552016-03-11 18:15:31 -080071import static org.onosproject.security.AppPermission.Type.GROUP_READ;
72import static org.onosproject.security.AppPermission.Type.GROUP_WRITE;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070073import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoonb856b812015-08-10 03:47:19 +090074
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080075/**
76 * Provides implementation of the group service APIs.
77 */
Ray Milkeyd04e2272018-10-16 18:20:18 -070078@Component(
79 immediate = true,
80 service = {
81 GroupService.class,
82 GroupProviderRegistry.class
83 },
84 property = {
Ray Milkey2d7bca12018-10-17 14:51:52 -070085 GM_POLL_FREQUENCY + ":Integer=" + GM_POLL_FREQUENCY_DEFAULT,
86 GM_PURGE_ON_DISCONNECTION + ":Boolean=" + GM_PURGE_ON_DISCONNECTION_DEFAULT
Ray Milkeyd04e2272018-10-16 18:20:18 -070087 }
88)
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080089public class GroupManager
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070090 extends AbstractListenerProviderRegistry<GroupEvent, GroupListener,
91 GroupProvider, GroupProviderService>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080092 implements GroupService, GroupProviderRegistry {
93
94 private final Logger log = getLogger(getClass());
95
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080096 private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080097 private final DeviceListener deviceListener = new InternalDeviceListener();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080098
Charles Chan07f15f22018-05-08 21:35:50 -070099 private final GroupDriverProvider defaultProvider = new GroupDriverProvider();
100
101 private ExecutorService eventExecutor;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200102
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700103 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800104 protected GroupStore store;
105
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700106 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800107 protected DeviceService deviceService;
108
Jordan Halterman59afc6a2017-10-30 16:12:42 -0700109 // Reference the DriverService to ensure the service is bound prior to initialization of the GroupDriverProvider
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jordan Halterman59afc6a2017-10-30 16:12:42 -0700111 protected DriverService driverService;
112
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700113 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Charles Chan0c7c43b2016-01-14 17:39:20 -0800114 protected ComponentConfigService cfgService;
115
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700116 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Andrea Campanella1ea15102017-09-04 16:00:09 +0200117 protected MastershipService mastershipService;
118
Andrea Campanella32a9c0b2020-03-27 12:53:46 +0100119 @Reference(cardinality = ReferenceCardinality.MANDATORY)
120 protected NetworkConfigRegistry netCfgService;
121
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700122 /** Frequency (in seconds) for polling groups via fallback provider. */
Ray Milkeyd04e2272018-10-16 18:20:18 -0700123 private int fallbackGroupPollFrequency = GM_POLL_FREQUENCY_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200124
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700125 /** Purge entries associated with a device when the device goes offline. */
Ray Milkeyd04e2272018-10-16 18:20:18 -0700126 private boolean purgeOnDisconnection = GM_PURGE_ON_DISCONNECTION_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200127
Charles Chan0c7c43b2016-01-14 17:39:20 -0800128
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800129 @Activate
Charles Chan0c7c43b2016-01-14 17:39:20 -0800130 public void activate(ComponentContext context) {
Charles Chan07f15f22018-05-08 21:35:50 -0700131 eventExecutor = Executors.newSingleThreadExecutor(groupedThreads("onos/group", "event"));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800132 store.setDelegate(delegate);
133 eventDispatcher.addSink(GroupEvent.class, listenerRegistry);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800134 deviceService.addListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800135 cfgService.registerProperties(getClass());
136 modified(context);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800137 log.info("Started");
138 }
139
140 @Deactivate
141 public void deactivate() {
Charles Chan07f15f22018-05-08 21:35:50 -0700142 eventExecutor.shutdown();
Andrea Campanella5a3c09c2017-12-01 13:57:48 +0100143 defaultProvider.terminate();
Andrea Campanella3f1c61e2016-04-01 17:30:12 -0700144 deviceService.removeListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800145 cfgService.unregisterProperties(getClass(), false);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800146 store.unsetDelegate(delegate);
147 eventDispatcher.removeSink(GroupEvent.class);
148 log.info("Stopped");
149 }
150
Charles Chan0c7c43b2016-01-14 17:39:20 -0800151 @Modified
152 public void modified(ComponentContext context) {
153 if (context != null) {
154 readComponentConfiguration(context);
155 }
Andrea Campanella1ea15102017-09-04 16:00:09 +0200156 defaultProvider.init(deviceService, new InternalGroupProviderService(defaultProvider),
157 mastershipService, fallbackGroupPollFrequency);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800158 }
159
160 @Override
161 protected GroupProvider defaultProvider() {
162 return defaultProvider;
Charles Chan0c7c43b2016-01-14 17:39:20 -0800163 }
164
165 /**
166 * Extracts properties from the component configuration context.
167 *
168 * @param context the component context
169 */
170 private void readComponentConfiguration(ComponentContext context) {
171 Dictionary<?, ?> properties = context.getProperties();
172 Boolean flag;
173
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700174 flag = Tools.isPropertyEnabled(properties, GM_PURGE_ON_DISCONNECTION);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800175 if (flag == null) {
176 log.info("PurgeOnDisconnection is not configured, " +
Andrea Campanella32a9c0b2020-03-27 12:53:46 +0100177 "using current value of {}", purgeOnDisconnection);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800178 } else {
179 purgeOnDisconnection = flag;
180 log.info("Configured. PurgeOnDisconnection is {}",
Andrea Campanella32a9c0b2020-03-27 12:53:46 +0100181 purgeOnDisconnection ? "enabled" : "disabled");
Charles Chan0c7c43b2016-01-14 17:39:20 -0800182 }
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700183 String s = get(properties, GM_POLL_FREQUENCY);
Andrea Campanella1ea15102017-09-04 16:00:09 +0200184 try {
Ray Milkeyd04e2272018-10-16 18:20:18 -0700185 fallbackGroupPollFrequency = isNullOrEmpty(s) ? GM_POLL_FREQUENCY_DEFAULT : Integer.parseInt(s);
Andrea Campanella1ea15102017-09-04 16:00:09 +0200186 } catch (NumberFormatException e) {
Ray Milkeyd04e2272018-10-16 18:20:18 -0700187 fallbackGroupPollFrequency = GM_POLL_FREQUENCY_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200188 }
Charles Chan0c7c43b2016-01-14 17:39:20 -0800189 }
190
191 /**
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800192 * Create a group in the specified device with the provided parameters.
193 *
194 * @param groupDesc group creation parameters
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800195 */
196 @Override
197 public void addGroup(GroupDescription groupDesc) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900198 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800199 store.storeGroupDescription(groupDesc);
200 }
201
202 /**
203 * Return a group object associated to an application cookie.
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700204 * <p>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800205 * NOTE1: The presence of group object in the system does not
206 * guarantee that the "group" is actually created in device.
207 * GROUP_ADDED notification would confirm the creation of
208 * this group in data plane.
209 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700210 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800211 * @param appCookie application cookie to be used for lookup
212 * @return group associated with the application cookie or
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700213 * NULL if Group is not found for the provided cookie
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800214 */
215 @Override
216 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900217 checkPermission(GROUP_READ);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800218 return store.getGroup(deviceId, appCookie);
219 }
220
221 /**
222 * Append buckets to existing group. The caller can optionally
223 * associate a new cookie during this updation. GROUP_UPDATED or
224 * GROUP_UPDATE_FAILED notifications would be provided along with
225 * cookie depending on the result of the operation on the device.
226 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700227 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800228 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700229 * @param buckets immutable list of group bucket to be added
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800230 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700231 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800232 */
233 @Override
234 public void addBucketsToGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700235 GroupKey oldCookie,
236 GroupBuckets buckets,
237 GroupKey newCookie,
238 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900239 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800240 store.updateGroupDescription(deviceId,
241 oldCookie,
242 UpdateType.ADD,
243 buckets,
244 newCookie);
245 }
246
247 /**
248 * Remove buckets from existing group. The caller can optionally
249 * associate a new cookie during this updation. GROUP_UPDATED or
250 * GROUP_UPDATE_FAILED notifications would be provided along with
251 * cookie depending on the result of the operation on the device.
252 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700253 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800254 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700255 * @param buckets immutable list of group bucket to be removed
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800256 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700257 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800258 */
259 @Override
260 public void removeBucketsFromGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700261 GroupKey oldCookie,
262 GroupBuckets buckets,
263 GroupKey newCookie,
264 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900265 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800266 store.updateGroupDescription(deviceId,
267 oldCookie,
268 UpdateType.REMOVE,
269 buckets,
270 newCookie);
271 }
272
Victor Silva0282ab82016-11-15 16:30:27 -0300273 /**
274 * Set buckets for an existing group. The caller can optionally
275 * associate a new cookie during this updation. GROUP_UPDATED or
276 * GROUP_UPDATE_FAILED notifications would be provided along with
277 * cookie depending on the result of the operation on the device.
278 *
279 * This operation overwrites the previous group buckets entirely.
280 *
281 * @param deviceId device identifier
282 * @param oldCookie cookie to be used to retrieve the existing group
283 * @param buckets immutable list of group buckets to be set
284 * @param newCookie immutable cookie to be used post update operation
285 * @param appId Application Id
286 */
287 @Override
288 public void setBucketsForGroup(DeviceId deviceId,
289 GroupKey oldCookie,
290 GroupBuckets buckets,
291 GroupKey newCookie,
292 ApplicationId appId) {
293 checkPermission(GROUP_WRITE);
294 store.updateGroupDescription(deviceId,
295 oldCookie,
296 UpdateType.SET,
297 buckets,
298 newCookie);
299 }
300
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530301 @Override
302 public void purgeGroupEntries(DeviceId deviceId) {
303 checkPermission(GROUP_WRITE);
304 store.purgeGroupEntry(deviceId);
305 }
306
Victor Silva4e8b7832016-08-17 17:11:19 -0300307 @Override
Daniele Moro43ac2892021-07-15 17:02:59 +0200308 public void purgeGroupEntries(DeviceId deviceId, ApplicationId appId) {
309 checkPermission(GROUP_WRITE);
310 store.purgeGroupEntries(deviceId, appId);
311 }
312
313 @Override
Victor Silva4e8b7832016-08-17 17:11:19 -0300314 public void purgeGroupEntries() {
315 checkPermission(GROUP_WRITE);
316 store.purgeGroupEntries();
317 }
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530318
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800319 /**
320 * Delete a group associated to an application cookie.
321 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
322 * provided along with cookie depending on the result of the
323 * operation on the device.
324 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700325 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800326 * @param appCookie application cookie to be used for lookup
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700327 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800328 */
329 @Override
330 public void removeGroup(DeviceId deviceId,
331 GroupKey appCookie,
332 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900333 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800334 store.deleteGroupDescription(deviceId, appCookie);
335 }
336
337 /**
338 * Retrieve all groups created by an application in the specified device
339 * as seen by current controller instance.
340 *
341 * @param deviceId device identifier
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700342 * @param appId application id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800343 * @return collection of immutable group objects created by the application
344 */
345 @Override
346 public Iterable<Group> getGroups(DeviceId deviceId,
347 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900348 checkPermission(GROUP_READ);
Carmelo Casconebc7eb852019-04-17 23:10:51 -0700349 return Iterables.filter(
350 store.getGroups(deviceId),
351 g -> g != null && Objects.equals(g.appId(), appId));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800352 }
353
Jonathan Hart32600692015-03-09 10:38:40 -0700354 @Override
355 public Iterable<Group> getGroups(DeviceId deviceId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900356 checkPermission(GROUP_READ);
Jonathan Hart32600692015-03-09 10:38:40 -0700357 return store.getGroups(deviceId);
358 }
359
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800360 @Override
361 protected GroupProviderService createProviderService(GroupProvider provider) {
362 return new InternalGroupProviderService(provider);
363 }
364
365 private class InternalGroupStoreDelegate implements GroupStoreDelegate {
366 @Override
367 public void notify(GroupEvent event) {
368 final Group group = event.subject();
369 GroupProvider groupProvider =
370 getProvider(group.deviceId());
371 GroupOperations groupOps = null;
372 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700373 case GROUP_ADD_REQUESTED:
374 log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
375 group.id(), group.deviceId());
376 GroupOperation groupAddOp = GroupOperation.
377 createAddGroupOperation(group.id(),
378 group.type(),
379 group.buckets());
380 groupOps = new GroupOperations(
381 Collections.singletonList(groupAddOp));
382 groupProvider.performGroupOperation(group.deviceId(), groupOps);
383 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800384
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700385 case GROUP_UPDATE_REQUESTED:
386 log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
387 group.id(), group.deviceId());
388 GroupOperation groupModifyOp = GroupOperation.
389 createModifyGroupOperation(group.id(),
390 group.type(),
391 group.buckets());
392 groupOps = new GroupOperations(
393 Collections.singletonList(groupModifyOp));
394 groupProvider.performGroupOperation(group.deviceId(), groupOps);
395 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800396
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700397 case GROUP_REMOVE_REQUESTED:
398 log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
399 group.id(), group.deviceId());
400 GroupOperation groupDeleteOp = GroupOperation.
401 createDeleteGroupOperation(group.id(),
402 group.type());
403 groupOps = new GroupOperations(
404 Collections.singletonList(groupDeleteOp));
405 groupProvider.performGroupOperation(group.deviceId(), groupOps);
406 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800407
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700408 case GROUP_ADDED:
409 case GROUP_UPDATED:
410 case GROUP_REMOVED:
411 case GROUP_ADD_FAILED:
412 case GROUP_UPDATE_FAILED:
413 case GROUP_REMOVE_FAILED:
helenyrwu89470f12016-08-12 13:18:10 -0700414 case GROUP_BUCKET_FAILOVER:
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700415 post(event);
416 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700417 default:
418 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800419 }
420 }
421 }
422
423 private class InternalGroupProviderService
424 extends AbstractProviderService<GroupProvider>
425 implements GroupProviderService {
426
427 protected InternalGroupProviderService(GroupProvider provider) {
428 super(provider);
429 }
430
431 @Override
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700432 public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
sangho7ff01812015-02-09 16:21:53 -0800433 store.groupOperationFailed(deviceId, operation);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800434 }
435
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800436 @Override
437 public void pushGroupMetrics(DeviceId deviceId,
438 Collection<Group> groupEntries) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700439 log.trace("Received group metrics from device {}", deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700440 checkValidity();
441 store.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800442 }
helenyrwu89470f12016-08-12 13:18:10 -0700443
444 @Override
445 public void notifyOfFailovers(Collection<Group> failoverGroups) {
446 store.notifyOfFailovers(failoverGroups);
447 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800448 }
449
450 private class InternalDeviceListener implements DeviceListener {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800451 @Override
452 public void event(DeviceEvent event) {
Charles Chan07f15f22018-05-08 21:35:50 -0700453 eventExecutor.execute(() -> processEventInternal(event));
454 }
455
456 private void processEventInternal(DeviceEvent event) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800457 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700458 case DEVICE_REMOVED:
459 case DEVICE_AVAILABILITY_CHANGED:
Charles Chan0c7c43b2016-01-14 17:39:20 -0800460 DeviceId deviceId = event.subject().id();
461 if (!deviceService.isAvailable(deviceId)) {
Tian Jian9cb2e9e2018-10-23 16:32:51 +0800462 log.debug("Device {} became unavailable for {}; clearing initial audit status",
463 deviceId, event.type());
464 store.deviceInitialAuditCompleted(deviceId, false);
Andrea Campanella32a9c0b2020-03-27 12:53:46 +0100465 BasicDeviceConfig cfg = netCfgService.getConfig(deviceId, BasicDeviceConfig.class);
466 //if purgeOnDisconnection is set for the device or it's a global configuration
467 // lets remove the groups.
468 boolean purge = cfg != null && cfg.isPurgeOnDisconnectionConfigured() ?
469 cfg.purgeOnDisconnection() : purgeOnDisconnection;
470 if (purge) {
471 log.info("PurgeOnDisconnection is requested for device {}, " +
472 "removing groups", deviceId);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800473 store.purgeGroupEntry(deviceId);
474 }
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700475 }
476 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700477 default:
478 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800479 }
480 }
481 }
helenyrwu89470f12016-08-12 13:18:10 -0700482
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800483}