blob: bfc6a9955302bd6551c25720c5c82fc14334b3db [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
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -080018import com.google.common.collect.Lists;
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;
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -070024import org.onosproject.net.Port;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020025import org.onosproject.net.OchPort;
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080026import org.onosproject.net.OchSignal;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080027import org.onosproject.net.PortNumber;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020028import org.onosproject.net.TributarySlot;
29import org.onosproject.net.OduSignalType;
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080030import org.onosproject.net.behaviour.LambdaQuery;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080031import org.onosproject.net.behaviour.MplsQuery;
32import org.onosproject.net.behaviour.VlanQuery;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070033import org.onosproject.net.device.DeviceEvent;
34import org.onosproject.net.device.DeviceListener;
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;
38import org.onosproject.net.newresource.ResourcePath;
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;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020043import java.util.List;
HIGUCHI Yutad39e3762015-12-04 09:43:16 -080044import java.util.SortedSet;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070045import java.util.concurrent.ExecutorService;
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020046import java.util.stream.Collectors;
47import java.util.stream.IntStream;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070048
49import static com.google.common.base.Preconditions.checkNotNull;
50
51/**
52 * An implementation of DeviceListener registering devices as resources.
53 */
54final class ResourceDeviceListener implements DeviceListener {
55
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020056 private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
57
Sho SHIMIZU44f37612015-11-25 16:23:22 -080058 private static final int MAX_VLAN_ID = VlanId.MAX_VLAN;
59 private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
60
61 private static final int MAX_MPLS_LABEL = 1048576;
62 private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
63
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +020064 private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8;
65 private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80;
66 private static final List<TributarySlot> ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots();
67 private static final List<TributarySlot> ENTIRE_ODU4_TRIBUTARY_SLOTS = getEntireOdu4TributarySlots();
68
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070069 private final ResourceAdminService adminService;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080070 private final DriverService driverService;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070071 private final ExecutorService executor;
72
73 /**
74 * Creates an instance with the specified ResourceAdminService and ExecutorService.
75 *
76 * @param adminService instance invoked to register resources
77 * @param executor executor used for processing resource registration
78 */
Sho SHIMIZU44f37612015-11-25 16:23:22 -080079 ResourceDeviceListener(ResourceAdminService adminService, DriverService driverService,
80 ExecutorService executor) {
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070081 this.adminService = checkNotNull(adminService);
Sho SHIMIZU44f37612015-11-25 16:23:22 -080082 this.driverService = checkNotNull(driverService);
Sho SHIMIZUd97a9502015-08-18 10:02:30 -070083 this.executor = checkNotNull(executor);
84 }
85
86 @Override
87 public void event(DeviceEvent event) {
88 Device device = event.subject();
89 switch (event.type()) {
90 case DEVICE_ADDED:
91 registerDeviceResource(device);
92 break;
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -070093 case DEVICE_REMOVED:
94 unregisterDeviceResource(device);
95 break;
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -070096 case PORT_ADDED:
97 registerPortResource(device, event.port());
Sho SHIMIZUc2ddedd2015-08-20 11:54:29 -070098 break;
Sho SHIMIZUe2292842015-08-20 11:59:23 -070099 case PORT_REMOVED:
100 unregisterPortResource(device, event.port());
101 break;
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700102 default:
103 break;
104 }
105 }
106
107 private void registerDeviceResource(Device device) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800108 executor.submit(() -> adminService.registerResources(ResourcePath.discrete(device.id())));
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700109 }
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -0700110
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -0700111 private void unregisterDeviceResource(Device device) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800112 executor.submit(() -> adminService.unregisterResources(ResourcePath.discrete(device.id())));
Sho SHIMIZUe60a5ab2015-08-20 11:51:49 -0700113 }
114
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -0700115 private void registerPortResource(Device device, Port port) {
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200116 ResourcePath portPath = ResourcePath.discrete(device.id(), port.number());
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800117 executor.submit(() -> {
118 adminService.registerResources(portPath);
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200119
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800120 // for VLAN IDs
121 if (isVlanEnabled(device.id(), port.number())) {
122 adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, portPath::child));
123 }
124
125 // for MPLS labels
126 if (isMplsEnabled(device.id(), port.number())) {
127 adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, portPath::child));
128 }
129
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800130 // for Lambdas
131 SortedSet<OchSignal> lambdas = queryLambdas(device.id(), port.number());
132 if (!lambdas.isEmpty()) {
133 adminService.registerResources(lambdas.stream()
134 .map(portPath::child)
135 .collect(Collectors.toList()));
136 }
137
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800138 // for Tributary slots
139 // TODO: need to define Behaviour to make a query about OCh port
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800140 switch (port.type()) {
141 case OCH:
142 // register ODU TributarySlots against the OCH port
143 registerTributarySlotsResources(((OchPort) port).signalType(), portPath);
144 break;
145 default:
146 break;
147 }
148 });
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200149 }
150
151 private void registerTributarySlotsResources(OduSignalType oduSignalType, ResourcePath portPath) {
152 switch (oduSignalType) {
153 case ODU2:
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800154 adminService.registerResources(Lists.transform(ENTIRE_ODU2_TRIBUTARY_SLOTS, portPath::child));
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200155 break;
156 case ODU4:
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800157 adminService.registerResources(Lists.transform(ENTIRE_ODU4_TRIBUTARY_SLOTS, portPath::child));
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200158 break;
159 default:
160 break;
161 }
Sho SHIMIZU08fdbd22015-08-19 16:59:35 -0700162 }
Sho SHIMIZUe2292842015-08-20 11:59:23 -0700163
164 private void unregisterPortResource(Device device, Port port) {
Sho SHIMIZU2c7cecf2015-11-11 14:16:14 -0800165 ResourcePath resource = ResourcePath.discrete(device.id(), port.number());
166 executor.submit(() -> adminService.unregisterResources(resource));
Sho SHIMIZUe2292842015-08-20 11:59:23 -0700167 }
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200168
HIGUCHI Yutad39e3762015-12-04 09:43:16 -0800169 private SortedSet<OchSignal> queryLambdas(DeviceId did, PortNumber port) {
170 try {
171 DriverHandler handler = driverService.createHandler(did);
172 if (handler == null) {
173 return Collections.emptySortedSet();
174 }
175 LambdaQuery query = handler.behaviour(LambdaQuery.class);
176 return query.queryLambdas(port);
177 } catch (ItemNotFoundException e) {
178 return Collections.emptySortedSet();
179 }
180 }
181
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800182 private boolean isVlanEnabled(DeviceId device, PortNumber port) {
183 try {
184 DriverHandler handler = driverService.createHandler(device);
185 if (handler == null) {
186 return false;
187 }
188
189 VlanQuery query = handler.behaviour(VlanQuery.class);
190 return query != null && query.isEnabled(port);
191 } catch (ItemNotFoundException e) {
192 return false;
193 }
194 }
195
196 private boolean isMplsEnabled(DeviceId device, PortNumber port) {
197 try {
198 DriverHandler handler = driverService.createHandler(device);
199 if (handler == null) {
200 return false;
201 }
202
203 MplsQuery query = handler.behaviour(MplsQuery.class);
204 return query != null && query.isEnabled(port);
205 } catch (ItemNotFoundException e) {
206 return false;
207 }
208 }
209
210 private static List<VlanId> getEntireVlans() {
211 return IntStream.range(0, MAX_VLAN_ID)
212 .mapToObj(x -> VlanId.vlanId((short) x))
213 .collect(Collectors.toList());
214 }
215
216 private static List<MplsLabel> getEntireMplsLabels() {
217 // potentially many objects are created
218 return IntStream.range(0, MAX_MPLS_LABEL)
219 .mapToObj(MplsLabel::mplsLabel)
220 .collect(Collectors.toList());
221 }
222
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200223 private static List<TributarySlot> getEntireOdu2TributarySlots() {
224 return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS)
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800225 .mapToObj(TributarySlot::of)
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200226 .collect(Collectors.toList());
227 }
228 private static List<TributarySlot> getEntireOdu4TributarySlots() {
229 return IntStream.rangeClosed(1, TOTAL_ODU4_TRIBUTARY_SLOTS)
Sho SHIMIZU44f37612015-11-25 16:23:22 -0800230 .mapToObj(TributarySlot::of)
Rimon Ashkenazye2410ff2015-11-10 14:11:08 +0200231 .collect(Collectors.toList());
232 }
Sho SHIMIZUd97a9502015-08-18 10:02:30 -0700233}