blob: 9d72a6c97dc52df5f559673fdd1b031fe75cbd81 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.optical;
weibitf32383b2014-10-22 10:17:31 -070017
Sho SHIMIZUc87db552015-10-28 15:36:59 -070018import com.google.common.collect.ImmutableList;
weibitf32383b2014-10-22 10:17:31 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
Marc De Leenheer16f857b2015-05-05 20:50:24 -070021import org.apache.felix.scr.annotations.Deactivate;
weibitf32383b2014-10-22 10:17:31 -070022import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080024import org.onosproject.cluster.ClusterService;
25import org.onosproject.cluster.NodeId;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080028import org.onosproject.mastership.MastershipService;
Toru Furusawa72ee30c2016-01-08 13:29:04 -080029import org.onosproject.net.CltSignalType;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.ConnectPoint;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070031import org.onosproject.net.Device;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.Host;
33import org.onosproject.net.Link;
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070034import org.onosproject.net.OchPort;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070035import org.onosproject.net.OduCltPort;
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070036import org.onosproject.net.OduSignalType;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.Path;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070038import org.onosproject.net.Port;
39import org.onosproject.net.device.DeviceService;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.host.HostService;
41import org.onosproject.net.intent.HostToHostIntent;
42import org.onosproject.net.intent.Intent;
43import org.onosproject.net.intent.IntentEvent;
44import org.onosproject.net.intent.IntentListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080045import org.onosproject.net.intent.IntentService;
46import org.onosproject.net.intent.IntentState;
Marc De Leenheer8c2caac2015-05-28 16:37:33 -070047import org.onosproject.net.intent.OpticalCircuitIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.net.intent.OpticalConnectivityIntent;
49import org.onosproject.net.intent.PointToPointIntent;
Sho SHIMIZUc87db552015-10-28 15:36:59 -070050import org.onosproject.net.newresource.ResourceAllocation;
Sho SHIMIZU5c16df82015-09-29 12:52:07 -070051import org.onosproject.net.newresource.ResourceService;
Sho SHIMIZU7d20af12015-10-01 16:03:51 -070052import org.onosproject.net.resource.device.IntentSetMultimap;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.topology.LinkWeight;
54import org.onosproject.net.topology.PathService;
55import org.onosproject.net.topology.TopologyEdge;
weibitf32383b2014-10-22 10:17:31 -070056import org.slf4j.Logger;
57import org.slf4j.LoggerFactory;
58
Sho SHIMIZUc87db552015-10-28 15:36:59 -070059import java.util.Collection;
Marc De Leenheer16f857b2015-05-05 20:50:24 -070060import java.util.Collections;
Brian O'Connor772852a2014-11-17 15:51:19 -080061import java.util.Iterator;
Marc De Leenheer16f857b2015-05-05 20:50:24 -070062import java.util.LinkedList;
Brian O'Connor772852a2014-11-17 15:51:19 -080063import java.util.List;
64import java.util.Set;
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -080065
Marc De Leenheer16f857b2015-05-05 20:50:24 -070066import static com.google.common.base.Preconditions.checkArgument;
Marc De Leenheer16f857b2015-05-05 20:50:24 -070067import static com.google.common.base.Preconditions.checkNotNull;
68
weibitf32383b2014-10-22 10:17:31 -070069/**
Marc De Leenheer16f857b2015-05-05 20:50:24 -070070 * OpticalPathProvisioner listens for event notifications from the Intent F/W.
weibitf32383b2014-10-22 10:17:31 -070071 * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
72 * for adding/releasing capacity at the packet layer.
weibitf32383b2014-10-22 10:17:31 -070073 */
74
75@Component(immediate = true)
76public class OpticalPathProvisioner {
77
78 protected static final Logger log = LoggerFactory
79 .getLogger(OpticalPathProvisioner.class);
80
81 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 private IntentService intentService;
83
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Brian O'Connor772852a2014-11-17 15:51:19 -080085 protected PathService pathService;
weibitf32383b2014-10-22 10:17:31 -070086
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected CoreService coreService;
89
weibit7e583462014-10-23 10:14:05 -070090 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Praseed Balakrishnanc0029652014-11-14 13:38:49 -080091 protected HostService hostService;
92
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -080093 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected MastershipService mastershipService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected ClusterService clusterService;
98
Marc De Leenheer1afa2a02015-05-13 09:18:07 -070099 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700100 protected DeviceService deviceService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sho SHIMIZU7d20af12015-10-01 16:03:51 -0700103 protected IntentSetMultimap intentSetMultimap;
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sho SHIMIZU5c16df82015-09-29 12:52:07 -0700106 protected ResourceService resourceService;
107
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700108 private ApplicationId appId;
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800109
weibitf32383b2014-10-22 10:17:31 -0700110 private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
111
112 @Activate
113 protected void activate() {
114 intentService.addListener(pathProvisioner);
Brian O'Connorabafb502014-12-02 22:26:20 -0800115 appId = coreService.registerApplication("org.onosproject.optical");
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700116 initOpticalPorts();
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700117 log.info("Started");
118 }
119
120 @Deactivate
121 protected void deactivate() {
122 intentService.removeListener(pathProvisioner);
123 log.info("Stopped");
weibitf32383b2014-10-22 10:17:31 -0700124 }
125
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700126 /**
127 * Initialize availability of optical ports.
128 */
129 private void initOpticalPorts() {
130 // TODO: check for existing optical intents
131 return;
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800132 }
133
weibitf32383b2014-10-22 10:17:31 -0700134 public class InternalOpticalPathProvisioner implements IntentListener {
135 @Override
136 public void event(IntentEvent event) {
137 switch (event.type()) {
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800138 case INSTALL_REQ:
weibitf32383b2014-10-22 10:17:31 -0700139 break;
140 case INSTALLED:
141 break;
142 case FAILED:
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700143 log.info("Intent {} failed, calling optical path provisioning app.", event.subject());
Brian O'Connor772852a2014-11-17 15:51:19 -0800144 setupLightpath(event.subject());
weibitf32383b2014-10-22 10:17:31 -0700145 break;
146 case WITHDRAWN:
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700147 log.info("Intent {} withdrawn.", event.subject());
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700148 releaseResources(event.subject());
weibitf32383b2014-10-22 10:17:31 -0700149 break;
150 default:
151 break;
152 }
153 }
154
Brian O'Connor772852a2014-11-17 15:51:19 -0800155 private void setupLightpath(Intent intent) {
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700156 checkNotNull(intent);
157
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800158 // TODO change the coordination approach between packet intents and optical intents
159 // Low speed LLDP may cause multiple calls which are not expected
160
Sho SHIMIZU0a9c9c42015-07-01 15:29:16 -0700161 if (intentService.getIntentState(intent.key()) != IntentState.FAILED) {
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800162 return;
Marc De Leenheerb473b9d2015-02-06 15:21:03 -0800163 }
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800164
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700165 // Get source and destination based on intent type
166 ConnectPoint src;
167 ConnectPoint dst;
Brian O'Connor772852a2014-11-17 15:51:19 -0800168 if (intent instanceof HostToHostIntent) {
169 HostToHostIntent hostToHostIntent = (HostToHostIntent) intent;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800170
Brian O'Connor772852a2014-11-17 15:51:19 -0800171 Host one = hostService.getHost(hostToHostIntent.one());
172 Host two = hostService.getHost(hostToHostIntent.two());
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800173
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700174 checkNotNull(one);
175 checkNotNull(two);
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800176
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700177 src = one.location();
178 dst = two.location();
Brian O'Connor772852a2014-11-17 15:51:19 -0800179 } else if (intent instanceof PointToPointIntent) {
180 PointToPointIntent p2pIntent = (PointToPointIntent) intent;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800181
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700182 src = p2pIntent.ingressPoint();
183 dst = p2pIntent.egressPoint();
Brian O'Connor772852a2014-11-17 15:51:19 -0800184 } else {
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700185 return;
Brian O'Connor772852a2014-11-17 15:51:19 -0800186 }
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800187
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700188 if (src == null || dst == null) {
189 return;
190 }
191
192 // Ignore if we're not the master for the intent's origin device
193 NodeId localNode = clusterService.getLocalNode().id();
194 NodeId sourceMaster = mastershipService.getMasterFor(src.deviceId());
195 if (!localNode.equals(sourceMaster)) {
196 return;
197 }
198
199 // Generate optical connectivity intents
Sho SHIMIZUfb446fe2015-05-21 14:45:23 -0700200 List<Intent> intents = getOpticalIntents(src, dst);
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700201
202 // Submit the intents
Brian O'Connor772852a2014-11-17 15:51:19 -0800203 for (Intent i : intents) {
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700204 intentService.submit(i);
Sho SHIMIZUb5d38412015-05-21 11:12:58 -0700205 log.debug("Submitted an intent: {}", i);
Brian O'Connor772852a2014-11-17 15:51:19 -0800206 }
weibit7e583462014-10-23 10:14:05 -0700207 }
208
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700209 /**
210 * Returns list of cross connection points of missing optical path sections.
211 *
212 * Scans the given multi-layer path and looks for sections that use cross connect links.
213 * The ingress and egress points in the optical layer are returned in a list.
214 *
215 * @param path the multi-layer path
216 * @return list of cross connection points on the optical layer
217 */
218 private List<ConnectPoint> getCrossConnectPoints(Path path) {
219 boolean scanning = false;
Sho SHIMIZU819ee292015-07-01 09:36:21 -0700220 List<ConnectPoint> connectPoints = new LinkedList<>();
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700221
222 for (Link link : path.links()) {
223 if (!isCrossConnectLink(link)) {
224 continue;
225 }
226
227 if (scanning) {
228 connectPoints.add(checkNotNull(link.src()));
229 scanning = false;
230 } else {
231 connectPoints.add(checkNotNull(link.dst()));
232 scanning = true;
233 }
234 }
235
236 return connectPoints;
237 }
238
239 /**
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700240 * Checks if cross connect points are of same type.
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700241 *
242 * @param crossConnectPoints list of cross connection points
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700243 * @return true if cross connect point pairs are of same type, false otherwise
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700244 */
245 private boolean checkCrossConnectPoints(List<ConnectPoint> crossConnectPoints) {
246 checkArgument(crossConnectPoints.size() % 2 == 0);
247
248 Iterator<ConnectPoint> itr = crossConnectPoints.iterator();
249
250 while (itr.hasNext()) {
251 // checkArgument at start ensures we'll always have pairs of connect points
252 ConnectPoint src = itr.next();
253 ConnectPoint dst = itr.next();
254
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700255 Device.Type srcType = deviceService.getDevice(src.deviceId()).type();
256 Device.Type dstType = deviceService.getDevice(dst.deviceId()).type();
257
258 // Only support connections between identical port types
259 if (srcType != dstType) {
260 log.warn("Unsupported mix of cross connect points");
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700261 return false;
262 }
263 }
264
265 return true;
266 }
267
268 /**
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700269 * Scans the list of cross connection points and returns a list of optical connectivity intents.
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700270 *
271 * @param crossConnectPoints list of cross connection points
272 * @return list of optical connectivity intents
273 */
274 private List<Intent> getIntents(List<ConnectPoint> crossConnectPoints) {
275 checkArgument(crossConnectPoints.size() % 2 == 0);
276
Sho SHIMIZU79945e82015-05-20 17:20:47 -0700277 List<Intent> intents = new LinkedList<>();
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700278 Iterator<ConnectPoint> itr = crossConnectPoints.iterator();
279
280 while (itr.hasNext()) {
281 // checkArgument at start ensures we'll always have pairs of connect points
282 ConnectPoint src = itr.next();
283 ConnectPoint dst = itr.next();
284
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700285 Port srcPort = deviceService.getPort(src.deviceId(), src.port());
286 Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700287
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700288 if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) {
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700289 // Create OTN circuit
290 Intent circuitIntent = OpticalCircuitIntent.builder()
291 .appId(appId)
292 .src(src)
293 .dst(dst)
Toru Furusawa72ee30c2016-01-08 13:29:04 -0800294 .signalType(CltSignalType.CLT_10GBE)
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700295 .bidirectional(true)
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700296 .build();
297 intents.add(circuitIntent);
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700298 } else if (srcPort instanceof OchPort && dstPort instanceof OchPort) {
299 // Create lightpath
300 // FIXME: hardcoded ODU signal type
301 Intent opticalIntent = OpticalConnectivityIntent.builder()
302 .appId(appId)
303 .src(src)
304 .dst(dst)
305 .signalType(OduSignalType.ODU4)
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700306 .bidirectional(true)
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700307 .build();
308 intents.add(opticalIntent);
Marc De Leenheer8c2caac2015-05-28 16:37:33 -0700309 } else {
310 log.warn("Unsupported cross connect point types {} {}", srcPort.type(), dstPort.type());
311 return Collections.emptyList();
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700312 }
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700313 }
314
315 return intents;
316 }
317
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700318 /**
319 * Returns list of optical connectivity intents needed to create connectivity
320 * between ingress and egress.
321 *
322 * @param ingress the ingress connect point
323 * @param egress the egress connect point
324 * @return list of optical connectivity intents, empty list if no path was found
325 */
326 private List<Intent> getOpticalIntents(ConnectPoint ingress, ConnectPoint egress) {
Brian O'Connor772852a2014-11-17 15:51:19 -0800327 Set<Path> paths = pathService.getPaths(ingress.deviceId(),
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700328 egress.deviceId(),
329 new OpticalLinkWeight());
Brian O'Connor772852a2014-11-17 15:51:19 -0800330
331 if (paths.isEmpty()) {
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700332 return Collections.emptyList();
weibit7e583462014-10-23 10:14:05 -0700333 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800334
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700335 // Search path with available cross connect points
336 for (Path path : paths) {
337 List<ConnectPoint> crossConnectPoints = getCrossConnectPoints(path);
Brian O'Connor772852a2014-11-17 15:51:19 -0800338
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700339 // Skip to next path if cross connect points are mismatched
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700340 if (!checkCrossConnectPoints(crossConnectPoints)) {
341 continue;
Brian O'Connor772852a2014-11-17 15:51:19 -0800342 }
343
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700344 return getIntents(crossConnectPoints);
Brian O'Connor772852a2014-11-17 15:51:19 -0800345 }
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800346
Marc De Leenheer234fa822015-11-18 18:24:57 -0800347 log.warn("Unable to find multi-layer path.");
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700348 return Collections.emptyList();
Brian O'Connor772852a2014-11-17 15:51:19 -0800349 }
350
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700351 /**
352 * Link weight function that emphasizes re-use of packet links.
353 */
354 private class OpticalLinkWeight implements LinkWeight {
355 @Override
356 public double weight(TopologyEdge edge) {
357 // Ignore inactive links
358 if (edge.link().state() == Link.State.INACTIVE) {
359 return -1;
360 }
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800361
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700362 // TODO: Ignore cross connect links with used ports
363
364 // Transport links have highest weight
365 if (edge.link().type() == Link.Type.OPTICAL) {
366 return 1000;
367 }
368
369 // Packet links
370 return 1;
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800371 }
weibitf32383b2014-10-22 10:17:31 -0700372 }
Brian O'Connorc7bdd8c2014-12-08 01:29:53 -0800373
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700374 /**
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700375 * Release resources associated to the given intent.
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700376 *
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700377 * @param intent the intent
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700378 */
Marc De Leenheer4a1c1fa2015-06-01 18:08:56 -0700379 private void releaseResources(Intent intent) {
Sho SHIMIZUc87db552015-10-28 15:36:59 -0700380 Collection<ResourceAllocation> allocations = resourceService.getResourceAllocations(intent.id());
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700381 if (intent instanceof OpticalConnectivityIntent) {
Sho SHIMIZU5c16df82015-09-29 12:52:07 -0700382 resourceService.release(intent.id());
Sho SHIMIZUc87db552015-10-28 15:36:59 -0700383 if (!allocations.isEmpty()) {
384 resourceService.release(ImmutableList.copyOf(allocations));
Marc De Leenheerc9733082015-06-04 12:22:38 -0700385 }
386 } else if (intent instanceof OpticalCircuitIntent) {
Sho SHIMIZU5c16df82015-09-29 12:52:07 -0700387 resourceService.release(intent.id());
Sho SHIMIZU7d20af12015-10-01 16:03:51 -0700388 intentSetMultimap.releaseMapping(intent.id());
Sho SHIMIZUc87db552015-10-28 15:36:59 -0700389 if (!allocations.isEmpty()) {
390 resourceService.release(ImmutableList.copyOf(allocations));
Ayaka Koshibebcb02372015-06-01 10:56:42 -0700391 }
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700392 }
Marc De Leenheer1afa2a02015-05-13 09:18:07 -0700393 }
Brian O'Connor772852a2014-11-17 15:51:19 -0800394 }
weibitf32383b2014-10-22 10:17:31 -0700395
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700396 /**
Marc De Leenheer234fa822015-11-18 18:24:57 -0800397 * Verifies if given device type is in packet layer, i.e., ROADM, OTN or ROADM_OTN device.
398 *
399 * @param type device type
400 * @return true if in packet layer, false otherwise
401 */
402 private boolean isPacketLayer(Device.Type type) {
Ayaka Koshibe31980ab2016-01-21 00:11:16 -0800403 return type == Device.Type.SWITCH || type == Device.Type.ROUTER || type == Device.Type.VIRTUAL;
Marc De Leenheer234fa822015-11-18 18:24:57 -0800404 }
405
406 /**
407 * Verifies if given device type is in packet layer, i.e., switch or router device.
408 *
409 * @param type device type
410 * @return true if in packet layer, false otherwise
411 */
412 private boolean isTransportLayer(Device.Type type) {
413 return type == Device.Type.ROADM || type == Device.Type.OTN || type == Device.Type.ROADM_OTN;
414 }
415
416 /**
417 * Verifies if given link forms a cross-connection between packet and optical layer.
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700418 *
419 * @param link the link
Marc De Leenheer234fa822015-11-18 18:24:57 -0800420 * @return true if the link is a cross-connect link, false otherwise
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700421 */
Marc De Leenheer234fa822015-11-18 18:24:57 -0800422 private boolean isCrossConnectLink(Link link) {
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700423 if (link.type() != Link.Type.OPTICAL) {
424 return false;
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800425 }
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700426
Marc De Leenheer234fa822015-11-18 18:24:57 -0800427 Device.Type src = deviceService.getDevice(link.src().deviceId()).type();
428 Device.Type dst = deviceService.getDevice(link.dst().deviceId()).type();
Marc De Leenheer16f857b2015-05-05 20:50:24 -0700429
Marc De Leenheer234fa822015-11-18 18:24:57 -0800430 return src != dst &&
431 ((isPacketLayer(src) && isTransportLayer(dst)) || (isPacketLayer(dst) && isTransportLayer(src)));
Brian O'Connor772852a2014-11-17 15:51:19 -0800432 }
Praseed Balakrishnanc0029652014-11-14 13:38:49 -0800433
weibitf32383b2014-10-22 10:17:31 -0700434}