Marc De Leenheer
Committed by Gerrit Code Review

Rewrote optical connectivity intent compiler

Change-Id: I5acece3c14bed8a23f7bbe0c5a9bc0932a2a0881
Showing 21 changed files with 754 additions and 244 deletions
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
45 <groupId>org.apache.karaf.shell</groupId> 45 <groupId>org.apache.karaf.shell</groupId>
46 <artifactId>org.apache.karaf.shell.console</artifactId> 46 <artifactId>org.apache.karaf.shell.console</artifactId>
47 </dependency> 47 </dependency>
48 -
49 <dependency> 48 <dependency>
50 <groupId>org.codehaus.jackson</groupId> 49 <groupId>org.codehaus.jackson</groupId>
51 <artifactId>jackson-core-asl</artifactId> 50 <artifactId>jackson-core-asl</artifactId>
...@@ -59,6 +58,12 @@ ...@@ -59,6 +58,12 @@
59 <artifactId>jackson-annotations</artifactId> 58 <artifactId>jackson-annotations</artifactId>
60 <scope>provided</scope> 59 <scope>provided</scope>
61 </dependency> 60 </dependency>
61 + <dependency>
62 + <groupId>org.onosproject</groupId>
63 + <artifactId>onos-core-serializers</artifactId>
64 + <version>${project.version}</version>
65 + </dependency>
66 +
62 </dependencies> 67 </dependencies>
63 68
64 </project> 69 </project>
......
...@@ -21,15 +21,20 @@ import org.apache.felix.scr.annotations.Component; ...@@ -21,15 +21,20 @@ import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 21 import org.apache.felix.scr.annotations.Deactivate;
22 import org.apache.felix.scr.annotations.Reference; 22 import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality; 23 import org.apache.felix.scr.annotations.ReferenceCardinality;
24 +import org.onlab.util.KryoNamespace;
24 import org.onosproject.cluster.ClusterService; 25 import org.onosproject.cluster.ClusterService;
25 import org.onosproject.cluster.NodeId; 26 import org.onosproject.cluster.NodeId;
26 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
27 import org.onosproject.core.CoreService; 28 import org.onosproject.core.CoreService;
28 import org.onosproject.mastership.MastershipService; 29 import org.onosproject.mastership.MastershipService;
29 import org.onosproject.net.ConnectPoint; 30 import org.onosproject.net.ConnectPoint;
31 +import org.onosproject.net.Device;
30 import org.onosproject.net.Host; 32 import org.onosproject.net.Host;
31 import org.onosproject.net.Link; 33 import org.onosproject.net.Link;
34 +import org.onosproject.net.OduCltPort;
32 import org.onosproject.net.Path; 35 import org.onosproject.net.Path;
36 +import org.onosproject.net.Port;
37 +import org.onosproject.net.device.DeviceService;
33 import org.onosproject.net.host.HostService; 38 import org.onosproject.net.host.HostService;
34 import org.onosproject.net.intent.HostToHostIntent; 39 import org.onosproject.net.intent.HostToHostIntent;
35 import org.onosproject.net.intent.Intent; 40 import org.onosproject.net.intent.Intent;
...@@ -39,9 +44,15 @@ import org.onosproject.net.intent.IntentService; ...@@ -39,9 +44,15 @@ import org.onosproject.net.intent.IntentService;
39 import org.onosproject.net.intent.IntentState; 44 import org.onosproject.net.intent.IntentState;
40 import org.onosproject.net.intent.OpticalConnectivityIntent; 45 import org.onosproject.net.intent.OpticalConnectivityIntent;
41 import org.onosproject.net.intent.PointToPointIntent; 46 import org.onosproject.net.intent.PointToPointIntent;
47 +import org.onosproject.net.resource.DeviceResourceService;
48 +import org.onosproject.net.resource.LinkResourceService;
42 import org.onosproject.net.topology.LinkWeight; 49 import org.onosproject.net.topology.LinkWeight;
43 import org.onosproject.net.topology.PathService; 50 import org.onosproject.net.topology.PathService;
44 import org.onosproject.net.topology.TopologyEdge; 51 import org.onosproject.net.topology.TopologyEdge;
52 +import org.onosproject.net.topology.TopologyService;
53 +import org.onosproject.store.serializers.KryoNamespaces;
54 +import org.onosproject.store.service.Serializer;
55 +import org.onosproject.store.service.StorageService;
45 import org.slf4j.Logger; 56 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory; 57 import org.slf4j.LoggerFactory;
47 58
...@@ -54,7 +65,6 @@ import java.util.Set; ...@@ -54,7 +65,6 @@ import java.util.Set;
54 import java.util.concurrent.ConcurrentHashMap; 65 import java.util.concurrent.ConcurrentHashMap;
55 66
56 import static com.google.common.base.Preconditions.checkArgument; 67 import static com.google.common.base.Preconditions.checkArgument;
57 -import static org.onosproject.net.intent.IntentState.INSTALLED;
58 68
59 import static com.google.common.base.Preconditions.checkNotNull; 69 import static com.google.common.base.Preconditions.checkNotNull;
60 70
...@@ -70,6 +80,9 @@ public class OpticalPathProvisioner { ...@@ -70,6 +80,9 @@ public class OpticalPathProvisioner {
70 protected static final Logger log = LoggerFactory 80 protected static final Logger log = LoggerFactory
71 .getLogger(OpticalPathProvisioner.class); 81 .getLogger(OpticalPathProvisioner.class);
72 82
83 + private static final Serializer SERIALIZER = Serializer.using(
84 + new KryoNamespace.Builder().register(KryoNamespaces.API).build());
85 +
73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 private IntentService intentService; 87 private IntentService intentService;
75 88
...@@ -77,6 +90,9 @@ public class OpticalPathProvisioner { ...@@ -77,6 +90,9 @@ public class OpticalPathProvisioner {
77 protected PathService pathService; 90 protected PathService pathService;
78 91
79 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 + protected TopologyService topologyService;
94 +
95 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 protected CoreService coreService; 96 protected CoreService coreService;
81 97
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -88,13 +104,19 @@ public class OpticalPathProvisioner { ...@@ -88,13 +104,19 @@ public class OpticalPathProvisioner {
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected ClusterService clusterService; 105 protected ClusterService clusterService;
90 106
91 - private ApplicationId appId; 107 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 + protected StorageService storageService;
92 109
93 - // TODO use a shared map for distributed operation 110 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 - private final Map<ConnectPoint, OpticalConnectivityIntent> inStatusTportMap = 111 + protected DeviceService deviceService;
95 - new ConcurrentHashMap<>(); 112 +
96 - private final Map<ConnectPoint, OpticalConnectivityIntent> outStatusTportMap = 113 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 - new ConcurrentHashMap<>(); 114 + protected DeviceResourceService deviceResourceService;
115 +
116 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 + protected LinkResourceService linkResourceService;
118 +
119 + private ApplicationId appId;
98 120
99 private final Map<ConnectPoint, Map<ConnectPoint, Intent>> intentMap = 121 private final Map<ConnectPoint, Map<ConnectPoint, Intent>> intentMap =
100 new ConcurrentHashMap<>(); 122 new ConcurrentHashMap<>();
...@@ -105,7 +127,7 @@ public class OpticalPathProvisioner { ...@@ -105,7 +127,7 @@ public class OpticalPathProvisioner {
105 protected void activate() { 127 protected void activate() {
106 intentService.addListener(pathProvisioner); 128 intentService.addListener(pathProvisioner);
107 appId = coreService.registerApplication("org.onosproject.optical"); 129 appId = coreService.registerApplication("org.onosproject.optical");
108 - initTport(); 130 + initOpticalPorts();
109 log.info("Started"); 131 log.info("Started");
110 } 132 }
111 133
...@@ -115,19 +137,12 @@ public class OpticalPathProvisioner { ...@@ -115,19 +137,12 @@ public class OpticalPathProvisioner {
115 log.info("Stopped"); 137 log.info("Stopped");
116 } 138 }
117 139
118 - protected void initTport() { 140 + /**
119 - inStatusTportMap.clear(); 141 + * Initialize availability of optical ports.
120 - outStatusTportMap.clear(); 142 + */
121 - for (Intent intent : intentService.getIntents()) { 143 + private void initOpticalPorts() {
122 - if (intentService.getIntentState(intent.key()) == INSTALLED) { 144 + // TODO: check for existing optical intents
123 - if (intent instanceof OpticalConnectivityIntent) { 145 + return;
124 - inStatusTportMap.put(((OpticalConnectivityIntent) intent).getSrc(),
125 - (OpticalConnectivityIntent) intent);
126 - outStatusTportMap.put(((OpticalConnectivityIntent) intent).getDst(),
127 - (OpticalConnectivityIntent) intent);
128 - }
129 - }
130 - }
131 } 146 }
132 147
133 public class InternalOpticalPathProvisioner implements IntentListener { 148 public class InternalOpticalPathProvisioner implements IntentListener {
...@@ -137,6 +152,7 @@ public class OpticalPathProvisioner { ...@@ -137,6 +152,7 @@ public class OpticalPathProvisioner {
137 case INSTALL_REQ: 152 case INSTALL_REQ:
138 break; 153 break;
139 case INSTALLED: 154 case INSTALLED:
155 + // track h2h & p2p intents using our connectivity
140 break; 156 break;
141 case FAILED: 157 case FAILED:
142 log.info("Intent {} failed, calling optical path provisioning app.", event.subject()); 158 log.info("Intent {} failed, calling optical path provisioning app.", event.subject());
...@@ -144,29 +160,13 @@ public class OpticalPathProvisioner { ...@@ -144,29 +160,13 @@ public class OpticalPathProvisioner {
144 break; 160 break;
145 case WITHDRAWN: 161 case WITHDRAWN:
146 log.info("Intent {} withdrawn.", event.subject()); 162 log.info("Intent {} withdrawn.", event.subject());
147 - //FIXME 163 + withdrawIntent(event.subject());
148 - //teardownLightpath(event.subject());
149 break; 164 break;
150 default: 165 default:
151 break; 166 break;
152 } 167 }
153 } 168 }
154 169
155 - private void reserveTport(Intent intent) {
156 - // TODO move to resourceManager
157 - if (intent instanceof OpticalConnectivityIntent) {
158 - OpticalConnectivityIntent opticalIntent =
159 - (OpticalConnectivityIntent) intent;
160 - if (inStatusTportMap.containsKey(opticalIntent.getSrc()) ||
161 - outStatusTportMap.containsKey(opticalIntent.getDst())) {
162 - //TODO throw an exception, perhaps
163 - log.warn("Overlapping reservation: {}", opticalIntent);
164 - }
165 - inStatusTportMap.put(opticalIntent.getSrc(), opticalIntent);
166 - outStatusTportMap.put(opticalIntent.getDst(), opticalIntent);
167 - }
168 - }
169 -
170 /** 170 /**
171 * Registers an intent from src to dst. 171 * Registers an intent from src to dst.
172 * 172 *
...@@ -190,6 +190,8 @@ public class OpticalPathProvisioner { ...@@ -190,6 +190,8 @@ public class OpticalPathProvisioner {
190 } 190 }
191 191
192 private void setupLightpath(Intent intent) { 192 private void setupLightpath(Intent intent) {
193 + checkNotNull(intent);
194 +
193 // TODO change the coordination approach between packet intents and optical intents 195 // TODO change the coordination approach between packet intents and optical intents
194 // Low speed LLDP may cause multiple calls which are not expected 196 // Low speed LLDP may cause multiple calls which are not expected
195 197
...@@ -197,56 +199,48 @@ public class OpticalPathProvisioner { ...@@ -197,56 +199,48 @@ public class OpticalPathProvisioner {
197 return; 199 return;
198 } 200 }
199 201
200 - NodeId localNode = clusterService.getLocalNode().id(); 202 + // Get source and destination based on intent type
201 - 203 + ConnectPoint src;
202 - List<Intent> intents = Lists.newArrayList(); 204 + ConnectPoint dst;
203 if (intent instanceof HostToHostIntent) { 205 if (intent instanceof HostToHostIntent) {
204 HostToHostIntent hostToHostIntent = (HostToHostIntent) intent; 206 HostToHostIntent hostToHostIntent = (HostToHostIntent) intent;
205 207
206 Host one = hostService.getHost(hostToHostIntent.one()); 208 Host one = hostService.getHost(hostToHostIntent.one());
207 Host two = hostService.getHost(hostToHostIntent.two()); 209 Host two = hostService.getHost(hostToHostIntent.two());
208 - if (one == null || two == null) {
209 - return; //FIXME
210 - }
211 210
212 - // Ignore if we're not the master for the intent's origin device 211 + checkNotNull(one);
213 - NodeId sourceMaster = mastershipService.getMasterFor(one.location().deviceId()); 212 + checkNotNull(two);
214 - if (!localNode.equals(sourceMaster)) {
215 - return;
216 - }
217 213
218 - // provision both directions 214 + src = one.location();
219 - intents.addAll(getOpticalPath(one.location(), two.location())); 215 + dst = two.location();
220 - // note: bi-directional intent is set up
221 - // HostToHost Intent requires symmetric path!
222 - //intents.addAll(getOpticalPath(two.location(), one.location()));
223 } else if (intent instanceof PointToPointIntent) { 216 } else if (intent instanceof PointToPointIntent) {
224 PointToPointIntent p2pIntent = (PointToPointIntent) intent; 217 PointToPointIntent p2pIntent = (PointToPointIntent) intent;
225 218
226 - // Ignore if we're not the master for the intent's origin device 219 + src = p2pIntent.ingressPoint();
227 - NodeId sourceMaster = mastershipService.getMasterFor(p2pIntent.ingressPoint().deviceId()); 220 + dst = p2pIntent.egressPoint();
228 - if (!localNode.equals(sourceMaster)) {
229 - return;
230 - }
231 -
232 - intents.addAll(getOpticalPath(p2pIntent.ingressPoint(), p2pIntent.egressPoint()));
233 } else { 221 } else {
234 - log.info("Unsupported intent type: {}", intent.getClass()); 222 + log.error("Unsupported intent type: {}", intent.getClass());
223 + return;
235 } 224 }
236 225
237 - // Create the intents 226 + if (src == null || dst == null) {
227 + return;
228 + }
229 +
230 + // Ignore if we're not the master for the intent's origin device
231 + NodeId localNode = clusterService.getLocalNode().id();
232 + NodeId sourceMaster = mastershipService.getMasterFor(src.deviceId());
233 + if (!localNode.equals(sourceMaster)) {
234 + return;
235 + }
236 +
237 + // Generate optical connectivity intents
238 + List<Intent> intents = Lists.newArrayList();
239 + intents.addAll(getOpticalIntents(src, dst));
240 +
241 + // Submit the intents
238 for (Intent i : intents) { 242 for (Intent i : intents) {
239 - // TODO: don't allow duplicate intents between the same points for now 243 + intentService.submit(i);
240 - // we may want to allow this carefully in future to increase capacity
241 - if (i instanceof OpticalConnectivityIntent) {
242 - OpticalConnectivityIntent oi = (OpticalConnectivityIntent) i;
243 - if (addIntent(oi.getSrc(), oi.getDst(), oi)) {
244 - intentService.submit(i);
245 - reserveTport(i);
246 - }
247 - } else {
248 - log.warn("Invalid intent type: {} for {}", i.getClass(), i);
249 - }
250 } 244 }
251 } 245 }
252 246
...@@ -281,11 +275,10 @@ public class OpticalPathProvisioner { ...@@ -281,11 +275,10 @@ public class OpticalPathProvisioner {
281 } 275 }
282 276
283 /** 277 /**
284 - * Checks availability of cross connect points by verifying T port status. 278 + * Checks if cross connect points are of same type.
285 - * TODO: refactor after rewriting OpticalConnectivityIntentCompiler
286 * 279 *
287 * @param crossConnectPoints list of cross connection points 280 * @param crossConnectPoints list of cross connection points
288 - * @return true if all cross connect points are available, false otherwise 281 + * @return true if cross connect point pairs are of same type, false otherwise
289 */ 282 */
290 private boolean checkCrossConnectPoints(List<ConnectPoint> crossConnectPoints) { 283 private boolean checkCrossConnectPoints(List<ConnectPoint> crossConnectPoints) {
291 checkArgument(crossConnectPoints.size() % 2 == 0); 284 checkArgument(crossConnectPoints.size() % 2 == 0);
...@@ -297,7 +290,12 @@ public class OpticalPathProvisioner { ...@@ -297,7 +290,12 @@ public class OpticalPathProvisioner {
297 ConnectPoint src = itr.next(); 290 ConnectPoint src = itr.next();
298 ConnectPoint dst = itr.next(); 291 ConnectPoint dst = itr.next();
299 292
300 - if (inStatusTportMap.get(src) != null || outStatusTportMap.get(dst) != null) { 293 + Device.Type srcType = deviceService.getDevice(src.deviceId()).type();
294 + Device.Type dstType = deviceService.getDevice(dst.deviceId()).type();
295 +
296 + // Only support connections between identical port types
297 + if (srcType != dstType) {
298 + log.warn("Unsupported mix of cross connect points");
301 return false; 299 return false;
302 } 300 }
303 } 301 }
...@@ -306,8 +304,7 @@ public class OpticalPathProvisioner { ...@@ -306,8 +304,7 @@ public class OpticalPathProvisioner {
306 } 304 }
307 305
308 /** 306 /**
309 - * Scans the list of cross connection points and returns a list of optical connectivity intents 307 + * Scans the list of cross connection points and returns a list of optical connectivity intents.
310 - * in both directions.
311 * 308 *
312 * @param crossConnectPoints list of cross connection points 309 * @param crossConnectPoints list of cross connection points
313 * @return list of optical connectivity intents 310 * @return list of optical connectivity intents
...@@ -323,25 +320,34 @@ public class OpticalPathProvisioner { ...@@ -323,25 +320,34 @@ public class OpticalPathProvisioner {
323 ConnectPoint src = itr.next(); 320 ConnectPoint src = itr.next();
324 ConnectPoint dst = itr.next(); 321 ConnectPoint dst = itr.next();
325 322
326 - // TODO: should have option for bidirectional OpticalConnectivityIntent 323 + Port srcPort = deviceService.getPort(src.deviceId(), src.port());
324 + Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
325 + // Create lightpath
326 + // TODO: Ensure src & dst are of type OchPort
327 Intent opticalIntent = OpticalConnectivityIntent.builder() 327 Intent opticalIntent = OpticalConnectivityIntent.builder()
328 .appId(appId) 328 .appId(appId)
329 .src(src) 329 .src(src)
330 .dst(dst) 330 .dst(dst)
331 .build(); 331 .build();
332 - Intent opticalIntentRev = OpticalConnectivityIntent.builder()
333 - .appId(appId)
334 - .src(dst)
335 - .dst(src)
336 - .build();
337 intents.add(opticalIntent); 332 intents.add(opticalIntent);
338 - intents.add(opticalIntentRev); 333 + if (srcPort instanceof OduCltPort && dstPort instanceof OduCltPort) {
334 + continue;
335 + // also create OTN service
336 + }
339 } 337 }
340 338
341 return intents; 339 return intents;
342 } 340 }
343 341
344 - private List<Intent> getOpticalPath(ConnectPoint ingress, ConnectPoint egress) { 342 + /**
343 + * Returns list of optical connectivity intents needed to create connectivity
344 + * between ingress and egress.
345 + *
346 + * @param ingress the ingress connect point
347 + * @param egress the egress connect point
348 + * @return list of optical connectivity intents, empty list if no path was found
349 + */
350 + private List<Intent> getOpticalIntents(ConnectPoint ingress, ConnectPoint egress) {
345 Set<Path> paths = pathService.getPaths(ingress.deviceId(), 351 Set<Path> paths = pathService.getPaths(ingress.deviceId(),
346 egress.deviceId(), 352 egress.deviceId(),
347 new OpticalLinkWeight()); 353 new OpticalLinkWeight());
...@@ -350,16 +356,11 @@ public class OpticalPathProvisioner { ...@@ -350,16 +356,11 @@ public class OpticalPathProvisioner {
350 return Collections.emptyList(); 356 return Collections.emptyList();
351 } 357 }
352 358
353 - List<Intent> connectionList = Lists.newArrayList(); 359 + // Search path with available cross connect points
354 - 360 + for (Path path : paths) {
355 - // Iterate over all paths until a suitable one has been found 361 + List<ConnectPoint> crossConnectPoints = getCrossConnectPoints(path);
356 - Iterator<Path> itrPath = paths.iterator();
357 - while (itrPath.hasNext()) {
358 - Path nextPath = itrPath.next();
359 -
360 - List<ConnectPoint> crossConnectPoints = getCrossConnectPoints(nextPath);
361 362
362 - // Skip to next path if not all connect points are available 363 + // Skip to next path if cross connect points are mismatched
363 if (!checkCrossConnectPoints(crossConnectPoints)) { 364 if (!checkCrossConnectPoints(crossConnectPoints)) {
364 continue; 365 continue;
365 } 366 }
...@@ -370,18 +371,41 @@ public class OpticalPathProvisioner { ...@@ -370,18 +371,41 @@ public class OpticalPathProvisioner {
370 return Collections.emptyList(); 371 return Collections.emptyList();
371 } 372 }
372 373
373 - private void teardownLightpath(Intent intent) { 374 + /**
374 - /* FIXME this command doesn't make much sense. we need to define the semantics 375 + * Link weight function that emphasizes re-use of packet links.
375 - // TODO move to resourceManager 376 + */
376 - if (intent instanceof OpticalConnectivityIntent) { 377 + private class OpticalLinkWeight implements LinkWeight {
377 - inStatusTportMap.remove(((OpticalConnectivityIntent) intent).getSrc()); 378 + @Override
378 - outStatusTportMap.remove(((OpticalConnectivityIntent) intent).getDst()); 379 + public double weight(TopologyEdge edge) {
379 - // TODO tear down the idle lightpath if the utilization is zero. 380 + // Ignore inactive links
381 + if (edge.link().state() == Link.State.INACTIVE) {
382 + return -1;
383 + }
380 384
385 + // TODO: Ignore cross connect links with used ports
386 +
387 + // Transport links have highest weight
388 + if (edge.link().type() == Link.Type.OPTICAL) {
389 + return 1000;
390 + }
391 +
392 + // Packet links
393 + return 1;
381 } 394 }
382 - */ //end-FIXME
383 } 395 }
384 396
397 + /**
398 + * Handle withdrawn intent on each network layer.
399 + *
400 + * @param intent the withdrawn intent
401 + */
402 + private void withdrawIntent(Intent intent) {
403 + if (intent instanceof OpticalConnectivityIntent) {
404 + deviceResourceService.releasePorts(intent.id());
405 + linkResourceService.releaseResources(linkResourceService.getAllocations(intent.id()));
406 + }
407 + // TODO: add other layers
408 + }
385 } 409 }
386 410
387 /** 411 /**
...@@ -405,25 +429,4 @@ public class OpticalPathProvisioner { ...@@ -405,25 +429,4 @@ public class OpticalPathProvisioner {
405 return false; 429 return false;
406 } 430 }
407 431
408 - /**
409 - * Link weight function that emphasizes re-use of packet links.
410 - */
411 - private static class OpticalLinkWeight implements LinkWeight {
412 - @Override
413 - public double weight(TopologyEdge edge) {
414 - // Ignore inactive links
415 - if (edge.link().state() == Link.State.INACTIVE) {
416 - return -1;
417 - }
418 -
419 - // Transport links have highest weight
420 - if (edge.link().type() == Link.Type.OPTICAL) {
421 - return 1000;
422 - }
423 -
424 - // Packet links
425 - return 1;
426 - }
427 - }
428 -
429 } 432 }
......
...@@ -26,7 +26,7 @@ public interface Device extends Element { ...@@ -26,7 +26,7 @@ public interface Device extends Element {
26 * Coarse classification of the type of the infrastructure device. 26 * Coarse classification of the type of the infrastructure device.
27 */ 27 */
28 public enum Type { 28 public enum Type {
29 - SWITCH, ROUTER, ROADM, OTN, FIREWALL, BALANCER, IPS, IDS, CONTROLLER, OTHER 29 + SWITCH, ROUTER, ROADM, OTN, ROADM_OTN, FIREWALL, BALANCER, IPS, IDS, CONTROLLER, OTHER
30 } 30 }
31 31
32 /** 32 /**
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
15 */ 15 */
16 package org.onosproject.net; 16 package org.onosproject.net;
17 17
18 -import org.onlab.util.Frequency;
19 -
20 import java.util.Objects; 18 import java.util.Objects;
21 19
22 import static com.google.common.base.MoreObjects.toStringHelper; 20 import static com.google.common.base.MoreObjects.toStringHelper;
...@@ -29,9 +27,6 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -29,9 +27,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
29 */ 27 */
30 public class OchPort extends DefaultPort { 28 public class OchPort extends DefaultPort {
31 29
32 - public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1);
33 - public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5);
34 -
35 private final OduSignalType signalType; 30 private final OduSignalType signalType;
36 private final boolean isTunable; 31 private final boolean isTunable;
37 private final OchSignal lambda; 32 private final OchSignal lambda;
...@@ -43,7 +38,7 @@ public class OchPort extends DefaultPort { ...@@ -43,7 +38,7 @@ public class OchPort extends DefaultPort {
43 * @param number port number 38 * @param number port number
44 * @param isEnabled port enabled state 39 * @param isEnabled port enabled state
45 * @param signalType ODU signal type 40 * @param signalType ODU signal type
46 - * @param isTunable maximum frequency in MHz 41 + * @param isTunable tunable wavelength capability
47 * @param lambda OCh signal 42 * @param lambda OCh signal
48 * @param annotations optional key/value annotations 43 * @param annotations optional key/value annotations
49 */ 44 */
......
...@@ -30,11 +30,10 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -30,11 +30,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
30 * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)". 30 * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)".
31 * </p> 31 * </p>
32 */ 32 */
33 -// TODO: consider which is better, OchSignal or OpticalChannelSignal
34 public class OchSignal implements Lambda { 33 public class OchSignal implements Lambda {
35 34
36 - private static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1); 35 + public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1);
37 - private static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5); 36 + public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5);
38 37
39 private final GridType gridType; 38 private final GridType gridType;
40 private final ChannelSpacing channelSpacing; 39 private final ChannelSpacing channelSpacing;
...@@ -57,10 +56,9 @@ public class OchSignal implements Lambda { ...@@ -57,10 +56,9 @@ public class OchSignal implements Lambda {
57 int spacingMultiplier, int slotGranularity) { 56 int spacingMultiplier, int slotGranularity) {
58 this.gridType = checkNotNull(gridType); 57 this.gridType = checkNotNull(gridType);
59 this.channelSpacing = checkNotNull(channelSpacing); 58 this.channelSpacing = checkNotNull(channelSpacing);
60 - // TODO: check the precondition for spacingMultiplier. Is negative value permitted? 59 + // Negative values are permitted for spacingMultiplier
61 this.spacingMultiplier = spacingMultiplier; 60 this.spacingMultiplier = spacingMultiplier;
62 - 61 + checkArgument(slotGranularity > 0, "slotGranularity must be larger than 0, received %s", slotGranularity);
63 - checkArgument(slotGranularity > 0, "slotGranularity must be more than 0, but %s", slotGranularity);
64 this.slotGranularity = slotGranularity; 62 this.slotGranularity = slotGranularity;
65 } 63 }
66 64
......
...@@ -40,7 +40,7 @@ public class OchPortDescription extends DefaultPortDescription { ...@@ -40,7 +40,7 @@ public class OchPortDescription extends DefaultPortDescription {
40 * @param isEnabled port enabled state 40 * @param isEnabled port enabled state
41 * @param signalType ODU signal type 41 * @param signalType ODU signal type
42 * @param isTunable tunable wavelength capability 42 * @param isTunable tunable wavelength capability
43 - * @param lambda Och signal 43 + * @param lambda OCh signal
44 * @param annotations optional key/value annotations map 44 * @param annotations optional key/value annotations map
45 */ 45 */
46 public OchPortDescription(PortNumber number, boolean isEnabled, OduSignalType signalType, 46 public OchPortDescription(PortNumber number, boolean isEnabled, OduSignalType signalType,
......
...@@ -24,8 +24,8 @@ import java.util.Collections; ...@@ -24,8 +24,8 @@ import java.util.Collections;
24 import static com.google.common.base.Preconditions.checkNotNull; 24 import static com.google.common.base.Preconditions.checkNotNull;
25 25
26 /** 26 /**
27 - * An optical layer intent for connectivity from one transponder port to another 27 + * An optical layer intent for connectivity between two OCh ports.
28 - * transponder port. No traffic selector or traffic treatment are needed. 28 + * No traffic selector or traffic treatment are needed.
29 */ 29 */
30 public final class OpticalConnectivityIntent extends Intent { 30 public final class OpticalConnectivityIntent extends Intent {
31 private final ConnectPoint src; 31 private final ConnectPoint src;
......
...@@ -15,11 +15,9 @@ ...@@ -15,11 +15,9 @@
15 */ 15 */
16 package org.onosproject.net.intent; 16 package org.onosproject.net.intent;
17 17
18 -import java.util.Collection;
19 -
20 import org.onosproject.core.ApplicationId; 18 import org.onosproject.core.ApplicationId;
21 import org.onosproject.net.ConnectPoint; 19 import org.onosproject.net.ConnectPoint;
22 -import org.onosproject.net.Link; 20 +import org.onosproject.net.OchSignal;
23 import org.onosproject.net.Path; 21 import org.onosproject.net.Path;
24 22
25 import com.google.common.base.MoreObjects; 23 import com.google.common.base.MoreObjects;
...@@ -32,27 +30,27 @@ public final class OpticalPathIntent extends Intent { ...@@ -32,27 +30,27 @@ public final class OpticalPathIntent extends Intent {
32 private final ConnectPoint src; 30 private final ConnectPoint src;
33 private final ConnectPoint dst; 31 private final ConnectPoint dst;
34 private final Path path; 32 private final Path path;
35 - 33 + private final OchSignal lambda;
36 34
37 private OpticalPathIntent(ApplicationId appId, 35 private OpticalPathIntent(ApplicationId appId,
38 Key key, 36 Key key,
39 ConnectPoint src, 37 ConnectPoint src,
40 ConnectPoint dst, 38 ConnectPoint dst,
41 Path path, 39 Path path,
40 + OchSignal lambda,
42 int priority) { 41 int priority) {
43 - super(appId, 42 + super(appId, key, ImmutableSet.copyOf(path.links()), priority);
44 - key,
45 - ImmutableSet.copyOf(path.links()),
46 - priority);
47 this.src = checkNotNull(src); 43 this.src = checkNotNull(src);
48 this.dst = checkNotNull(dst); 44 this.dst = checkNotNull(dst);
49 this.path = checkNotNull(path); 45 this.path = checkNotNull(path);
46 + this.lambda = checkNotNull(lambda);
50 } 47 }
51 48
52 protected OpticalPathIntent() { 49 protected OpticalPathIntent() {
53 this.src = null; 50 this.src = null;
54 this.dst = null; 51 this.dst = null;
55 this.path = null; 52 this.path = null;
53 + this.lambda = null;
56 } 54 }
57 55
58 /** 56 /**
...@@ -72,6 +70,7 @@ public final class OpticalPathIntent extends Intent { ...@@ -72,6 +70,7 @@ public final class OpticalPathIntent extends Intent {
72 private ConnectPoint src; 70 private ConnectPoint src;
73 private ConnectPoint dst; 71 private ConnectPoint dst;
74 private Path path; 72 private Path path;
73 + private OchSignal lambda;
75 Key key; 74 Key key;
76 75
77 @Override 76 @Override
...@@ -123,6 +122,17 @@ public final class OpticalPathIntent extends Intent { ...@@ -123,6 +122,17 @@ public final class OpticalPathIntent extends Intent {
123 } 122 }
124 123
125 /** 124 /**
125 + * Sets the optical channel (lambda) for the intent that will be built.
126 + *
127 + * @param lambda the optical channel
128 + * @return this builder
129 + */
130 + public Builder lambda(OchSignal lambda) {
131 + this.lambda = lambda;
132 + return this;
133 + }
134 +
135 + /**
126 * Builds an optical path intent from the accumulated parameters. 136 * Builds an optical path intent from the accumulated parameters.
127 * 137 *
128 * @return optical path intent 138 * @return optical path intent
...@@ -135,6 +145,7 @@ public final class OpticalPathIntent extends Intent { ...@@ -135,6 +145,7 @@ public final class OpticalPathIntent extends Intent {
135 src, 145 src,
136 dst, 146 dst,
137 path, 147 path,
148 + lambda,
138 priority 149 priority
139 ); 150 );
140 } 151 }
...@@ -153,6 +164,10 @@ public final class OpticalPathIntent extends Intent { ...@@ -153,6 +164,10 @@ public final class OpticalPathIntent extends Intent {
153 return path; 164 return path;
154 } 165 }
155 166
167 + public OchSignal lambda() {
168 + return lambda;
169 + }
170 +
156 @Override 171 @Override
157 public String toString() { 172 public String toString() {
158 return MoreObjects.toStringHelper(getClass()) 173 return MoreObjects.toStringHelper(getClass())
...@@ -163,11 +178,7 @@ public final class OpticalPathIntent extends Intent { ...@@ -163,11 +178,7 @@ public final class OpticalPathIntent extends Intent {
163 .add("ingressPort", src) 178 .add("ingressPort", src)
164 .add("egressPort", dst) 179 .add("egressPort", dst)
165 .add("path", path) 180 .add("path", path)
181 + .add("lambda", lambda)
166 .toString(); 182 .toString();
167 } 183 }
168 -
169 -
170 - public Collection<Link> requiredLinks() {
171 - return path.links();
172 - }
173 } 184 }
......
1 +/*
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 + */
16 +package org.onosproject.net.resource;
17 +
18 +import org.onosproject.net.Port;
19 +import org.onosproject.net.intent.Intent;
20 +import org.onosproject.net.intent.IntentId;
21 +
22 +import java.util.Set;
23 +
24 +/**
25 + * Service for providing device resources.
26 + */
27 +public interface DeviceResourceService {
28 + /**
29 + * Request a set of ports needed to satisfy the intent.
30 + *
31 + * @param intent the intent
32 + * @return set of ports
33 + */
34 + Set<Port> requestPorts(Intent intent);
35 +
36 + /**
37 + * Release ports associated with given intent ID.
38 + *
39 + * @param intentId intent ID
40 + */
41 + void releasePorts(IntentId intentId);
42 +}
1 +/*
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 + */
16 +package org.onosproject.net.resource;
17 +
18 +import org.onosproject.net.DeviceId;
19 +import org.onosproject.net.Port;
20 +import org.onosproject.net.intent.IntentId;
21 +
22 +import java.util.Set;
23 +
24 +public interface DeviceResourceStore {
25 + Set<Port> getFreePorts(DeviceId deviceId);
26 +
27 + void allocatePorts(Set<Port> port, IntentId intent);
28 +
29 + void releasePorts(IntentId intent);
30 +}
...@@ -89,6 +89,10 @@ public final class NetTestTools { ...@@ -89,6 +89,10 @@ public final class NetTestTools {
89 return new DefaultPath(PID, links, ids.length); 89 return new DefaultPath(PID, links, ids.length);
90 } 90 }
91 91
92 + // Creates OCh signal
93 + public static OchSignal createLambda() {
94 + return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_6P25GHZ, 8, 4);
95 + }
92 96
93 /** 97 /**
94 * Verifies that Annotations created by merging {@code annotations} is 98 * Verifies that Annotations created by merging {@code annotations} is
......
...@@ -18,6 +18,7 @@ package org.onosproject.net.intent; ...@@ -18,6 +18,7 @@ package org.onosproject.net.intent;
18 import org.hamcrest.Matchers; 18 import org.hamcrest.Matchers;
19 import org.junit.Before; 19 import org.junit.Before;
20 import org.junit.Test; 20 import org.junit.Test;
21 +import org.onosproject.net.OchSignal;
21 import org.onosproject.net.Path; 22 import org.onosproject.net.Path;
22 23
23 import com.google.common.testing.EqualsTester; 24 import com.google.common.testing.EqualsTester;
...@@ -28,6 +29,7 @@ import static org.hamcrest.core.IsEqual.equalTo; ...@@ -28,6 +29,7 @@ import static org.hamcrest.core.IsEqual.equalTo;
28 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; 29 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
29 import static org.onosproject.net.NetTestTools.APP_ID; 30 import static org.onosproject.net.NetTestTools.APP_ID;
30 import static org.onosproject.net.NetTestTools.connectPoint; 31 import static org.onosproject.net.NetTestTools.connectPoint;
32 +import static org.onosproject.net.NetTestTools.createLambda;
31 import static org.onosproject.net.NetTestTools.createPath; 33 import static org.onosproject.net.NetTestTools.createPath;
32 34
33 public class OpticalPathIntentTest extends AbstractIntentTest { 35 public class OpticalPathIntentTest extends AbstractIntentTest {
...@@ -37,6 +39,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest { ...@@ -37,6 +39,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest {
37 OpticalPathIntent intent1; 39 OpticalPathIntent intent1;
38 OpticalPathIntent intent2; 40 OpticalPathIntent intent2;
39 Path defaultPath; 41 Path defaultPath;
42 + OchSignal lambda;
40 43
41 @Before 44 @Before
42 public void opticalPathIntentTestSetUp() { 45 public void opticalPathIntentTestSetUp() {
...@@ -46,6 +49,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest { ...@@ -46,6 +49,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest {
46 .src(connectPoint("one", 1)) 49 .src(connectPoint("one", 1))
47 .dst(connectPoint("two", 2)) 50 .dst(connectPoint("two", 2))
48 .path(defaultPath) 51 .path(defaultPath)
52 + .lambda(createLambda())
49 .priority(PRIORITY) 53 .priority(PRIORITY)
50 .build(); 54 .build();
51 55
...@@ -54,6 +58,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest { ...@@ -54,6 +58,7 @@ public class OpticalPathIntentTest extends AbstractIntentTest {
54 .src(connectPoint("two", 1)) 58 .src(connectPoint("two", 1))
55 .dst(connectPoint("one", 2)) 59 .dst(connectPoint("one", 2))
56 .path(defaultPath) 60 .path(defaultPath)
61 + .lambda(createLambda())
57 .priority(PRIORITY) 62 .priority(PRIORITY)
58 .build(); 63 .build();
59 } 64 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.intent.impl.compiler; 16 package org.onosproject.net.intent.impl.compiler;
17 17
18 +import java.util.Collections;
18 import java.util.List; 19 import java.util.List;
19 import java.util.Set; 20 import java.util.Set;
20 21
...@@ -23,16 +24,31 @@ import org.apache.felix.scr.annotations.Component; ...@@ -23,16 +24,31 @@ import org.apache.felix.scr.annotations.Component;
23 import org.apache.felix.scr.annotations.Deactivate; 24 import org.apache.felix.scr.annotations.Deactivate;
24 import org.apache.felix.scr.annotations.Reference; 25 import org.apache.felix.scr.annotations.Reference;
25 import org.apache.felix.scr.annotations.ReferenceCardinality; 26 import org.apache.felix.scr.annotations.ReferenceCardinality;
27 +import org.onlab.util.Frequency;
28 +import org.onosproject.net.ChannelSpacing;
26 import org.onosproject.net.ConnectPoint; 29 import org.onosproject.net.ConnectPoint;
30 +import org.onosproject.net.GridType;
27 import org.onosproject.net.Link; 31 import org.onosproject.net.Link;
32 +import org.onosproject.net.OchPort;
33 +import org.onosproject.net.OchSignal;
34 +import org.onosproject.net.OmsPort;
28 import org.onosproject.net.Path; 35 import org.onosproject.net.Path;
36 +import org.onosproject.net.Port;
37 +import org.onosproject.net.device.DeviceService;
29 import org.onosproject.net.intent.Intent; 38 import org.onosproject.net.intent.Intent;
30 import org.onosproject.net.intent.IntentCompiler; 39 import org.onosproject.net.intent.IntentCompiler;
31 import org.onosproject.net.intent.IntentExtensionService; 40 import org.onosproject.net.intent.IntentExtensionService;
32 import org.onosproject.net.intent.OpticalConnectivityIntent; 41 import org.onosproject.net.intent.OpticalConnectivityIntent;
33 import org.onosproject.net.intent.OpticalPathIntent; 42 import org.onosproject.net.intent.OpticalPathIntent;
34 -import org.onosproject.net.intent.impl.PathNotFoundException; 43 +import org.onosproject.net.resource.DefaultLinkResourceRequest;
44 +import org.onosproject.net.resource.DeviceResourceService;
45 +import org.onosproject.net.resource.LambdaResource;
46 +import org.onosproject.net.resource.LambdaResourceAllocation;
35 import org.onosproject.net.resource.LinkResourceAllocations; 47 import org.onosproject.net.resource.LinkResourceAllocations;
48 +import org.onosproject.net.resource.LinkResourceRequest;
49 +import org.onosproject.net.resource.LinkResourceService;
50 +import org.onosproject.net.resource.ResourceAllocation;
51 +import org.onosproject.net.resource.ResourceType;
36 import org.onosproject.net.topology.LinkWeight; 52 import org.onosproject.net.topology.LinkWeight;
37 import org.onosproject.net.topology.Topology; 53 import org.onosproject.net.topology.Topology;
38 import org.onosproject.net.topology.TopologyEdge; 54 import org.onosproject.net.topology.TopologyEdge;
...@@ -40,18 +56,32 @@ import org.onosproject.net.topology.TopologyService; ...@@ -40,18 +56,32 @@ import org.onosproject.net.topology.TopologyService;
40 56
41 import com.google.common.collect.ImmutableList; 57 import com.google.common.collect.ImmutableList;
42 58
59 +import static com.google.common.base.Preconditions.checkArgument;
60 +
43 /** 61 /**
44 * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}. 62 * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}.
45 */ 63 */
46 @Component(immediate = true) 64 @Component(immediate = true)
47 public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> { 65 public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
48 66
67 + private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM;
68 + private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ;
69 +
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected IntentExtensionService intentManager; 71 protected IntentExtensionService intentManager;
51 72
52 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected TopologyService topologyService; 74 protected TopologyService topologyService;
54 75
76 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
77 + protected DeviceService deviceService;
78 +
79 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 + protected LinkResourceService linkResourceService;
81 +
82 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 + protected DeviceResourceService deviceResourceService;
84 +
55 @Activate 85 @Activate
56 public void activate() { 86 public void activate() {
57 intentManager.registerCompiler(OpticalConnectivityIntent.class, this); 87 intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
...@@ -66,19 +96,152 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical ...@@ -66,19 +96,152 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
66 public List<Intent> compile(OpticalConnectivityIntent intent, 96 public List<Intent> compile(OpticalConnectivityIntent intent,
67 List<Intent> installable, 97 List<Intent> installable,
68 Set<LinkResourceAllocations> resources) { 98 Set<LinkResourceAllocations> resources) {
69 - // TODO: compute multiple paths using the K-shortest path algorithm 99 + // Check if source and destination are optical OCh ports
70 - Path path = calculateOpticalPath(intent.getSrc(), intent.getDst()); 100 + ConnectPoint src = intent.getSrc();
71 - Intent newIntent = OpticalPathIntent.builder() 101 + ConnectPoint dst = intent.getDst();
72 - .appId(intent.appId()) 102 + Port srcPort = deviceService.getPort(src.deviceId(), src.port());
73 - .src(intent.getSrc()) 103 + Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
74 - .dst(intent.getDst()) 104 + checkArgument(srcPort instanceof OchPort);
75 - .path(path) 105 + checkArgument(dstPort instanceof OchPort);
76 - .build(); 106 +
77 - return ImmutableList.of(newIntent); 107 + // Calculate available light paths
108 + Set<Path> paths = getOpticalPaths(intent);
109 +
110 + // Use first path that can be successfully reserved
111 + for (Path path : paths) {
112 + // Request and reserve lambda on path
113 + LinkResourceAllocations linkAllocs = assignWavelength(intent, path);
114 + if (linkAllocs == null) {
115 + continue;
116 + }
117 +
118 + OmsPort omsPort = (OmsPort) deviceService.getPort(path.src().deviceId(), path.src().port());
119 +
120 + // Try to reserve port resources, roll back if unsuccessful
121 + Set<Port> portAllocs = deviceResourceService.requestPorts(intent);
122 + if (portAllocs == null) {
123 + linkResourceService.releaseResources(linkAllocs);
124 + continue;
125 + }
126 +
127 + // Create installable optical path intent
128 + LambdaResourceAllocation lambdaAlloc = getWavelength(path, linkAllocs);
129 + OchSignal ochSignal = getOchSignal(lambdaAlloc, omsPort.minFrequency(), omsPort.grid());
130 +
131 + Intent newIntent = OpticalPathIntent.builder()
132 + .appId(intent.appId())
133 + .src(intent.getSrc())
134 + .dst(intent.getDst())
135 + .path(path)
136 + .lambda(ochSignal)
137 + .build();
138 +
139 + return ImmutableList.of(newIntent);
140 + }
141 +
142 + return Collections.emptyList();
143 + }
144 +
145 + /**
146 + * Find the lambda allocated to the path.
147 + *
148 + * @param path the path
149 + * @param linkAllocs the link allocations
150 + * @return
151 + */
152 + private LambdaResourceAllocation getWavelength(Path path, LinkResourceAllocations linkAllocs) {
153 + for (Link link : path.links()) {
154 + for (ResourceAllocation alloc : linkAllocs.getResourceAllocation(link)) {
155 + if (alloc.type() == ResourceType.LAMBDA) {
156 + return (LambdaResourceAllocation) alloc;
157 + }
158 + }
159 + }
160 +
161 + return null;
162 + }
163 +
164 + /**
165 + * Request and reserve first available wavelength across path.
166 + *
167 + * @param path path in WDM topology
168 + * @return first available lambda resource allocation
169 + */
170 + private LinkResourceAllocations assignWavelength(Intent intent, Path path) {
171 + LinkResourceRequest.Builder request =
172 + DefaultLinkResourceRequest.builder(intent.id(), path.links())
173 + .addLambdaRequest();
174 +
175 + LinkResourceAllocations allocations = linkResourceService.requestResources(request.build());
176 +
177 + checkWavelengthContinuity(allocations, path);
178 +
179 + return allocations;
180 + }
181 +
182 + /**
183 + * Checks wavelength continuity constraint across path, i.e., an identical lambda is used on all links.
184 + * @return true if wavelength continuity is met, false otherwise
185 + */
186 + private boolean checkWavelengthContinuity(LinkResourceAllocations allocations, Path path) {
187 + if (allocations == null) {
188 + return false;
189 + }
190 +
191 + LambdaResource lambda = null;
192 +
193 + for (Link link : path.links()) {
194 + for (ResourceAllocation alloc : allocations.getResourceAllocation(link)) {
195 + if (alloc.type() == ResourceType.LAMBDA) {
196 + LambdaResource nextLambda = ((LambdaResourceAllocation) alloc).lambda();
197 + if (nextLambda == null) {
198 + return false;
199 + }
200 + if (lambda == null) {
201 + lambda = nextLambda;
202 + continue;
203 + }
204 + if (!lambda.equals(nextLambda)) {
205 + return false;
206 + }
207 + }
208 + }
209 + }
210 +
211 + return true;
212 + }
213 +
214 + /**
215 + * Convert lambda resource allocation in OCh signal.
216 + *
217 + * @param alloc lambda resource allocation
218 + * @param minFrequency minimum frequency
219 + * @param grid grid spacing frequency
220 + * @return OCh signal
221 + */
222 + private OchSignal getOchSignal(LambdaResourceAllocation alloc, Frequency minFrequency, Frequency grid) {
223 + int channel = alloc.lambda().toInt();
224 +
225 + // Calculate center frequency
226 + Frequency centerFrequency = minFrequency.add(grid.multiply(channel)).add(grid.floorDivision(2));
227 +
228 + // Build OCh signal object
229 + int spacingMultiplier = (int) (centerFrequency.subtract(OchSignal.CENTER_FREQUENCY).asHz() / grid.asHz());
230 + int slotGranularity = (int) (grid.asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz());
231 + OchSignal ochSignal = new OchSignal(DEFAULT_OCH_GRIDTYPE, DEFAULT_CHANNEL_SPACING,
232 + spacingMultiplier, slotGranularity);
233 +
234 + return ochSignal;
78 } 235 }
79 236
80 - private Path calculateOpticalPath(ConnectPoint start, ConnectPoint end) { 237 + /**
81 - // TODO: support user policies 238 + * Calculates optical paths in WDM topology.
239 + *
240 + * @param intent optical connectivity intent
241 + * @return set of paths in WDM topology
242 + */
243 + private Set<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
244 + // Route in WDM topology
82 Topology topology = topologyService.currentTopology(); 245 Topology topology = topologyService.currentTopology();
83 LinkWeight weight = new LinkWeight() { 246 LinkWeight weight = new LinkWeight() {
84 @Override 247 @Override
...@@ -86,18 +249,18 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical ...@@ -86,18 +249,18 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
86 if (edge.link().state() == Link.State.INACTIVE) { 249 if (edge.link().state() == Link.State.INACTIVE) {
87 return -1; 250 return -1;
88 } 251 }
89 - return edge.link().type() == Link.Type.OPTICAL ? +1 : -1; 252 + if (edge.link().type() != Link.Type.OPTICAL) {
253 + return -1;
254 + }
255 + return edge.link().annotations().value("optical.type").equals("WDM") ? +1 : -1;
90 } 256 }
91 }; 257 };
92 258
259 + ConnectPoint start = intent.getSrc();
260 + ConnectPoint end = intent.getDst();
93 Set<Path> paths = topologyService.getPaths(topology, start.deviceId(), 261 Set<Path> paths = topologyService.getPaths(topology, start.deviceId(),
94 - end.deviceId(), weight); 262 + end.deviceId(), weight);
95 - if (paths.isEmpty()) {
96 - throw new PathNotFoundException(start.elementId(), end.elementId());
97 - }
98 263
99 - // TODO: let's be more intelligent about this eventually 264 + return paths;
100 - return paths.iterator().next();
101 } 265 }
102 -
103 } 266 }
......
...@@ -30,29 +30,21 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; ...@@ -30,29 +30,21 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
30 import org.onosproject.net.flow.FlowRule; 30 import org.onosproject.net.flow.FlowRule;
31 import org.onosproject.net.flow.TrafficSelector; 31 import org.onosproject.net.flow.TrafficSelector;
32 import org.onosproject.net.flow.TrafficTreatment; 32 import org.onosproject.net.flow.TrafficTreatment;
33 +import org.onosproject.net.flow.criteria.Criteria;
34 +import org.onosproject.net.flow.instructions.Instructions;
33 import org.onosproject.net.intent.FlowRuleIntent; 35 import org.onosproject.net.intent.FlowRuleIntent;
34 import org.onosproject.net.intent.Intent; 36 import org.onosproject.net.intent.Intent;
35 import org.onosproject.net.intent.IntentCompiler; 37 import org.onosproject.net.intent.IntentCompiler;
36 import org.onosproject.net.intent.IntentExtensionService; 38 import org.onosproject.net.intent.IntentExtensionService;
37 import org.onosproject.net.intent.OpticalPathIntent; 39 import org.onosproject.net.intent.OpticalPathIntent;
38 -import org.onosproject.net.intent.impl.IntentCompilationException;
39 -import org.onosproject.net.resource.DefaultLinkResourceRequest;
40 -import org.onosproject.net.resource.LambdaResource;
41 -import org.onosproject.net.resource.LambdaResourceAllocation;
42 import org.onosproject.net.resource.LinkResourceAllocations; 40 import org.onosproject.net.resource.LinkResourceAllocations;
43 -import org.onosproject.net.resource.LinkResourceRequest;
44 import org.onosproject.net.resource.LinkResourceService; 41 import org.onosproject.net.resource.LinkResourceService;
45 -import org.onosproject.net.resource.ResourceAllocation;
46 -import org.onosproject.net.resource.ResourceType;
47 -import org.onosproject.net.topology.TopologyService;
48 42
49 import java.util.Collections; 43 import java.util.Collections;
50 import java.util.LinkedList; 44 import java.util.LinkedList;
51 import java.util.List; 45 import java.util.List;
52 import java.util.Set; 46 import java.util.Set;
53 47
54 -import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
55 -
56 @Component(immediate = true) 48 @Component(immediate = true)
57 public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> { 49 public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
58 50
...@@ -63,15 +55,10 @@ public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathInte ...@@ -63,15 +55,10 @@ public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathInte
63 protected CoreService coreService; 55 protected CoreService coreService;
64 56
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 - protected TopologyService topologyService;
67 -
68 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected LinkResourceService resourceService; 58 protected LinkResourceService resourceService;
70 59
71 private ApplicationId appId; 60 private ApplicationId appId;
72 61
73 - static final short SIGNAL_TYPE = (short) 1;
74 -
75 @Activate 62 @Activate
76 public void activate() { 63 public void activate() {
77 appId = coreService.registerApplication("org.onosproject.net.intent"); 64 appId = coreService.registerApplication("org.onosproject.net.intent");
...@@ -86,64 +73,50 @@ public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathInte ...@@ -86,64 +73,50 @@ public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathInte
86 @Override 73 @Override
87 public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable, 74 public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable,
88 Set<LinkResourceAllocations> resources) { 75 Set<LinkResourceAllocations> resources) {
89 - LinkResourceAllocations allocations = assignWavelength(intent);
90 -
91 return Collections.singletonList( 76 return Collections.singletonList(
92 - new FlowRuleIntent(appId, createRules(intent, allocations), intent.resources())); 77 + new FlowRuleIntent(appId, createRules(intent), intent.resources()));
93 } 78 }
94 79
95 - private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) { 80 + private List<FlowRule> createRules(OpticalPathIntent intent) {
96 - LinkResourceRequest.Builder request = DefaultLinkResourceRequest
97 - .builder(intent.id(), intent.path().links())
98 - .addLambdaRequest();
99 - return resourceService.requestResources(request.build());
100 - }
101 -
102 - private List<FlowRule> createRules(OpticalPathIntent intent, LinkResourceAllocations allocations) {
103 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); 81 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
104 selectorBuilder.matchInPort(intent.src().port()); 82 selectorBuilder.matchInPort(intent.src().port());
105 83
106 List<FlowRule> rules = new LinkedList<>(); 84 List<FlowRule> rules = new LinkedList<>();
107 - ConnectPoint prev = intent.src(); 85 + ConnectPoint current = intent.src();
108 86
109 for (Link link : intent.path().links()) { 87 for (Link link : intent.path().links()) {
110 - ResourceAllocation allocation = allocations.getResourceAllocation(link).stream()
111 - .filter(x -> x.type() == ResourceType.LAMBDA)
112 - .findFirst()
113 - .orElseThrow(() -> new IntentCompilationException("Lambda was not assigned successfully"));
114 - LambdaResource la = ((LambdaResourceAllocation) allocation).lambda();
115 -
116 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); 88 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
117 - treatmentBuilder.setLambda((short) la.toInt()); 89 + treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
118 treatmentBuilder.setOutput(link.src().port()); 90 treatmentBuilder.setOutput(link.src().port());
119 91
120 - FlowRule rule = new DefaultFlowRule(prev.deviceId(), 92 + FlowRule rule = DefaultFlowRule.builder()
121 - selectorBuilder.build(), 93 + .forDevice(current.deviceId())
122 - treatmentBuilder.build(), 94 + .withSelector(selectorBuilder.build())
123 - 100, 95 + .withTreatment(treatmentBuilder.build())
124 - appId, 96 + .withPriority(100)
125 - 100, 97 + .fromApp(appId)
126 - true); 98 + .makePermanent()
99 + .build();
127 100
128 rules.add(rule); 101 rules.add(rule);
129 102
130 - prev = link.dst(); 103 + current = link.dst();
131 selectorBuilder.matchInPort(link.dst().port()); 104 selectorBuilder.matchInPort(link.dst().port());
132 - selectorBuilder.matchOpticalSignalType(SIGNAL_TYPE); 105 + selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
133 - selectorBuilder.matchLambda((short) la.toInt());
134 -
135 } 106 }
136 107
137 - // build the last T port rule 108 + // Build the egress ROADM rule
138 - TrafficTreatment.Builder treatmentLast = builder(); 109 + TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
139 treatmentLast.setOutput(intent.dst().port()); 110 treatmentLast.setOutput(intent.dst().port());
140 - FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(), 111 +
141 - selectorBuilder.build(), 112 + FlowRule rule = new DefaultFlowRule.Builder()
142 - treatmentLast.build(), 113 + .forDevice(intent.dst().deviceId())
143 - 100, 114 + .withSelector(selectorBuilder.build())
144 - appId, 115 + .withTreatment(treatmentLast.build())
145 - 100, 116 + .withPriority(100)
146 - true); 117 + .fromApp(appId)
118 + .makePermanent()
119 + .build();
147 rules.add(rule); 120 rules.add(rule);
148 121
149 return rules; 122 return rules;
......
1 +/*
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 + */
16 +package org.onosproject.net.resource.impl;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onosproject.net.Port;
25 +import org.onosproject.net.intent.Intent;
26 +import org.onosproject.net.intent.IntentId;
27 +import org.onosproject.net.intent.OpticalConnectivityIntent;
28 +import org.onosproject.net.resource.DeviceResourceService;
29 +import org.onosproject.net.resource.DeviceResourceStore;
30 +import org.slf4j.Logger;
31 +
32 +import java.util.Arrays;
33 +import java.util.HashSet;
34 +import java.util.Set;
35 +
36 +import static com.google.common.base.Preconditions.checkNotNull;
37 +import static org.slf4j.LoggerFactory.getLogger;
38 +
39 +/**
40 + * Provides basic implementation of device resources allocation.
41 + */
42 +@Component(immediate = true)
43 +@Service
44 +public class DeviceResourceManager implements DeviceResourceService {
45 +
46 + private final Logger log = getLogger(getClass());
47 +
48 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 + private DeviceResourceStore store;
50 +
51 + @Activate
52 + public void activate() {
53 + log.info("Started");
54 + }
55 +
56 + @Deactivate
57 + public void deactivate() {
58 + log.info("Stopped");
59 + }
60 +
61 + @Override
62 + public Set<Port> requestPorts(Intent intent) {
63 + checkNotNull(intent);
64 + if (intent instanceof OpticalConnectivityIntent) {
65 + OpticalConnectivityIntent opticalIntent = (OpticalConnectivityIntent) intent;
66 + Set<Port> srcPorts = store.getFreePorts(opticalIntent.getSrc().deviceId());
67 + Set<Port> dstPorts = store.getFreePorts(opticalIntent.getDst().deviceId());
68 +
69 + Port srcPort = getTypedPort(srcPorts, Port.Type.OCH);
70 + Port dstPort = getTypedPort(dstPorts, Port.Type.OCH);
71 +
72 + if (srcPort == null || dstPort == null) {
73 + return null;
74 + }
75 +
76 + Set<Port> allocPorts = new HashSet(Arrays.asList(srcPort, dstPort));
77 +
78 + store.allocatePorts(allocPorts, intent.id());
79 +
80 + return allocPorts;
81 + }
82 +
83 + return null;
84 + }
85 +
86 + @Override
87 + public void releasePorts(IntentId intentId) {
88 + store.releasePorts(intentId);
89 + }
90 +
91 + private Port getTypedPort(Set<Port> ports, Port.Type type) {
92 + for (Port port : ports) {
93 + if (port.type() == type) {
94 + return port;
95 + }
96 + }
97 +
98 + return null;
99 + }
100 +}
...@@ -52,6 +52,7 @@ import static org.hamcrest.Matchers.hasSize; ...@@ -52,6 +52,7 @@ import static org.hamcrest.Matchers.hasSize;
52 import static org.onosproject.net.Link.Type.DIRECT; 52 import static org.onosproject.net.Link.Type.DIRECT;
53 import static org.onosproject.net.NetTestTools.PID; 53 import static org.onosproject.net.NetTestTools.PID;
54 import static org.onosproject.net.NetTestTools.connectPoint; 54 import static org.onosproject.net.NetTestTools.connectPoint;
55 +import static org.onosproject.net.NetTestTools.createLambda;
55 56
56 public class OpticalPathIntentCompilerTest { 57 public class OpticalPathIntentCompilerTest {
57 58
...@@ -93,6 +94,7 @@ public class OpticalPathIntentCompilerTest { ...@@ -93,6 +94,7 @@ public class OpticalPathIntentCompilerTest {
93 .src(d1p1) 94 .src(d1p1)
94 .dst(d3p1) 95 .dst(d3p1)
95 .path(new DefaultPath(PID, links, hops)) 96 .path(new DefaultPath(PID, links, hops))
97 + .lambda(createLambda())
96 .build(); 98 .build();
97 intentExtensionService = createMock(IntentExtensionService.class); 99 intentExtensionService = createMock(IntentExtensionService.class);
98 intentExtensionService.registerCompiler(OpticalPathIntent.class, sut); 100 intentExtensionService.registerCompiler(OpticalPathIntent.class, sut);
......
1 +/*
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 + */
16 +package org.onosproject.store.resource.impl;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onlab.util.KryoNamespace;
25 +import org.onosproject.net.DeviceId;
26 +import org.onosproject.net.Port;
27 +import org.onosproject.net.device.DeviceService;
28 +import org.onosproject.net.intent.IntentId;
29 +import org.onosproject.net.resource.DeviceResourceStore;
30 +import org.onosproject.store.serializers.KryoNamespaces;
31 +import org.onosproject.store.service.ConsistentMap;
32 +import org.onosproject.store.service.Serializer;
33 +import org.onosproject.store.service.StorageService;
34 +import org.onosproject.store.service.TransactionContext;
35 +import org.onosproject.store.service.TransactionalMap;
36 +import org.slf4j.Logger;
37 +
38 +import java.util.HashSet;
39 +import java.util.Set;
40 +
41 +import static com.google.common.base.Preconditions.checkArgument;
42 +import static org.slf4j.LoggerFactory.getLogger;
43 +import static com.google.common.base.Preconditions.checkNotNull;
44 +
45 +/**
46 + * Store that manages device resources using Copycat-backed TransactionalMaps.
47 + */
48 +@Component(immediate = true, enabled = true)
49 +@Service
50 +public class ConsistentDeviceResourceStore implements DeviceResourceStore {
51 + private final Logger log = getLogger(getClass());
52 +
53 + private static final String PORT_ALLOCATIONS = "PortAllocations";
54 + private static final String INTENT_ALLOCATIONS = "IntentAllocations";
55 +
56 + private static final Serializer SERIALIZER = Serializer.using(
57 + new KryoNamespace.Builder().register(KryoNamespaces.API).build());
58 +
59 + private ConsistentMap<Port, IntentId> portAllocMap;
60 + private ConsistentMap<IntentId, Set<Port>> intentAllocMap;
61 +
62 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 + protected StorageService storageService;
64 +
65 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 + protected DeviceService deviceService;
67 +
68 + @Activate
69 + public void activate() {
70 + portAllocMap = storageService.<Port, IntentId>consistentMapBuilder()
71 + .withName(PORT_ALLOCATIONS)
72 + .withSerializer(SERIALIZER)
73 + .build();
74 + intentAllocMap = storageService.<IntentId, Set<Port>>consistentMapBuilder()
75 + .withName(INTENT_ALLOCATIONS)
76 + .withSerializer(SERIALIZER)
77 + .build();
78 + log.info("Started");
79 + }
80 +
81 + @Deactivate
82 + public void deactivate() {
83 + log.info("Stopped");
84 + }
85 +
86 + private TransactionalMap<Port, IntentId> getPortAllocs(TransactionContext tx) {
87 + return tx.getTransactionalMap(PORT_ALLOCATIONS, SERIALIZER);
88 + }
89 +
90 + private TransactionalMap<IntentId, Set<Port>> getIntentAllocs(TransactionContext tx) {
91 + return tx.getTransactionalMap(INTENT_ALLOCATIONS, SERIALIZER);
92 + }
93 +
94 + private TransactionContext getTxContext() {
95 + return storageService.transactionContextBuilder().build();
96 + }
97 +
98 + @Override
99 + public Set<Port> getFreePorts(DeviceId deviceId) {
100 + checkNotNull(deviceId);
101 +
102 + Set<Port> freePorts = new HashSet<>();
103 + for (Port port : deviceService.getPorts(deviceId)) {
104 + if (!portAllocMap.containsKey(port)) {
105 + freePorts.add(port);
106 + }
107 + }
108 +
109 + return freePorts;
110 + }
111 +
112 + @Override
113 + public void allocatePorts(Set<Port> ports, IntentId intentId) {
114 + checkNotNull(ports);
115 + checkArgument(ports.size() > 0);
116 + checkNotNull(intentId);
117 +
118 + TransactionContext tx = getTxContext();
119 + tx.begin();
120 + try {
121 + TransactionalMap<Port, IntentId> portAllocs = getPortAllocs(tx);
122 + for (Port port : ports) {
123 + portAllocs.put(port, intentId);
124 + }
125 + TransactionalMap<IntentId, Set<Port>> intentAllocs = getIntentAllocs(tx);
126 + intentAllocs.put(intentId, ports);
127 + tx.commit();
128 + } catch (Exception e) {
129 + log.error("Exception thrown, rolling back", e);
130 + tx.abort();
131 + throw e;
132 + }
133 + }
134 +
135 + @Override
136 + public void releasePorts(IntentId intentId) {
137 + checkNotNull(intentId);
138 +
139 + TransactionContext tx = getTxContext();
140 + tx.begin();
141 + try {
142 + TransactionalMap<IntentId, Set<Port>> intentAllocs = getIntentAllocs(tx);
143 + Set<Port> ports = intentAllocs.get(intentId);
144 + intentAllocs.remove(intentId);
145 +
146 + TransactionalMap<Port, IntentId> portAllocs = getPortAllocs(tx);
147 + for (Port port : ports) {
148 + portAllocs.remove(port);
149 + }
150 + } catch (Exception e) {
151 + log.error("Exception thrown, rolling back", e);
152 + tx.abort();
153 + throw e;
154 + }
155 + }
156 +}
...@@ -17,6 +17,8 @@ import org.apache.felix.scr.annotations.Service; ...@@ -17,6 +17,8 @@ import org.apache.felix.scr.annotations.Service;
17 import org.apache.felix.scr.annotations.Activate; 17 import org.apache.felix.scr.annotations.Activate;
18 import org.apache.felix.scr.annotations.Deactivate; 18 import org.apache.felix.scr.annotations.Deactivate;
19 import org.onlab.util.Bandwidth; 19 import org.onlab.util.Bandwidth;
20 +import org.onosproject.net.OmsPort;
21 +import org.onosproject.net.device.DeviceService;
20 import org.slf4j.Logger; 22 import org.slf4j.Logger;
21 import org.onlab.util.KryoNamespace; 23 import org.onlab.util.KryoNamespace;
22 import org.onlab.util.PositionalParameterStringFormatter; 24 import org.onlab.util.PositionalParameterStringFormatter;
...@@ -55,7 +57,6 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -55,7 +57,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
55 import static com.google.common.base.Preconditions.checkState; 57 import static com.google.common.base.Preconditions.checkState;
56 import static org.slf4j.LoggerFactory.getLogger; 58 import static org.slf4j.LoggerFactory.getLogger;
57 import static org.onosproject.net.AnnotationKeys.BANDWIDTH; 59 import static org.onosproject.net.AnnotationKeys.BANDWIDTH;
58 -import static org.onosproject.net.AnnotationKeys.OPTICAL_WAVES;
59 60
60 /** 61 /**
61 * Store that manages link resources using Copycat-backed TransactionalMaps. 62 * Store that manages link resources using Copycat-backed TransactionalMaps.
...@@ -78,7 +79,7 @@ public class ConsistentLinkResourceStore extends ...@@ -78,7 +79,7 @@ public class ConsistentLinkResourceStore extends
78 79
79 // table to store current allocations 80 // table to store current allocations
80 /** LinkKey -> List<LinkResourceAllocations>. */ 81 /** LinkKey -> List<LinkResourceAllocations>. */
81 - private static final String LINK_RESOURCE_ALLOCATIONS = "LinkResourceAllocations"; 82 + private static final String LINK_RESOURCE_ALLOCATIONS = "o";
82 83
83 /** IntentId -> LinkResourceAllocations. */ 84 /** IntentId -> LinkResourceAllocations. */
84 private static final String INTENT_ALLOCATIONS = "IntentAllocations"; 85 private static final String INTENT_ALLOCATIONS = "IntentAllocations";
...@@ -95,6 +96,9 @@ public class ConsistentLinkResourceStore extends ...@@ -95,6 +96,9 @@ public class ConsistentLinkResourceStore extends
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 protected LinkService linkService; 97 protected LinkService linkService;
97 98
99 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 + protected DeviceService deviceService;
101 +
98 @Activate 102 @Activate
99 public void activate() { 103 public void activate() {
100 intentAllocMap = storageService.<IntentId, LinkResourceAllocations>consistentMapBuilder() 104 intentAllocMap = storageService.<IntentId, LinkResourceAllocations>consistentMapBuilder()
...@@ -136,14 +140,14 @@ public class ConsistentLinkResourceStore extends ...@@ -136,14 +140,14 @@ public class ConsistentLinkResourceStore extends
136 140
137 private Set<LambdaResourceAllocation> getLambdaResourceCapacity(Link link) { 141 private Set<LambdaResourceAllocation> getLambdaResourceCapacity(Link link) {
138 Set<LambdaResourceAllocation> allocations = new HashSet<>(); 142 Set<LambdaResourceAllocation> allocations = new HashSet<>();
139 - try { 143 +
140 - final int waves = Integer.parseInt(link.annotations().value(OPTICAL_WAVES)); 144 + OmsPort port = (OmsPort) deviceService.getPort(link.src().deviceId(), link.src().port());
141 - for (int i = 1; i <= waves; i++) { 145 +
142 - allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i))); 146 + // Assume fixed grid for now
143 - } 147 + for (int i = 0; i < port.totalChannels(); i++) {
144 - } catch (NumberFormatException e) { 148 + allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
145 - log.debug("No {} annotation on link {}", OPTICAL_WAVES, link);
146 } 149 }
150 +
147 return allocations; 151 return allocations;
148 } 152 }
149 153
......
...@@ -54,12 +54,17 @@ class SmallOpticalTopo( Topo ): ...@@ -54,12 +54,17 @@ class SmallOpticalTopo( Topo ):
54 self.addLink( O9, O10, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink ) 54 self.addLink( O9, O10, port1=20, port2=20, annotations={ "optical.waves": 80, "optical.type": "WDM", "optical.kms": 1000, "durable": "true" }, cls=LINCLink )
55 55
56 self.addLink( SFOR10, O1, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 56 self.addLink( SFOR10, O1, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
57 + self.addLink( SFOR10, O1, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
58 +
57 self.addLink( LAXR10, O3, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 59 self.addLink( LAXR10, O3, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
58 # added second tap 60 # added second tap
59 self.addLink( LAXR10, O3, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 61 self.addLink( LAXR10, O3, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
60 self.addLink( SDGR10, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 62 self.addLink( SDGR10, O4, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
61 self.addLink( CHGR10, O7, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 63 self.addLink( CHGR10, O7, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
64 +
62 self.addLink( JFKR10, O9, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 65 self.addLink( JFKR10, O9, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
66 + self.addLink( JFKR10, O9, port1=3, port2=11, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
67 +
63 self.addLink( ATLR10, O10, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink ) 68 self.addLink( ATLR10, O10, port1=2, port2=10, speed1=10000, annotations={ "bandwidth": 100000, "optical.type": "cross-connect", "durable": "true" }, cls=LINCLink )
64 69
65 h1 = self.addHost( 'h1' ) 70 h1 = self.addHost( 'h1' )
......
...@@ -426,11 +426,15 @@ class LINCSwitch(OpticalSwitch): ...@@ -426,11 +426,15 @@ class LINCSwitch(OpticalSwitch):
426 response = json.load(urllib2.urlopen(url)) 426 response = json.load(urllib2.urlopen(url))
427 devs = response.get('devices') 427 devs = response.get('devices')
428 428
429 - # Wait for all devices to be registered & available 429 + # Wait for all devices to be registered
430 - if (len(devices) == len(devs)): 430 + if (len(devices) != len(devs)):
431 - for d in devs: 431 + continue
432 - if not d['available']: 432 +
433 - continue 433 + # Wait for all devices to available
434 + available = True
435 + for d in devs:
436 + available &= d['available']
437 + if available:
434 break 438 break
435 439
436 if (time >= TIMEOUT): 440 if (time >= TIMEOUT):
......
...@@ -138,6 +138,16 @@ public final class Frequency implements RichComparable<Frequency> { ...@@ -138,6 +138,16 @@ public final class Frequency implements RichComparable<Frequency> {
138 return new Frequency(this.frequency * value); 138 return new Frequency(this.frequency * value);
139 } 139 }
140 140
141 + /**
142 + * Returns a Frequency whose value is Math.floorDiv(this, value).
143 + *
144 + * @param value
145 + * @return Math.floorDiv(this, value)
146 + */
147 + public Frequency floorDivision(long value) {
148 + return new Frequency(Math.floorDiv(this.frequency, value));
149 + }
150 +
141 @Override 151 @Override
142 public int compareTo(Frequency other) { 152 public int compareTo(Frequency other) {
143 return ComparisonChain.start() 153 return ComparisonChain.start()
......