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> | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -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); | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDeviceResourceStore.java
0 → 100644
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() | ... | ... |
-
Please register or login to post a comment