blob: 4a0e4098319bb7d50adbb38b1c41cd78fb875c65 [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
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080018import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
Charles Chan0c7c43b2016-01-14 17:39:20 -080021import org.apache.felix.scr.annotations.Modified;
22import org.apache.felix.scr.annotations.Property;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.apache.felix.scr.annotations.Service;
Jian Lid9b5f552016-03-11 18:15:31 -080026import org.onlab.util.Tools;
Charles Chan0c7c43b2016-01-14 17:39:20 -080027import org.onosproject.cfg.ComponentConfigService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080028import org.onosproject.core.ApplicationId;
Andrea Campanella1ea15102017-09-04 16:00:09 +020029import org.onosproject.mastership.MastershipService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080030import org.onosproject.net.DeviceId;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080031import org.onosproject.net.device.DeviceEvent;
32import org.onosproject.net.device.DeviceListener;
33import org.onosproject.net.device.DeviceService;
Jordan Halterman59afc6a2017-10-30 16:12:42 -070034import org.onosproject.net.driver.DriverService;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080035import org.onosproject.net.group.Group;
36import org.onosproject.net.group.GroupBuckets;
37import org.onosproject.net.group.GroupDescription;
38import org.onosproject.net.group.GroupEvent;
39import org.onosproject.net.group.GroupKey;
40import org.onosproject.net.group.GroupListener;
41import org.onosproject.net.group.GroupOperation;
42import org.onosproject.net.group.GroupOperations;
43import org.onosproject.net.group.GroupProvider;
44import org.onosproject.net.group.GroupProviderRegistry;
45import org.onosproject.net.group.GroupProviderService;
46import org.onosproject.net.group.GroupService;
47import org.onosproject.net.group.GroupStore;
48import org.onosproject.net.group.GroupStore.UpdateType;
49import org.onosproject.net.group.GroupStoreDelegate;
Jian Lid9b5f552016-03-11 18:15:31 -080050import org.onosproject.net.provider.AbstractListenerProviderRegistry;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080051import org.onosproject.net.provider.AbstractProviderService;
Charles Chan0c7c43b2016-01-14 17:39:20 -080052import org.osgi.service.component.ComponentContext;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080053import org.slf4j.Logger;
54
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070055import java.util.Collection;
56import java.util.Collections;
Charles Chan0c7c43b2016-01-14 17:39:20 -080057import java.util.Dictionary;
Charles Chan07f15f22018-05-08 21:35:50 -070058import java.util.concurrent.ExecutorService;
59import java.util.concurrent.Executors;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070060
Andrea Campanella1ea15102017-09-04 16:00:09 +020061import static com.google.common.base.Strings.isNullOrEmpty;
62import static org.onlab.util.Tools.get;
Charles Chan07f15f22018-05-08 21:35:50 -070063import static org.onlab.util.Tools.groupedThreads;
Changhoon Yoon541ef712015-05-23 17:18:34 +090064import static org.onosproject.security.AppGuard.checkPermission;
Jian Lid9b5f552016-03-11 18:15:31 -080065import static org.onosproject.security.AppPermission.Type.GROUP_READ;
66import static org.onosproject.security.AppPermission.Type.GROUP_WRITE;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070067import static org.slf4j.LoggerFactory.getLogger;
Changhoon Yoonb856b812015-08-10 03:47:19 +090068
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080069/**
70 * Provides implementation of the group service APIs.
71 */
72@Component(immediate = true)
73@Service
74public class GroupManager
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070075 extends AbstractListenerProviderRegistry<GroupEvent, GroupListener,
76 GroupProvider, GroupProviderService>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080077 implements GroupService, GroupProviderRegistry {
78
79 private final Logger log = getLogger(getClass());
80
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080081 private final GroupStoreDelegate delegate = new InternalGroupStoreDelegate();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080082 private final DeviceListener deviceListener = new InternalDeviceListener();
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080083
Charles Chan07f15f22018-05-08 21:35:50 -070084 private final GroupDriverProvider defaultProvider = new GroupDriverProvider();
85
86 private ExecutorService eventExecutor;
Andrea Campanella1ea15102017-09-04 16:00:09 +020087
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -080088 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected GroupStore store;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080092 protected DeviceService deviceService;
93
Jordan Halterman59afc6a2017-10-30 16:12:42 -070094 // Reference the DriverService to ensure the service is bound prior to initialization of the GroupDriverProvider
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected DriverService driverService;
97
Charles Chan0c7c43b2016-01-14 17:39:20 -080098 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected ComponentConfigService cfgService;
100
Andrea Campanella1ea15102017-09-04 16:00:09 +0200101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected MastershipService mastershipService;
103
104 private static final int DEFAULT_POLL_FREQUENCY = 30;
105 @Property(name = "fallbackGroupPollFrequency", intValue = DEFAULT_POLL_FREQUENCY,
106 label = "Frequency (in seconds) for polling groups via fallback provider")
107 private int fallbackGroupPollFrequency = DEFAULT_POLL_FREQUENCY;
108
Charles Chan0c7c43b2016-01-14 17:39:20 -0800109 @Property(name = "purgeOnDisconnection", boolValue = false,
110 label = "Purge entries associated with a device when the device goes offline")
111 private boolean purgeOnDisconnection = false;
Andrea Campanella1ea15102017-09-04 16:00:09 +0200112
Charles Chan0c7c43b2016-01-14 17:39:20 -0800113
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800114 @Activate
Charles Chan0c7c43b2016-01-14 17:39:20 -0800115 public void activate(ComponentContext context) {
Charles Chan07f15f22018-05-08 21:35:50 -0700116 eventExecutor = Executors.newSingleThreadExecutor(groupedThreads("onos/group", "event"));
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800117 store.setDelegate(delegate);
118 eventDispatcher.addSink(GroupEvent.class, listenerRegistry);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800119 deviceService.addListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800120 cfgService.registerProperties(getClass());
121 modified(context);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800122 log.info("Started");
123 }
124
125 @Deactivate
126 public void deactivate() {
Charles Chan07f15f22018-05-08 21:35:50 -0700127 eventExecutor.shutdown();
Andrea Campanella5a3c09c2017-12-01 13:57:48 +0100128 defaultProvider.terminate();
Andrea Campanella3f1c61e2016-04-01 17:30:12 -0700129 deviceService.removeListener(deviceListener);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800130 cfgService.unregisterProperties(getClass(), false);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800131 store.unsetDelegate(delegate);
132 eventDispatcher.removeSink(GroupEvent.class);
133 log.info("Stopped");
134 }
135
Charles Chan0c7c43b2016-01-14 17:39:20 -0800136 @Modified
137 public void modified(ComponentContext context) {
138 if (context != null) {
139 readComponentConfiguration(context);
140 }
Andrea Campanella1ea15102017-09-04 16:00:09 +0200141 defaultProvider.init(deviceService, new InternalGroupProviderService(defaultProvider),
142 mastershipService, fallbackGroupPollFrequency);
Andrea Campanella6ee73922016-02-03 18:00:00 -0800143 }
144
145 @Override
146 protected GroupProvider defaultProvider() {
147 return defaultProvider;
Charles Chan0c7c43b2016-01-14 17:39:20 -0800148 }
149
150 /**
151 * Extracts properties from the component configuration context.
152 *
153 * @param context the component context
154 */
155 private void readComponentConfiguration(ComponentContext context) {
156 Dictionary<?, ?> properties = context.getProperties();
157 Boolean flag;
158
Jian Lid9b5f552016-03-11 18:15:31 -0800159 flag = Tools.isPropertyEnabled(properties, "purgeOnDisconnection");
Charles Chan0c7c43b2016-01-14 17:39:20 -0800160 if (flag == null) {
161 log.info("PurgeOnDisconnection is not configured, " +
162 "using current value of {}", purgeOnDisconnection);
163 } else {
164 purgeOnDisconnection = flag;
165 log.info("Configured. PurgeOnDisconnection is {}",
166 purgeOnDisconnection ? "enabled" : "disabled");
167 }
Andrea Campanella1ea15102017-09-04 16:00:09 +0200168 String s = get(properties, "fallbackGroupPollFrequency");
169 try {
170 fallbackGroupPollFrequency = isNullOrEmpty(s) ? DEFAULT_POLL_FREQUENCY : Integer.parseInt(s);
171 } catch (NumberFormatException e) {
172 fallbackGroupPollFrequency = DEFAULT_POLL_FREQUENCY;
173 }
Charles Chan0c7c43b2016-01-14 17:39:20 -0800174 }
175
176 /**
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800177 * Create a group in the specified device with the provided parameters.
178 *
179 * @param groupDesc group creation parameters
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800180 */
181 @Override
182 public void addGroup(GroupDescription groupDesc) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900183 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800184 store.storeGroupDescription(groupDesc);
185 }
186
187 /**
188 * Return a group object associated to an application cookie.
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700189 * <p>
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800190 * NOTE1: The presence of group object in the system does not
191 * guarantee that the "group" is actually created in device.
192 * GROUP_ADDED notification would confirm the creation of
193 * this group in data plane.
194 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700195 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800196 * @param appCookie application cookie to be used for lookup
197 * @return group associated with the application cookie or
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700198 * NULL if Group is not found for the provided cookie
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800199 */
200 @Override
201 public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900202 checkPermission(GROUP_READ);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800203 return store.getGroup(deviceId, appCookie);
204 }
205
206 /**
207 * Append buckets to existing group. The caller can optionally
208 * associate a new cookie during this updation. GROUP_UPDATED or
209 * GROUP_UPDATE_FAILED notifications would be provided along with
210 * cookie depending on the result of the operation on the device.
211 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700212 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800213 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700214 * @param buckets immutable list of group bucket to be added
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800215 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700216 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800217 */
218 @Override
219 public void addBucketsToGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700220 GroupKey oldCookie,
221 GroupBuckets buckets,
222 GroupKey newCookie,
223 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900224 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800225 store.updateGroupDescription(deviceId,
226 oldCookie,
227 UpdateType.ADD,
228 buckets,
229 newCookie);
230 }
231
232 /**
233 * Remove buckets from existing group. The caller can optionally
234 * associate a new cookie during this updation. GROUP_UPDATED or
235 * GROUP_UPDATE_FAILED notifications would be provided along with
236 * cookie depending on the result of the operation on the device.
237 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700238 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800239 * @param oldCookie cookie to be used to retrieve the existing group
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700240 * @param buckets immutable list of group bucket to be removed
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800241 * @param newCookie immutable cookie to be used post update operation
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700242 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800243 */
244 @Override
245 public void removeBucketsFromGroup(DeviceId deviceId,
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700246 GroupKey oldCookie,
247 GroupBuckets buckets,
248 GroupKey newCookie,
249 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900250 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800251 store.updateGroupDescription(deviceId,
252 oldCookie,
253 UpdateType.REMOVE,
254 buckets,
255 newCookie);
256 }
257
Victor Silva0282ab82016-11-15 16:30:27 -0300258 /**
259 * Set buckets for an existing group. The caller can optionally
260 * associate a new cookie during this updation. GROUP_UPDATED or
261 * GROUP_UPDATE_FAILED notifications would be provided along with
262 * cookie depending on the result of the operation on the device.
263 *
264 * This operation overwrites the previous group buckets entirely.
265 *
266 * @param deviceId device identifier
267 * @param oldCookie cookie to be used to retrieve the existing group
268 * @param buckets immutable list of group buckets to be set
269 * @param newCookie immutable cookie to be used post update operation
270 * @param appId Application Id
271 */
272 @Override
273 public void setBucketsForGroup(DeviceId deviceId,
274 GroupKey oldCookie,
275 GroupBuckets buckets,
276 GroupKey newCookie,
277 ApplicationId appId) {
278 checkPermission(GROUP_WRITE);
279 store.updateGroupDescription(deviceId,
280 oldCookie,
281 UpdateType.SET,
282 buckets,
283 newCookie);
284 }
285
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530286 @Override
287 public void purgeGroupEntries(DeviceId deviceId) {
288 checkPermission(GROUP_WRITE);
289 store.purgeGroupEntry(deviceId);
290 }
291
Victor Silva4e8b7832016-08-17 17:11:19 -0300292 @Override
293 public void purgeGroupEntries() {
294 checkPermission(GROUP_WRITE);
295 store.purgeGroupEntries();
296 }
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530297
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800298 /**
299 * Delete a group associated to an application cookie.
300 * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
301 * provided along with cookie depending on the result of the
302 * operation on the device.
303 *
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700304 * @param deviceId device identifier
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800305 * @param appCookie application cookie to be used for lookup
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700306 * @param appId Application Id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800307 */
308 @Override
309 public void removeGroup(DeviceId deviceId,
310 GroupKey appCookie,
311 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900312 checkPermission(GROUP_WRITE);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800313 store.deleteGroupDescription(deviceId, appCookie);
314 }
315
316 /**
317 * Retrieve all groups created by an application in the specified device
318 * as seen by current controller instance.
319 *
320 * @param deviceId device identifier
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700321 * @param appId application id
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800322 * @return collection of immutable group objects created by the application
323 */
324 @Override
325 public Iterable<Group> getGroups(DeviceId deviceId,
326 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900327 checkPermission(GROUP_READ);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800328 return store.getGroups(deviceId);
329 }
330
Jonathan Hart32600692015-03-09 10:38:40 -0700331 @Override
332 public Iterable<Group> getGroups(DeviceId deviceId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900333 checkPermission(GROUP_READ);
Jonathan Hart32600692015-03-09 10:38:40 -0700334 return store.getGroups(deviceId);
335 }
336
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800337 @Override
338 protected GroupProviderService createProviderService(GroupProvider provider) {
339 return new InternalGroupProviderService(provider);
340 }
341
342 private class InternalGroupStoreDelegate implements GroupStoreDelegate {
343 @Override
344 public void notify(GroupEvent event) {
345 final Group group = event.subject();
346 GroupProvider groupProvider =
347 getProvider(group.deviceId());
348 GroupOperations groupOps = null;
349 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700350 case GROUP_ADD_REQUESTED:
351 log.debug("GROUP_ADD_REQUESTED for Group {} on device {}",
352 group.id(), group.deviceId());
353 GroupOperation groupAddOp = GroupOperation.
354 createAddGroupOperation(group.id(),
355 group.type(),
356 group.buckets());
357 groupOps = new GroupOperations(
358 Collections.singletonList(groupAddOp));
359 groupProvider.performGroupOperation(group.deviceId(), groupOps);
360 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800361
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700362 case GROUP_UPDATE_REQUESTED:
363 log.debug("GROUP_UPDATE_REQUESTED for Group {} on device {}",
364 group.id(), group.deviceId());
365 GroupOperation groupModifyOp = GroupOperation.
366 createModifyGroupOperation(group.id(),
367 group.type(),
368 group.buckets());
369 groupOps = new GroupOperations(
370 Collections.singletonList(groupModifyOp));
371 groupProvider.performGroupOperation(group.deviceId(), groupOps);
372 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800373
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700374 case GROUP_REMOVE_REQUESTED:
375 log.debug("GROUP_REMOVE_REQUESTED for Group {} on device {}",
376 group.id(), group.deviceId());
377 GroupOperation groupDeleteOp = GroupOperation.
378 createDeleteGroupOperation(group.id(),
379 group.type());
380 groupOps = new GroupOperations(
381 Collections.singletonList(groupDeleteOp));
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_ADDED:
386 case GROUP_UPDATED:
387 case GROUP_REMOVED:
388 case GROUP_ADD_FAILED:
389 case GROUP_UPDATE_FAILED:
390 case GROUP_REMOVE_FAILED:
helenyrwu89470f12016-08-12 13:18:10 -0700391 case GROUP_BUCKET_FAILOVER:
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700392 post(event);
393 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700394 default:
395 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800396 }
397 }
398 }
399
400 private class InternalGroupProviderService
401 extends AbstractProviderService<GroupProvider>
402 implements GroupProviderService {
403
404 protected InternalGroupProviderService(GroupProvider provider) {
405 super(provider);
406 }
407
408 @Override
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700409 public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
sangho7ff01812015-02-09 16:21:53 -0800410 store.groupOperationFailed(deviceId, operation);
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800411 }
412
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800413 @Override
414 public void pushGroupMetrics(DeviceId deviceId,
415 Collection<Group> groupEntries) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700416 log.trace("Received group metrics from device {}", deviceId);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700417 checkValidity();
418 store.pushGroupMetrics(deviceId, groupEntries);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800419 }
helenyrwu89470f12016-08-12 13:18:10 -0700420
421 @Override
422 public void notifyOfFailovers(Collection<Group> failoverGroups) {
423 store.notifyOfFailovers(failoverGroups);
424 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800425 }
426
427 private class InternalDeviceListener implements DeviceListener {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800428 @Override
429 public void event(DeviceEvent event) {
Charles Chan07f15f22018-05-08 21:35:50 -0700430 eventExecutor.execute(() -> processEventInternal(event));
431 }
432
433 private void processEventInternal(DeviceEvent event) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800434 switch (event.type()) {
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700435 case DEVICE_REMOVED:
436 case DEVICE_AVAILABILITY_CHANGED:
Charles Chan0c7c43b2016-01-14 17:39:20 -0800437 DeviceId deviceId = event.subject().id();
438 if (!deviceService.isAvailable(deviceId)) {
Charles Chan07f15f22018-05-08 21:35:50 -0700439 log.debug("Device {} became unavailable; clearing initial audit status",
440 event.type(), event.subject().id());
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700441 store.deviceInitialAuditCompleted(event.subject().id(), false);
Charles Chan0c7c43b2016-01-14 17:39:20 -0800442
443 if (purgeOnDisconnection) {
444 store.purgeGroupEntry(deviceId);
445 }
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700446 }
447 break;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700448 default:
449 break;
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800450 }
451 }
452 }
helenyrwu89470f12016-08-12 13:18:10 -0700453
Srikanth Vavilapalli45c27c82015-01-30 12:57:56 -0800454}