blob: b72e693bbaaa9d834943cba8a4965df6f5aa5c89 [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;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080035import org.onosproject.net.driver.DriverHandler;
36import org.onosproject.net.driver.DriverService;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070037import org.onosproject.net.newresource.ResourceAdminService;
Sho SHIMIZU8fa670a2016-01-14 11:17:18 -080038import org.onosproject.net.newresource.Resource;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070041
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080042import java.util.Collections;
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -080043import java.util.Set;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070044import java.util.concurrent.ExecutorService;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020045import java.util.stream.Collectors;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070046
47import static com.google.common.base.Preconditions.checkNotNull;
48
49/**
50 * An implementation of DeviceListener registering devices as resources.
51 */
52final class ResourceDeviceListener implements DeviceListener {
53
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020054 private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
55
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070056 private final ResourceAdminService adminService;
HIGUCHI Yuta11d16092015-12-04 23:35:43 -080057 private final DeviceService deviceService;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080058 private final DriverService driverService;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070059 private final ExecutorService executor;
60
61 /**
62 * Creates an instance with the specified ResourceAdminService and ExecutorService.
63 *
64 * @param adminService instance invoked to register resources
Jian Lidfba7392016-01-22 16:46:58 -080065 * @param deviceService {@link DeviceService} to be used
66 * @param driverService {@link DriverService} 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 SHIMIZU8fa670a2016-01-14 11:17:18 -0800112 executor.submit(() -> adminService.registerResources(Resource.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 SHIMIZU8fa670a2016-01-14 11:17:18 -0800116 executor.submit(() -> adminService.unregisterResources(Resource.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) {
Sho SHIMIZU8fa670a2016-01-14 11:17:18 -0800120 Resource portPath = Resource.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 SHIMIZU8fa670a2016-01-14 11:17:18 -0800159 Resource resource = Resource.discrete(device.id(), port.number());
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800160 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 {
165 DriverHandler handler = driverService.createHandler(did);
HIGUCHI Yuta82b3c112016-01-07 22:22:26 -0800166 if (handler == null || !handler.hasBehaviour(LambdaQuery.class)) {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800167 return Collections.emptySet();
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800168 }
169 LambdaQuery query = handler.behaviour(LambdaQuery.class);
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800170 if (query != null) {
Marc De Leenheer2c305302015-12-07 21:37:44 -0800171 return query.queryLambdas(port).stream()
172 .flatMap(x -> OchSignal.toFlexGrid(x).stream())
Marc De Leenheer622861d2015-12-15 22:52:52 -0800173 .collect(Collectors.toSet());
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800174 } else {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800175 return Collections.emptySet();
HIGUCHI Yuta11d16092015-12-04 23:35:43 -0800176 }
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800177 } catch (ItemNotFoundException e) {
Marc De Leenheer622861d2015-12-15 22:52:52 -0800178 return Collections.emptySet();
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800179 }
180 }
181
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800182 private Set<VlanId> queryVlanIds(DeviceId device, PortNumber port) {
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800183 try {
184 DriverHandler handler = driverService.createHandler(device);
HIGUCHI Yuta82b3c112016-01-07 22:22:26 -0800185 if (handler == null || !handler.hasBehaviour(VlanQuery.class)) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800186 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800187 }
188
189 VlanQuery query = handler.behaviour(VlanQuery.class);
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800190 if (query == null) {
191 return ImmutableSet.of();
192 }
193 return query.queryVlanIds(port);
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800194 } catch (ItemNotFoundException e) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800195 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800196 }
197 }
198
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800199 private Set<MplsLabel> queryMplsLabels(DeviceId device, PortNumber port) {
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800200 try {
201 DriverHandler handler = driverService.createHandler(device);
HIGUCHI Yuta82b3c112016-01-07 22:22:26 -0800202 if (handler == null || !handler.hasBehaviour(MplsQuery.class)) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800203 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800204 }
205
206 MplsQuery query = handler.behaviour(MplsQuery.class);
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800207 if (query == null) {
208 return ImmutableSet.of();
209 }
210 return query.queryMplsLabels(port);
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800211 } catch (ItemNotFoundException e) {
HIGUCHI Yutab7a15d72015-12-15 09:54:40 -0800212 return ImmutableSet.of();
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800213 }
214 }
215
Toru Furusawac23f5832015-12-04 11:39:18 -0800216 private Set<TributarySlot> queryTributarySlots(DeviceId device, PortNumber port) {
217 try {
Toru Furusawac23f5832015-12-04 11:39:18 -0800218 DriverHandler handler = driverService.createHandler(device);
HIGUCHI Yuta82b3c112016-01-07 22:22:26 -0800219 if (handler == null || !handler.hasBehaviour(TributarySlotQuery.class)) {
Toru Furusawac23f5832015-12-04 11:39:18 -0800220 return Collections.emptySet();
221 }
222 TributarySlotQuery query = handler.behaviour(TributarySlotQuery.class);
223 if (query != null) {
224 return query.queryTributarySlots(port);
225 } else {
226 return Collections.emptySet();
227 }
228 } catch (ItemNotFoundException e) {
229 return Collections.emptySet();
230 }
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200231 }
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700232}