blob: 88535858b47580ddd1b421103d0035f9174836c2 [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
Jian Lid9b5f552016-03-11 18:15:31 -080018import org.onlab.util.Tools;
Charles Chan0c7c43b2016-01-14 17:39:20 -080019import org.onosproject.cfg.ComponentConfigService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080020import org.onosproject.core.ApplicationId;
Andrea Campanella1ea15102017-09-04 16:00:09 +020021import org.onosproject.mastership.MastershipService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080022import org.onosproject.net.DeviceId;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080023import org.onosproject.net.device.DeviceEvent;
24import org.onosproject.net.device.DeviceListener;
25import org.onosproject.net.device.DeviceService;
Jordan Halterman59afc6a2017-10-30 16:12:42 -070026import org.onosproject.net.driver.DriverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080027import org.onosproject.net.group.Group;
28import org.onosproject.net.group.GroupBuckets;
29import org.onosproject.net.group.GroupDescription;
30import org.onosproject.net.group.GroupEvent;
31import org.onosproject.net.group.GroupKey;
32import org.onosproject.net.group.GroupListener;
33import org.onosproject.net.group.GroupOperation;
34import org.onosproject.net.group.GroupOperations;
35import org.onosproject.net.group.GroupProvider;
36import org.onosproject.net.group.GroupProviderRegistry;
37import org.onosproject.net.group.GroupProviderService;
38import org.onosproject.net.group.GroupService;
39import org.onosproject.net.group.GroupStore;
40import org.onosproject.net.group.GroupStore.UpdateType;
41import org.onosproject.net.group.GroupStoreDelegate;
Jian Lid9b5f552016-03-11 18:15:31 -080042import org.onosproject.net.provider.AbstractListenerProviderRegistry;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080043import org.onosproject.net.provider.AbstractProviderService;
Charles Chan0c7c43b2016-01-14 17:39:20 -080044import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070045import org.osgi.service.component.annotations.Activate;
46import org.osgi.service.component.annotations.Component;
47import org.osgi.service.component.annotations.Deactivate;
48import org.osgi.service.component.annotations.Modified;
49import org.osgi.service.component.annotations.Reference;
50import org.osgi.service.component.annotations.ReferenceCardinality;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080051import org.slf4j.Logger;
52
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070053import java.util.Collection;
54import java.util.Collections;
Charles Chan0c7c43b2016-01-14 17:39:20 -080055import java.util.Dictionary;
Charles Chan07f15f22018-05-08 21:35:50 -070056import java.util.concurrent.ExecutorService;
57import java.util.concurrent.Executors;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070058
Andrea Campanella1ea15102017-09-04 16:00:09 +020059import static com.google.common.base.Strings.isNullOrEmpty;
60import static org.onlab.util.Tools.get;
Charles Chan07f15f22018-05-08 21:35:50 -070061import static org.onlab.util.Tools.groupedThreads;
Thomas Vachuskaf566fa22018-10-30 14:03:36 -070062import static org.onosproject.net.OsgiPropertyConstants.*;
Changhoon Yoon541ef712015-05-23 17:18:34 +090063import static org.onosproject.security.AppGuard.checkPermission;
Jian Lid9b5f552016-03-11 18:15:31 -080064import static org.onosproject.security.AppPermission.Type.GROUP_READ;
65import static org.onosproject.security.AppPermission.Type.GROUP_WRITE;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070066import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoonb856b812015-08-10 03:47:19 +090067
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080068/**
69 * Provides implementation of the group service APIs.
70 */
Ray Milkeyd04e2272018-10-16 18:20:18 -070071@Component(
72 immediate = true,
73 service = {
74 GroupService.class,
75 GroupProviderRegistry.class
76 },
77 property = {
Ray Milkey2d7bca12018-10-17 14:51:52 -070078 GM_POLL_FREQUENCY + ":Integer=" + GM_POLL_FREQUENCY_DEFAULT,
79 GM_PURGE_ON_DISCONNECTION + ":Boolean=" + GM_PURGE_ON_DISCONNECTION_DEFAULT
Ray Milkeyd04e2272018-10-16 18:20:18 -070080 }
81)
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080082public class GroupManager
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070083 extends AbstractListenerProviderRegistry<GroupEvent, GroupListener,
84 GroupProvider, GroupProviderService>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080085 implements GroupService, GroupProviderRegistry {
86
87 private final Logger log = getLogger(getClass());
88
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080089 private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080090 private final DeviceListener deviceListener = new InternalDeviceListener();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080091
Charles Chan07f15f22018-05-08 21:35:50 -070092 private final GroupDriverProvider defaultProvider = new GroupDriverProvider();
93
94 private ExecutorService eventExecutor;
Andrea Campanella1ea15102017-09-04 16:00:09 +020095
Ray Milkeyd84f89b2018-08-17 14:54:17 -070096 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080097 protected GroupStore store;
98
Ray Milkeyd84f89b2018-08-17 14:54:17 -070099 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800100 protected DeviceService deviceService;
101
Jordan Halterman59afc6a2017-10-30 16:12:42 -0700102 // Reference the DriverService to ensure the service is bound prior to initialization of the GroupDriverProvider
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700103 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jordan Halterman59afc6a2017-10-30 16:12:42 -0700104 protected DriverService driverService;
105
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700106 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Charles Chan0c7c43b2016-01-14 17:39:20 -0800107 protected ComponentConfigService cfgService;
108
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700109 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Andrea Campanella1ea15102017-09-04 16:00:09 +0200110 protected MastershipService mastershipService;
111
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700112 /** Frequency (in seconds) for polling groups via fallback provider. */
Ray Milkeyd04e2272018-10-16 18:20:18 -0700113 private int fallbackGroupPollFrequency = GM_POLL_FREQUENCY_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200114
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700115 /** Purge entries associated with a device when the device goes offline. */
Ray Milkeyd04e2272018-10-16 18:20:18 -0700116 private boolean purgeOnDisconnection = GM_PURGE_ON_DISCONNECTION_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200117
Charles Chan0c7c43b2016-01-14 17:39:20 -0800118
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800119 @Activate
Charles Chan0c7c43b2016-01-14 17:39:20 -0800120 public void activate(ComponentContext context) {
Charles Chan07f15f22018-05-08 21:35:50 -0700121 eventExecutor = Executors.newSingleThreadExecutor(groupedThreads("onos/group", "event"));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800122 store.setDelegate(delegate);
123 eventDispatcher.addSink(GroupEvent.class, listenerRegistry);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800124 deviceService.addListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800125 cfgService.registerProperties(getClass());
126 modified(context);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800127 log.info("Started");
128 }
129
130 @Deactivate
131 public void deactivate() {
Charles Chan07f15f22018-05-08 21:35:50 -0700132 eventExecutor.shutdown();
Andrea Campanella5a3c09c2017-12-01 13:57:48 +0100133 defaultProvider.terminate();
Andrea Campanella3f1c61e2016-04-01 17:30:12 -0700134 deviceService.removeListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800135 cfgService.unregisterProperties(getClass(), false);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800136 store.unsetDelegate(delegate);
137 eventDispatcher.removeSink(GroupEvent.class);
138 log.info("Stopped");
139 }
140
Charles Chan0c7c43b2016-01-14 17:39:20 -0800141 @Modified
142 public void modified(ComponentContext context) {
143 if (context != null) {
144 readComponentConfiguration(context);
145 }
Andrea Campanella1ea15102017-09-04 16:00:09 +0200146 defaultProvider.init(deviceService, new InternalGroupProviderService(defaultProvider),
147 mastershipService, fallbackGroupPollFrequency);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800148 }
149
150 @Override
151 protected GroupProvider defaultProvider() {
152 return defaultProvider;
Charles Chan0c7c43b2016-01-14 17:39:20 -0800153 }
154
155 /**
156 * Extracts properties from the component configuration context.
157 *
158 * @param context the component context
159 */
160 private void readComponentConfiguration(ComponentContext context) {
161 Dictionary<?, ?> properties = context.getProperties();
162 Boolean flag;
163
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700164 flag = Tools.isPropertyEnabled(properties, GM_PURGE_ON_DISCONNECTION);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800165 if (flag == null) {
166 log.info("PurgeOnDisconnection is not configured, " +
167 "using current value of {}", purgeOnDisconnection);
168 } else {
169 purgeOnDisconnection = flag;
170 log.info("Configured. PurgeOnDisconnection is {}",
171 purgeOnDisconnection ? "enabled" : "disabled");
172 }
Thomas Vachuskaf566fa22018-10-30 14:03:36 -0700173 String s = get(properties, GM_POLL_FREQUENCY);
Andrea Campanella1ea15102017-09-04 16:00:09 +0200174 try {
Ray Milkeyd04e2272018-10-16 18:20:18 -0700175 fallbackGroupPollFrequency = isNullOrEmpty(s) ? GM_POLL_FREQUENCY_DEFAULT : Integer.parseInt(s);
Andrea Campanella1ea15102017-09-04 16:00:09 +0200176 } catch (NumberFormatException e) {
Ray Milkeyd04e2272018-10-16 18:20:18 -0700177 fallbackGroupPollFrequency = GM_POLL_FREQUENCY_DEFAULT;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200178 }
Charles Chan0c7c43b2016-01-14 17:39:20 -0800179 }
180
181 /**
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800182 * Create a group in the specified device with the provided parameters.
183 *
184 * @param groupDesc group creation parameters
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800185 */
186 @Override
187 public void addGroup(GroupDescription groupDesc) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900188 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800189 store.storeGroupDescription(groupDesc);
190 }
191
192 /**
193 * Return a group object associated to an application cookie.
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700194 * <p>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800195 * NOTE1: The presence of group object in the system does not
196 * guarantee that the "group" is actually created in device.
197 * GROUP_ADDED notification would confirm the creation of
198 * this group in data plane.
199 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700200 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800201 * @param appCookie application cookie to be used for lookup
202 * @return group associated with the application cookie or
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700203 * NULL if Group is not found for the provided cookie
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800204 */
205 @Override
206 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900207 checkPermission(GROUP_READ);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800208 return store.getGroup(deviceId, appCookie);
209 }
210
211 /**
212 * Append buckets to existing group. The caller can optionally
213 * associate a new cookie during this updation. GROUP_UPDATED or
214 * GROUP_UPDATE_FAILED notifications would be provided along with
215 * cookie depending on the result of the operation on the device.
216 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700217 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800218 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700219 * @param buckets immutable list of group bucket to be added
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800220 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700221 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800222 */
223 @Override
224 public void addBucketsToGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700225 GroupKey oldCookie,
226 GroupBuckets buckets,
227 GroupKey newCookie,
228 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900229 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800230 store.updateGroupDescription(deviceId,
231 oldCookie,
232 UpdateType.ADD,
233 buckets,
234 newCookie);
235 }
236
237 /**
238 * Remove buckets from existing group. The caller can optionally
239 * associate a new cookie during this updation. GROUP_UPDATED or
240 * GROUP_UPDATE_FAILED notifications would be provided along with
241 * cookie depending on the result of the operation on the device.
242 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700243 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800244 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700245 * @param buckets immutable list of group bucket to be removed
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800246 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700247 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800248 */
249 @Override
250 public void removeBucketsFromGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700251 GroupKey oldCookie,
252 GroupBuckets buckets,
253 GroupKey newCookie,
254 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900255 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800256 store.updateGroupDescription(deviceId,
257 oldCookie,
258 UpdateType.REMOVE,
259 buckets,
260 newCookie);
261 }
262
Victor Silva0282ab82016-11-15 16:30:27 -0300263 /**
264 * Set buckets for an existing group. The caller can optionally
265 * associate a new cookie during this updation. GROUP_UPDATED or
266 * GROUP_UPDATE_FAILED notifications would be provided along with
267 * cookie depending on the result of the operation on the device.
268 *
269 * This operation overwrites the previous group buckets entirely.
270 *
271 * @param deviceId device identifier
272 * @param oldCookie cookie to be used to retrieve the existing group
273 * @param buckets immutable list of group buckets to be set
274 * @param newCookie immutable cookie to be used post update operation
275 * @param appId Application Id
276 */
277 @Override
278 public void setBucketsForGroup(DeviceId deviceId,
279 GroupKey oldCookie,
280 GroupBuckets buckets,
281 GroupKey newCookie,
282 ApplicationId appId) {
283 checkPermission(GROUP_WRITE);
284 store.updateGroupDescription(deviceId,
285 oldCookie,
286 UpdateType.SET,
287 buckets,
288 newCookie);
289 }
290
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530291 @Override
292 public void purgeGroupEntries(DeviceId deviceId) {
293 checkPermission(GROUP_WRITE);
294 store.purgeGroupEntry(deviceId);
295 }
296
Victor Silva4e8b7832016-08-17 17:11:19 -0300297 @Override
298 public void purgeGroupEntries() {
299 checkPermission(GROUP_WRITE);
300 store.purgeGroupEntries();
301 }
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530302
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800303 /**
304 * Delete a group associated to an application cookie.
305 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
306 * provided along with cookie depending on the result of the
307 * operation on the device.
308 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700309 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800310 * @param appCookie application cookie to be used for lookup
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700311 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800312 */
313 @Override
314 public void removeGroup(DeviceId deviceId,
315 GroupKey appCookie,
316 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900317 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800318 store.deleteGroupDescription(deviceId, appCookie);
319 }
320
321 /**
322 * Retrieve all groups created by an application in the specified device
323 * as seen by current controller instance.
324 *
325 * @param deviceId device identifier
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700326 * @param appId application id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800327 * @return collection of immutable group objects created by the application
328 */
329 @Override
330 public Iterable<Group> getGroups(DeviceId deviceId,
331 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900332 checkPermission(GROUP_READ);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800333 return store.getGroups(deviceId);
334 }
335
Jonathan Hart32600692015-03-09 10:38:40 -0700336 @Override
337 public Iterable<Group> getGroups(DeviceId deviceId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900338 checkPermission(GROUP_READ);
Jonathan Hart32600692015-03-09 10:38:40 -0700339 return store.getGroups(deviceId);
340 }
341
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800342 @Override
343 protected GroupProviderService createProviderService(GroupProvider provider) {
344 return new InternalGroupProviderService(provider);
345 }
346
347 private class InternalGroupStoreDelegate implements GroupStoreDelegate {
348 @Override
349 public void notify(GroupEvent event) {
350 final Group group = event.subject();
351 GroupProvider groupProvider =
352 getProvider(group.deviceId());
353 GroupOperations groupOps = null;
354 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700355 case GROUP_ADD_REQUESTED:
356 log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
357 group.id(), group.deviceId());
358 GroupOperation groupAddOp = GroupOperation.
359 createAddGroupOperation(group.id(),
360 group.type(),
361 group.buckets());
362 groupOps = new GroupOperations(
363 Collections.singletonList(groupAddOp));
364 groupProvider.performGroupOperation(group.deviceId(), groupOps);
365 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800366
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700367 case GROUP_UPDATE_REQUESTED:
368 log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
369 group.id(), group.deviceId());
370 GroupOperation groupModifyOp = GroupOperation.
371 createModifyGroupOperation(group.id(),
372 group.type(),
373 group.buckets());
374 groupOps = new GroupOperations(
375 Collections.singletonList(groupModifyOp));
376 groupProvider.performGroupOperation(group.deviceId(), groupOps);
377 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800378
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700379 case GROUP_REMOVE_REQUESTED:
380 log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
381 group.id(), group.deviceId());
382 GroupOperation groupDeleteOp = GroupOperation.
383 createDeleteGroupOperation(group.id(),
384 group.type());
385 groupOps = new GroupOperations(
386 Collections.singletonList(groupDeleteOp));
387 groupProvider.performGroupOperation(group.deviceId(), groupOps);
388 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800389
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700390 case GROUP_ADDED:
391 case GROUP_UPDATED:
392 case GROUP_REMOVED:
393 case GROUP_ADD_FAILED:
394 case GROUP_UPDATE_FAILED:
395 case GROUP_REMOVE_FAILED:
helenyrwu89470f12016-08-12 13:18:10 -0700396 case GROUP_BUCKET_FAILOVER:
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700397 post(event);
398 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700399 default:
400 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800401 }
402 }
403 }
404
405 private class InternalGroupProviderService
406 extends AbstractProviderService<GroupProvider>
407 implements GroupProviderService {
408
409 protected InternalGroupProviderService(GroupProvider provider) {
410 super(provider);
411 }
412
413 @Override
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700414 public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
sangho7ff01812015-02-09 16:21:53 -0800415 store.groupOperationFailed(deviceId, operation);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800416 }
417
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800418 @Override
419 public void pushGroupMetrics(DeviceId deviceId,
420 Collection<Group> groupEntries) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700421 log.trace("Received group metrics from device {}", deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700422 checkValidity();
423 store.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800424 }
helenyrwu89470f12016-08-12 13:18:10 -0700425
426 @Override
427 public void notifyOfFailovers(Collection<Group> failoverGroups) {
428 store.notifyOfFailovers(failoverGroups);
429 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800430 }
431
432 private class InternalDeviceListener implements DeviceListener {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800433 @Override
434 public void event(DeviceEvent event) {
Charles Chan07f15f22018-05-08 21:35:50 -0700435 eventExecutor.execute(() -> processEventInternal(event));
436 }
437
438 private void processEventInternal(DeviceEvent event) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800439 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700440 case DEVICE_REMOVED:
441 case DEVICE_AVAILABILITY_CHANGED:
Charles Chan0c7c43b2016-01-14 17:39:20 -0800442 DeviceId deviceId = event.subject().id();
443 if (!deviceService.isAvailable(deviceId)) {
Tian Jian9cb2e9e2018-10-23 16:32:51 +0800444 log.debug("Device {} became unavailable for {}; clearing initial audit status",
445 deviceId, event.type());
446 store.deviceInitialAuditCompleted(deviceId, false);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800447
448 if (purgeOnDisconnection) {
449 store.purgeGroupEntry(deviceId);
450 }
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700451 }
452 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700453 default:
454 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800455 }
456 }
457 }
helenyrwu89470f12016-08-12 13:18:10 -0700458
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800459}