Marc De Leenheer
Committed by Gerrit Code Review

Rewrote optical connectivity intent compiler

Change-Id: I5acece3c14bed8a23f7bbe0c5a9bc0932a2a0881
Showing 21 changed files with 625 additions and 118 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>
......
...@@ -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()
......