blob: 65ffec0dc4e6ffb4246844ac1eed46b938816f16 [file] [log] [blame]
Jonathan Hartf8cd0522016-10-25 07:09:55 -07001/*
2 * Copyright 2017-present 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 */
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;
25import java.util.concurrent.CompletableFuture;
26import 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
39 private Map<DeviceId, CompletableFuture<DeviceId>> devices = new ConcurrentHashMap();
40
41 private AsyncDeviceFetcher(DeviceService deviceService) {
Jonathan Hart249b4cf2017-02-03 18:02:58 -080042 this.deviceService = checkNotNull(deviceService);
Jonathan Hartf8cd0522016-10-25 07:09:55 -070043 deviceService.addListener(listener);
44 }
45
46 /**
47 * Shuts down.
48 */
49 public void shutdown() {
50 deviceService.removeListener(listener);
51 devices.clear();
52 }
53
54 /**
55 * Returns a completable future that completes when the device is available
56 * for the first time.
57 *
58 * @param deviceId ID of the device
59 * @return completable future
60 */
61 public CompletableFuture<DeviceId> getDevice(DeviceId deviceId) {
62 CompletableFuture<DeviceId> future = new CompletableFuture<>();
63 return devices.computeIfAbsent(deviceId, deviceId1 -> {
64 if (deviceService.isAvailable(deviceId)) {
65 future.complete(deviceId);
66 }
67 return future;
68 });
69 }
70
71 /**
72 * Creates a device fetcher based on the device service.
73 *
74 * @param deviceService device service
75 * @return device fetcher
76 */
77 public static AsyncDeviceFetcher create(DeviceService deviceService) {
78 return new AsyncDeviceFetcher(deviceService);
79 }
80
81 private class InternalDeviceListener implements DeviceListener {
82 @Override
83 public void event(DeviceEvent event) {
84 switch (event.type()) {
85 case DEVICE_ADDED:
86 case DEVICE_AVAILABILITY_CHANGED:
87 if (deviceService.isAvailable(event.subject().id())) {
88 DeviceId deviceId = event.subject().id();
89 CompletableFuture<DeviceId> future = devices.get(deviceId);
90 if (future != null) {
91 future.complete(deviceId);
92 }
93 }
94 break;
95 case DEVICE_UPDATED:
96 case DEVICE_REMOVED:
97 case DEVICE_SUSPENDED:
98 case PORT_ADDED:
99 case PORT_UPDATED:
100 case PORT_REMOVED:
101 default:
102 break;
103 }
104 }
105 }
106}