blob: 19d575378cf5b13703b120b510817960dadee81f [file] [log] [blame]
Jonathan Hartf8cd0522016-10-25 07:09:55 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jonathan Hartf8cd0522016-10-25 07:09:55 -07003 *
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 */
16
Jonathan Hartf4bd0482017-01-27 15:11:18 -080017package org.onosproject.routing;
Jonathan Hartf8cd0522016-10-25 07:09:55 -070018
19import org.onosproject.net.DeviceId;
20import org.onosproject.net.device.DeviceEvent;
21import org.onosproject.net.device.DeviceListener;
22import org.onosproject.net.device.DeviceService;
23
24import java.util.Map;
Charles Chanc6d227e2017-02-28 15:15:17 -080025import java.util.Optional;
Jonathan Hartf8cd0522016-10-25 07:09:55 -070026import java.util.concurrent.ConcurrentHashMap;
27
Jonathan Hart249b4cf2017-02-03 18:02:58 -080028import static com.google.common.base.Preconditions.checkNotNull;
29
Jonathan Hartf8cd0522016-10-25 07:09:55 -070030/**
31 * Provides a means of asynchronously waiting on devices.
32 */
33public final class AsyncDeviceFetcher {
34
35 private DeviceService deviceService;
36
37 private DeviceListener listener = new InternalDeviceListener();
38
Charles Chanc6d227e2017-02-28 15:15:17 -080039 private Map<DeviceId, Runnable> onConnect = new ConcurrentHashMap<>();
40 private Map<DeviceId, Runnable> onDisconnect = new ConcurrentHashMap<>();
Jonathan Hartf8cd0522016-10-25 07:09:55 -070041
42 private AsyncDeviceFetcher(DeviceService deviceService) {
Jonathan Hart249b4cf2017-02-03 18:02:58 -080043 this.deviceService = checkNotNull(deviceService);
Jonathan Hartf8cd0522016-10-25 07:09:55 -070044 deviceService.addListener(listener);
45 }
46
47 /**
48 * Shuts down.
49 */
50 public void shutdown() {
51 deviceService.removeListener(listener);
Charles Chanc6d227e2017-02-28 15:15:17 -080052 onConnect.clear();
53 onDisconnect.clear();
Jonathan Hartf8cd0522016-10-25 07:09:55 -070054 }
55
56 /**
Charles Chanc6d227e2017-02-28 15:15:17 -080057 * Executes provided callback when given device connects/disconnects.
58 * @param deviceId device ID
59 * @param onConnect callback that will be executed immediately if the device
60 * is currently online, or when the device becomes online
61 * @param onDisconnect callback that will be executed when the device becomes offline
Jonathan Hartf8cd0522016-10-25 07:09:55 -070062 */
Charles Chanc6d227e2017-02-28 15:15:17 -080063 void registerCallback(DeviceId deviceId, Runnable onConnect, Runnable onDisconnect) {
64 if (onConnect != null) {
Jonathan Hartf8cd0522016-10-25 07:09:55 -070065 if (deviceService.isAvailable(deviceId)) {
Charles Chanc6d227e2017-02-28 15:15:17 -080066 onConnect.run();
Jonathan Hartf8cd0522016-10-25 07:09:55 -070067 }
Charles Chanc6d227e2017-02-28 15:15:17 -080068 this.onConnect.put(deviceId, onConnect);
69 }
70 if (onDisconnect != null) {
71 this.onDisconnect.put(deviceId, onDisconnect);
72 }
Jonathan Hartf8cd0522016-10-25 07:09:55 -070073 }
74
75 /**
76 * Creates a device fetcher based on the device service.
77 *
78 * @param deviceService device service
79 * @return device fetcher
80 */
81 public static AsyncDeviceFetcher create(DeviceService deviceService) {
82 return new AsyncDeviceFetcher(deviceService);
83 }
84
85 private class InternalDeviceListener implements DeviceListener {
86 @Override
87 public void event(DeviceEvent event) {
88 switch (event.type()) {
Charles Chanc6d227e2017-02-28 15:15:17 -080089 case DEVICE_ADDED:
90 case DEVICE_AVAILABILITY_CHANGED:
Jonathan Hartf8cd0522016-10-25 07:09:55 -070091 DeviceId deviceId = event.subject().id();
Charles Chanc6d227e2017-02-28 15:15:17 -080092 if (deviceService.isAvailable(deviceId)) {
93 Optional.ofNullable(onConnect.get(deviceId)).ifPresent(Runnable::run);
94 } else {
95 Optional.ofNullable(onDisconnect.get(deviceId)).ifPresent(Runnable::run);
Jonathan Hartf8cd0522016-10-25 07:09:55 -070096 }
Charles Chanc6d227e2017-02-28 15:15:17 -080097 break;
98 case DEVICE_UPDATED:
99 case DEVICE_REMOVED:
100 case DEVICE_SUSPENDED:
101 case PORT_ADDED:
102 case PORT_UPDATED:
103 case PORT_REMOVED:
104 default:
105 break;
Jonathan Hartf8cd0522016-10-25 07:09:55 -0700106 }
107 }
108 }
109}