blob: 9494cbeeb9bc46f9d25b08e3fb83d3ecab0daeb0 [file] [log] [blame]
Sho SHIMIZUd97a9502015-08-18 10:02:30 -07001/*
2 * Copyright 2015 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 */
16package org.onosproject.net.newresource.impl;
17
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -080018import com.google.common.collect.ImmutableSet;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080019import org.onlab.packet.MplsLabel;
20import org.onlab.packet.VlanId;
21import org.onlab.util.ItemNotFoundException;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070022import org.onosproject.net.Device;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080023import org.onosproject.net.DeviceId;
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080024import org.onosproject.net.OchSignal;
Toru Furusawac23f5832015-12-04 11:39:18 -080025import org.onosproject.net.Port;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080026import org.onosproject.net.PortNumber;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020027import org.onosproject.net.TributarySlot;
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080028import org.onosproject.net.behaviour.LambdaQuery;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080029import org.onosproject.net.behaviour.MplsQuery;
Toru Furusawac23f5832015-12-04 11:39:18 -080030import org.onosproject.net.behaviour.TributarySlotQuery;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080031import org.onosproject.net.behaviour.VlanQuery;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070032import org.onosproject.net.device.DeviceEvent;
33import org.onosproject.net.device.DeviceListener;
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080034import org.onosproject.net.device.DeviceService;
35import org.onosproject.net.driver.Driver;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080036import org.onosproject.net.driver.DriverHandler;
37import org.onosproject.net.driver.DriverService;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070038import org.onosproject.net.newresource.ResourceAdminService;
39import org.onosproject.net.newresource.ResourcePath;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020040import org.slf4j.Logger;
41import org.slf4j.LoggerFactory;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070042
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080043import java.util.Collections;
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -080044import java.util.Set;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070045import java.util.concurrent.ExecutorService;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020046import java.util.stream.Collectors;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070047
48import static com.google.common.base.Preconditions.checkNotNull;
49
50/**
51 * An implementation of DeviceListener registering devices as resources.
52 */
53final class ResourceDeviceListener implements DeviceListener {
54
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020055 private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
56
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070057 private final ResourceAdminService adminService;
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080058 private final DeviceService deviceService;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080059 private final DriverService driverService;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070060 private final ExecutorService executor;
61
62 /**
63 * Creates an instance with the specified ResourceAdminService and ExecutorService.
64 *
65 * @param adminService instance invoked to register resources
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080066 * @param deviceService {@link DeviceService} to be used.
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070067 * @param executor executor used for processing resource registration
68 */
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080069 ResourceDeviceListener(ResourceAdminService adminService, DeviceService deviceService, DriverService driverService,
Sho SHIMIZU44f37612015-11-25 16:23:22 -080070 ExecutorService executor) {
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070071 this.adminService = checkNotNull(adminService);
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080072 this.deviceService = checkNotNull(deviceService);
Sho SHIMIZU44f37612015-11-25 16:23:22 -080073 this.driverService = checkNotNull(driverService);
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070074 this.executor = checkNotNull(executor);
75 }
76
77 @Override
78 public void event(DeviceEvent event) {
79 Device device = event.subject();
80 switch (event.type()) {
81 case DEVICE_ADDED:
82 registerDeviceResource(device);
83 break;
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -070084 case DEVICE_REMOVED:
85 unregisterDeviceResource(device);
86 break;
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080087 case DEVICE_AVAILABILITY_CHANGED:
88 if (deviceService.isAvailable(device.id())) {
89 registerDeviceResource(device);
90 // TODO: do we need to walk the ports?
91 } else {
92 unregisterDeviceResource(device);
93 }
94 break;
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -070095 case PORT_ADDED:
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080096 case PORT_UPDATED:
97 if (event.port().isEnabled()) {
98 registerPortResource(device, event.port());
99 } else {
100 unregisterPortResource(device, event.port());
101 }
Sho SHIMIZUc2ddedd2015-08-20 11:54:29 -0700102 break;
Sho SHIMIZUe2292842015-08-20 11:59:23 -0700103 case PORT_REMOVED:
104 unregisterPortResource(device, event.port());
105 break;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700106 default:
107 break;
108 }
109 }
110
111 private void registerDeviceResource(Device device) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800112 executor.submit(() -> adminService.registerResources(ResourcePath.discrete(device.id())));
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700113 }
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -0700114
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -0700115 private void unregisterDeviceResource(Device device) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800116 executor.submit(() -> adminService.unregisterResources(ResourcePath.discrete(device.id())));
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -0700117 }
118
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -0700119 private void registerPortResource(Device device, Port port) {
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200120 ResourcePath portPath = ResourcePath.discrete(device.id(), port.number());
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800121 executor.submit(() -> {
122 adminService.registerResources(portPath);
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200123
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800124 // for VLAN IDs
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800125 Set<VlanId> vlans = queryVlanIds(device.id(), port.number());
126 if (!vlans.isEmpty()) {
127 adminService.registerResources(vlans.stream()
128 .map(portPath::child)
129 .collect(Collectors.toList()));
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800130 }
131
132 // for MPLS labels
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800133 Set<MplsLabel> mplsLabels = queryMplsLabels(device.id(), port.number());
134 if (!mplsLabels.isEmpty()) {
135 adminService.registerResources(mplsLabels.stream()
136 .map(portPath::child)
137 .collect(Collectors.toList()));
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800138 }
139
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800140 // for Lambdas
Marc De Leenheer622861d2015-12-15 22:52:52 -0800141 Set<OchSignal> lambdas = queryLambdas(device.id(), port.number());
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800142 if (!lambdas.isEmpty()) {
143 adminService.registerResources(lambdas.stream()
144 .map(portPath::child)
145 .collect(Collectors.toList()));
146 }
147
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800148 // for Tributary slots
Toru Furusawac23f5832015-12-04 11:39:18 -0800149 Set<TributarySlot> tSlots = queryTributarySlots(device.id(), port.number());
150 if (!tSlots.isEmpty()) {
151 adminService.registerResources(tSlots.stream()
152 .map(portPath::child)
153 .collect(Collectors.toList()));
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800154 }
155 });
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200156 }
157
Sho SHIMIZUe2292842015-08-20 11:59:23 -0700158 private void unregisterPortResource(Device device, Port port) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800159 ResourcePath resource = ResourcePath.discrete(device.id(), port.number());
160 executor.submit(() -> adminService.unregisterResources(resource));
Sho SHIMIZUe2292842015-08-20 11:59:23 -0700161 }
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200162
Marc De Leenheer622861d2015-12-15 22:52:52 -0800163 private Set<OchSignal> queryLambdas(DeviceId did, PortNumber port) {
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800164 try {
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800165 // DriverHandler does not provide a way to check if a
166 // behaviour is supported.
167 Driver driver = driverService.getDriver(did);
168 if (driver == null || !driver.hasBehaviour(LambdaQuery.class)) {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800169 return Collections.emptySet();
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800170 }
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800171 DriverHandler handler = driverService.createHandler(did);
172 if (handler == null) {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800173 return Collections.emptySet();
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800174 }
175 LambdaQuery query = handler.behaviour(LambdaQuery.class);
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800176 if (query != null) {
Marc De Leenheer2c305302015-12-07 21:37:44 -0800177 return query.queryLambdas(port).stream()
178 .flatMap(x -> OchSignal.toFlexGrid(x).stream())
Marc De Leenheer622861d2015-12-15 22:52:52 -0800179 .collect(Collectors.toSet());
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800180 } else {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800181 return Collections.emptySet();
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800182 }
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800183 } catch (ItemNotFoundException e) {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800184 return Collections.emptySet();
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800185 }
186 }
187
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800188 private Set<VlanId> queryVlanIds(DeviceId device, PortNumber port) {
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800189 try {
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800190 // DriverHandler does not provide a way to check if a
191 // behaviour is supported.
192 Driver driver = driverService.getDriver(device);
193 if (driver == null || !driver.hasBehaviour(VlanQuery.class)) {
194 // device does not support this
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800195 return ImmutableSet.of();
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800196 }
197
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800198 DriverHandler handler = driverService.createHandler(device);
199 if (handler == null) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800200 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800201 }
202
203 VlanQuery query = handler.behaviour(VlanQuery.class);
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800204 if (query == null) {
205 return ImmutableSet.of();
206 }
207 return query.queryVlanIds(port);
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800208 } catch (ItemNotFoundException e) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800209 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800210 }
211 }
212
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800213 private Set<MplsLabel> queryMplsLabels(DeviceId device, PortNumber port) {
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800214 try {
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800215 // DriverHandler does not provide a way to check if a
216 // behaviour is supported.
217 Driver driver = driverService.getDriver(device);
218 if (driver == null || !driver.hasBehaviour(MplsQuery.class)) {
219 // device does not support this
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800220 return ImmutableSet.of();
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800221 }
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800222 DriverHandler handler = driverService.createHandler(device);
223 if (handler == null) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800224 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800225 }
226
227 MplsQuery query = handler.behaviour(MplsQuery.class);
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800228 if (query == null) {
229 return ImmutableSet.of();
230 }
231 return query.queryMplsLabels(port);
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800232 } catch (ItemNotFoundException e) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800233 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800234 }
235 }
236
Toru Furusawac23f5832015-12-04 11:39:18 -0800237 private Set<TributarySlot> queryTributarySlots(DeviceId device, PortNumber port) {
238 try {
239 // DriverHandler does not provide a way to check if a
240 // behaviour is supported.
241 Driver driver = driverService.getDriver(device);
242 if (driver == null || !driver.hasBehaviour(TributarySlotQuery.class)) {
243 return Collections.emptySet();
244 }
245 DriverHandler handler = driverService.createHandler(device);
246 if (handler == null) {
247 return Collections.emptySet();
248 }
249 TributarySlotQuery query = handler.behaviour(TributarySlotQuery.class);
250 if (query != null) {
251 return query.queryTributarySlots(port);
252 } else {
253 return Collections.emptySet();
254 }
255 } catch (ItemNotFoundException e) {
256 return Collections.emptySet();
257 }
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200258 }
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700259}