Committed by
Gerrit Code Review
Merge "Prototype bandwidth reservation"
Showing
12 changed files
with
476 additions
and
30 deletions
... | @@ -15,18 +15,29 @@ | ... | @@ -15,18 +15,29 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.calendar; | 16 | package org.onlab.onos.calendar; |
17 | 17 | ||
18 | -import org.onlab.onos.net.ConnectPoint; | 18 | +import java.net.URI; |
19 | -import org.onlab.onos.net.DeviceId; | ||
20 | -import org.onlab.onos.net.intent.IntentService; | ||
21 | -import org.onlab.rest.BaseResource; | ||
22 | 19 | ||
23 | import javax.ws.rs.POST; | 20 | import javax.ws.rs.POST; |
24 | import javax.ws.rs.Path; | 21 | import javax.ws.rs.Path; |
25 | import javax.ws.rs.PathParam; | 22 | import javax.ws.rs.PathParam; |
26 | import javax.ws.rs.core.Response; | 23 | import javax.ws.rs.core.Response; |
27 | -import java.net.URI; | 24 | + |
25 | +import org.onlab.onos.core.ApplicationId; | ||
26 | +import org.onlab.onos.core.CoreService; | ||
27 | +import org.onlab.onos.net.ConnectPoint; | ||
28 | +import org.onlab.onos.net.DeviceId; | ||
29 | +import org.onlab.onos.net.flow.DefaultTrafficSelector; | ||
30 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
31 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
32 | +import org.onlab.onos.net.intent.Intent; | ||
33 | +import org.onlab.onos.net.intent.IntentService; | ||
34 | +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint; | ||
35 | +import org.onlab.onos.net.resource.BandwidthResourceRequest; | ||
36 | +import org.onlab.packet.Ethernet; | ||
37 | +import org.onlab.rest.BaseResource; | ||
28 | 38 | ||
29 | import static org.onlab.onos.net.PortNumber.portNumber; | 39 | import static org.onlab.onos.net.PortNumber.portNumber; |
40 | +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
30 | 41 | ||
31 | /** | 42 | /** |
32 | * Web resource for triggering calendared intents. | 43 | * Web resource for triggering calendared intents. |
... | @@ -47,12 +58,33 @@ public class BandwidthCalendarResource extends BaseResource { | ... | @@ -47,12 +58,33 @@ public class BandwidthCalendarResource extends BaseResource { |
47 | ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); | 58 | ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort)); |
48 | ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort)); | 59 | ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort)); |
49 | 60 | ||
61 | + TrafficSelector selector = buildTrafficSelector(); | ||
62 | + TrafficTreatment treatment = builder().build(); | ||
63 | + | ||
64 | + Intent intent = new PointToPointIntentWithBandwidthConstraint( | ||
65 | + appId(), selector, treatment, | ||
66 | + srcPoint, dstPoint, new BandwidthResourceRequest(Double.parseDouble(bandwidth))); | ||
67 | + service.submit(intent); | ||
68 | + | ||
50 | return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint + | 69 | return Response.ok("Yo! We got src=" + srcPoint + "; dst=" + dstPoint + |
51 | "; bw=" + bandwidth + "; intent service " + service).build(); | 70 | "; bw=" + bandwidth + "; intent service " + service).build(); |
52 | } | 71 | } |
53 | 72 | ||
73 | + private TrafficSelector buildTrafficSelector() { | ||
74 | + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); | ||
75 | + Short ethType = Ethernet.TYPE_IPV4; | ||
76 | + | ||
77 | + selectorBuilder.matchEthType(ethType); | ||
78 | + | ||
79 | + return selectorBuilder.build(); | ||
80 | + } | ||
81 | + | ||
54 | private DeviceId deviceId(String dpid) { | 82 | private DeviceId deviceId(String dpid) { |
55 | return DeviceId.deviceId(URI.create("of:" + dpid)); | 83 | return DeviceId.deviceId(URI.create("of:" + dpid)); |
56 | } | 84 | } |
57 | 85 | ||
86 | + protected ApplicationId appId() { | ||
87 | + return get(CoreService.class).registerApplication("org.onlab.onos.calendar"); | ||
88 | + } | ||
89 | + | ||
58 | } | 90 | } | ... | ... |
cli/src/main/java/org/onlab/onos/cli/net/AddPointToPointIntentWithBandwidthConstraintCommand.java
0 → 100644
1 | +/* | ||
2 | + * Licensed to the Apache Software Foundation (ASF) under one | ||
3 | + * or more contributor license agreements. See the NOTICE file | ||
4 | + * distributed with this work for additional information | ||
5 | + * regarding copyright ownership. The ASF licenses this file | ||
6 | + * to you under the Apache License, Version 2.0 (the | ||
7 | + * "License"); you may not use this file except in compliance | ||
8 | + * with the License. You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, | ||
13 | + * software distributed under the License is distributed on an | ||
14 | + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
15 | + * KIND, either express or implied. See the License for the | ||
16 | + * specific language governing permissions and limitations | ||
17 | + * under the License. | ||
18 | + */ | ||
19 | +package org.onlab.onos.cli.net; | ||
20 | + | ||
21 | +import org.apache.karaf.shell.commands.Argument; | ||
22 | +import org.apache.karaf.shell.commands.Command; | ||
23 | +import org.onlab.onos.net.ConnectPoint; | ||
24 | +import org.onlab.onos.net.DeviceId; | ||
25 | +import org.onlab.onos.net.PortNumber; | ||
26 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
27 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
28 | +import org.onlab.onos.net.intent.Intent; | ||
29 | +import org.onlab.onos.net.intent.IntentService; | ||
30 | +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint; | ||
31 | +import org.onlab.onos.net.resource.BandwidthResourceRequest; | ||
32 | + | ||
33 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
34 | +import static org.onlab.onos.net.PortNumber.portNumber; | ||
35 | +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
36 | + | ||
37 | +/** | ||
38 | + * Installs point-to-point connectivity intents. | ||
39 | + */ | ||
40 | +@Command(scope = "onos", name = "add-point-intent-bw", | ||
41 | + description = "Installs point-to-point connectivity intent with bandwidth constraint") | ||
42 | +public class AddPointToPointIntentWithBandwidthConstraintCommand extends ConnectivityIntentCommand { | ||
43 | + | ||
44 | + @Argument(index = 0, name = "ingressDevice", | ||
45 | + description = "Ingress Device/Port Description", | ||
46 | + required = true, multiValued = false) | ||
47 | + String ingressDeviceString = null; | ||
48 | + | ||
49 | + @Argument(index = 1, name = "egressDevice", | ||
50 | + description = "Egress Device/Port Description", | ||
51 | + required = true, multiValued = false) | ||
52 | + String egressDeviceString = null; | ||
53 | + | ||
54 | + @Argument(index = 2, name = "bandwidth", | ||
55 | + description = "Bandwidth", | ||
56 | + required = true, multiValued = false) | ||
57 | + String bandwidthString = null; | ||
58 | + | ||
59 | + @Override | ||
60 | + protected void execute() { | ||
61 | + IntentService service = get(IntentService.class); | ||
62 | + | ||
63 | + DeviceId ingressDeviceId = deviceId(getDeviceId(ingressDeviceString)); | ||
64 | + PortNumber ingressPortNumber = portNumber(getPortNumber(ingressDeviceString)); | ||
65 | + ConnectPoint ingress = new ConnectPoint(ingressDeviceId, ingressPortNumber); | ||
66 | + | ||
67 | + DeviceId egressDeviceId = deviceId(getDeviceId(egressDeviceString)); | ||
68 | + PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString)); | ||
69 | + ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber); | ||
70 | + | ||
71 | + long bandwidth = Long.parseLong(bandwidthString); | ||
72 | + | ||
73 | + TrafficSelector selector = buildTrafficSelector(); | ||
74 | + TrafficTreatment treatment = builder().build(); | ||
75 | + | ||
76 | + Intent intent = new PointToPointIntentWithBandwidthConstraint( | ||
77 | + appId(), selector, treatment, | ||
78 | + ingress, egress, new BandwidthResourceRequest(bandwidth)); | ||
79 | + service.submit(intent); | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Extracts the port number portion of the ConnectPoint. | ||
84 | + * | ||
85 | + * @param deviceString string representing the device/port | ||
86 | + * @return port number as a string, empty string if the port is not found | ||
87 | + */ | ||
88 | + private String getPortNumber(String deviceString) { | ||
89 | + int slash = deviceString.indexOf('/'); | ||
90 | + if (slash <= 0) { | ||
91 | + return ""; | ||
92 | + } | ||
93 | + return deviceString.substring(slash + 1, deviceString.length()); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * Extracts the device ID portion of the ConnectPoint. | ||
98 | + * | ||
99 | + * @param deviceString string representing the device/port | ||
100 | + * @return device ID string | ||
101 | + */ | ||
102 | + private String getDeviceId(String deviceString) { | ||
103 | + int slash = deviceString.indexOf('/'); | ||
104 | + if (slash <= 0) { | ||
105 | + return ""; | ||
106 | + } | ||
107 | + return deviceString.substring(0, slash); | ||
108 | + } | ||
109 | +} |
... | @@ -47,8 +47,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { | ... | @@ -47,8 +47,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { |
47 | */ | 47 | */ |
48 | protected TrafficSelector buildTrafficSelector() { | 48 | protected TrafficSelector buildTrafficSelector() { |
49 | TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); | 49 | TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); |
50 | - | ||
51 | Short ethType = Ethernet.TYPE_IPV4; | 50 | Short ethType = Ethernet.TYPE_IPV4; |
51 | + | ||
52 | if (!Strings.isNullOrEmpty(ethTypeString)) { | 52 | if (!Strings.isNullOrEmpty(ethTypeString)) { |
53 | EthType ethTypeParameter = EthType.valueOf(ethTypeString); | 53 | EthType ethTypeParameter = EthType.valueOf(ethTypeString); |
54 | ethType = ethTypeParameter.value(); | 54 | ethType = ethTypeParameter.value(); | ... | ... |
... | @@ -116,6 +116,17 @@ | ... | @@ -116,6 +116,17 @@ |
116 | </optional-completers> | 116 | </optional-completers> |
117 | </command> | 117 | </command> |
118 | <command> | 118 | <command> |
119 | + <action class="org.onlab.onos.cli.net.AddPointToPointIntentWithBandwidthConstraintCommand"/> | ||
120 | + <completers> | ||
121 | + <ref component-id="connectPointCompleter"/> | ||
122 | + <ref component-id="connectPointCompleter"/> | ||
123 | + <null/> | ||
124 | + </completers> | ||
125 | + <optional-completers> | ||
126 | + <entry key="-t" value-ref="ethTypeCompleter"/> | ||
127 | + </optional-completers> | ||
128 | + </command> | ||
129 | + <command> | ||
119 | <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/> | 130 | <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/> |
120 | <completers> | 131 | <completers> |
121 | <ref component-id="connectPointCompleter"/> | 132 | <ref component-id="connectPointCompleter"/> | ... | ... |
... | @@ -20,6 +20,7 @@ import org.onlab.onos.core.ApplicationId; | ... | @@ -20,6 +20,7 @@ import org.onlab.onos.core.ApplicationId; |
20 | import org.onlab.onos.net.Path; | 20 | import org.onlab.onos.net.Path; |
21 | import org.onlab.onos.net.flow.TrafficSelector; | 21 | import org.onlab.onos.net.flow.TrafficSelector; |
22 | import org.onlab.onos.net.flow.TrafficTreatment; | 22 | import org.onlab.onos.net.flow.TrafficTreatment; |
23 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
23 | 24 | ||
24 | /** | 25 | /** |
25 | * Abstraction of explicitly path specified connectivity intent. | 26 | * Abstraction of explicitly path specified connectivity intent. |
... | @@ -27,6 +28,7 @@ import org.onlab.onos.net.flow.TrafficTreatment; | ... | @@ -27,6 +28,7 @@ import org.onlab.onos.net.flow.TrafficTreatment; |
27 | public class PathIntent extends ConnectivityIntent { | 28 | public class PathIntent extends ConnectivityIntent { |
28 | 29 | ||
29 | private final Path path; | 30 | private final Path path; |
31 | + private final LinkResourceRequest[] resourceRequests; | ||
30 | 32 | ||
31 | /** | 33 | /** |
32 | * Creates a new point-to-point intent with the supplied ingress/egress | 34 | * Creates a new point-to-point intent with the supplied ingress/egress |
... | @@ -39,10 +41,11 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -39,10 +41,11 @@ public class PathIntent extends ConnectivityIntent { |
39 | * @throws NullPointerException {@code path} is null | 41 | * @throws NullPointerException {@code path} is null |
40 | */ | 42 | */ |
41 | public PathIntent(ApplicationId appId, TrafficSelector selector, | 43 | public PathIntent(ApplicationId appId, TrafficSelector selector, |
42 | - TrafficTreatment treatment, Path path) { | 44 | + TrafficTreatment treatment, Path path, LinkResourceRequest[] resourceRequests) { |
43 | super(id(PathIntent.class, selector, treatment, path), appId, | 45 | super(id(PathIntent.class, selector, treatment, path), appId, |
44 | resources(path.links()), selector, treatment); | 46 | resources(path.links()), selector, treatment); |
45 | this.path = path; | 47 | this.path = path; |
48 | + this.resourceRequests = resourceRequests; | ||
46 | } | 49 | } |
47 | 50 | ||
48 | /** | 51 | /** |
... | @@ -51,6 +54,7 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -51,6 +54,7 @@ public class PathIntent extends ConnectivityIntent { |
51 | protected PathIntent() { | 54 | protected PathIntent() { |
52 | super(); | 55 | super(); |
53 | this.path = null; | 56 | this.path = null; |
57 | + this.resourceRequests = new LinkResourceRequest[0]; | ||
54 | } | 58 | } |
55 | 59 | ||
56 | /** | 60 | /** |
... | @@ -67,6 +71,10 @@ public class PathIntent extends ConnectivityIntent { | ... | @@ -67,6 +71,10 @@ public class PathIntent extends ConnectivityIntent { |
67 | return true; | 71 | return true; |
68 | } | 72 | } |
69 | 73 | ||
74 | + public LinkResourceRequest[] resourceRequests() { | ||
75 | + return resourceRequests; | ||
76 | + } | ||
77 | + | ||
70 | @Override | 78 | @Override |
71 | public String toString() { | 79 | public String toString() { |
72 | return MoreObjects.toStringHelper(getClass()) | 80 | return MoreObjects.toStringHelper(getClass()) | ... | ... |
core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntentWithBandwidthConstraint.java
0 → 100644
1 | +/* | ||
2 | + * Licensed to the Apache Software Foundation (ASF) under one | ||
3 | + * or more contributor license agreements. See the NOTICE file | ||
4 | + * distributed with this work for additional information | ||
5 | + * regarding copyright ownership. The ASF licenses this file | ||
6 | + * to you under the Apache License, Version 2.0 (the | ||
7 | + * "License"); you may not use this file except in compliance | ||
8 | + * with the License. You may obtain a copy of the License at | ||
9 | + * | ||
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + * | ||
12 | + * Unless required by applicable law or agreed to in writing, | ||
13 | + * software distributed under the License is distributed on an | ||
14 | + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
15 | + * KIND, either express or implied. See the License for the | ||
16 | + * specific language governing permissions and limitations | ||
17 | + * under the License. | ||
18 | + */ | ||
19 | +package org.onlab.onos.net.intent; | ||
20 | + | ||
21 | +import org.onlab.onos.core.ApplicationId; | ||
22 | +import org.onlab.onos.net.ConnectPoint; | ||
23 | +import org.onlab.onos.net.flow.TrafficSelector; | ||
24 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
25 | +import org.onlab.onos.net.resource.BandwidthResourceRequest; | ||
26 | + | ||
27 | +import com.google.common.base.MoreObjects; | ||
28 | + | ||
29 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
30 | + | ||
31 | +/** | ||
32 | + * Abstraction of point-to-point connectivity. | ||
33 | + */ | ||
34 | +public class PointToPointIntentWithBandwidthConstraint extends ConnectivityIntent { | ||
35 | + | ||
36 | + private final ConnectPoint ingressPoint; | ||
37 | + private final ConnectPoint egressPoint; | ||
38 | + private final BandwidthResourceRequest bandwidthResourceRequest; | ||
39 | + | ||
40 | + /** | ||
41 | + * Creates a new point-to-point intent with the supplied ingress/egress | ||
42 | + * ports. | ||
43 | + * | ||
44 | + * @param appId application identifier | ||
45 | + * @param selector traffic selector | ||
46 | + * @param treatment treatment | ||
47 | + * @param ingressPoint ingress port | ||
48 | + * @param egressPoint egress port | ||
49 | + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null. | ||
50 | + */ | ||
51 | + public PointToPointIntentWithBandwidthConstraint(ApplicationId appId, TrafficSelector selector, | ||
52 | + TrafficTreatment treatment, | ||
53 | + ConnectPoint ingressPoint, | ||
54 | + ConnectPoint egressPoint, | ||
55 | + BandwidthResourceRequest bandwidthResourceRequest) { | ||
56 | + super(id(PointToPointIntentWithBandwidthConstraint.class, selector, | ||
57 | + treatment, ingressPoint, egressPoint, bandwidthResourceRequest.bandwidth()), | ||
58 | + appId, null, selector, treatment); | ||
59 | + this.ingressPoint = checkNotNull(ingressPoint); | ||
60 | + this.egressPoint = checkNotNull(egressPoint); | ||
61 | + this.bandwidthResourceRequest = bandwidthResourceRequest; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Constructor for serializer. | ||
66 | + */ | ||
67 | + protected PointToPointIntentWithBandwidthConstraint() { | ||
68 | + super(); | ||
69 | + this.ingressPoint = null; | ||
70 | + this.egressPoint = null; | ||
71 | + bandwidthResourceRequest = new BandwidthResourceRequest(0.0); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * Returns the port on which the ingress traffic should be connected to | ||
76 | + * the egress. | ||
77 | + * | ||
78 | + * @return ingress port | ||
79 | + */ | ||
80 | + public ConnectPoint ingressPoint() { | ||
81 | + return ingressPoint; | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * Returns the port on which the traffic should egress. | ||
86 | + * | ||
87 | + * @return egress port | ||
88 | + */ | ||
89 | + public ConnectPoint egressPoint() { | ||
90 | + return egressPoint; | ||
91 | + } | ||
92 | + | ||
93 | + public BandwidthResourceRequest bandwidthRequest() { | ||
94 | + return this.bandwidthResourceRequest; | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public String toString() { | ||
99 | + return MoreObjects.toStringHelper(getClass()) | ||
100 | + .add("id", id()) | ||
101 | + .add("appId", appId()) | ||
102 | + .add("selector", selector()) | ||
103 | + .add("treatment", treatment()) | ||
104 | + .add("ingress", ingressPoint) | ||
105 | + .add("egress", egressPoint) | ||
106 | + .add("bandwidth", bandwidthResourceRequest.bandwidth().toString()) | ||
107 | + .toString(); | ||
108 | + } | ||
109 | + | ||
110 | +} |
... | @@ -15,11 +15,12 @@ | ... | @@ -15,11 +15,12 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.net.intent; | 16 | package org.onlab.onos.net.intent; |
17 | 17 | ||
18 | -import static org.junit.Assert.assertEquals; | ||
19 | - | ||
20 | import org.junit.Test; | 18 | import org.junit.Test; |
21 | import org.onlab.onos.net.NetTestTools; | 19 | import org.onlab.onos.net.NetTestTools; |
22 | import org.onlab.onos.net.Path; | 20 | import org.onlab.onos.net.Path; |
21 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
22 | + | ||
23 | +import static org.junit.Assert.assertEquals; | ||
23 | 24 | ||
24 | public class PathIntentTest extends ConnectivityIntentTest { | 25 | public class PathIntentTest extends ConnectivityIntentTest { |
25 | // 111:11 --> 222:22 | 26 | // 111:11 --> 222:22 |
... | @@ -39,11 +40,11 @@ public class PathIntentTest extends ConnectivityIntentTest { | ... | @@ -39,11 +40,11 @@ public class PathIntentTest extends ConnectivityIntentTest { |
39 | 40 | ||
40 | @Override | 41 | @Override |
41 | protected PathIntent createOne() { | 42 | protected PathIntent createOne() { |
42 | - return new PathIntent(APPID, MATCH, NOP, PATH1); | 43 | + return new PathIntent(APPID, MATCH, NOP, PATH1, new LinkResourceRequest[0]); |
43 | } | 44 | } |
44 | 45 | ||
45 | @Override | 46 | @Override |
46 | protected PathIntent createAnother() { | 47 | protected PathIntent createAnother() { |
47 | - return new PathIntent(APPID, MATCH, NOP, PATH2); | 48 | + return new PathIntent(APPID, MATCH, NOP, PATH2, new LinkResourceRequest[0]); |
48 | } | 49 | } |
49 | } | 50 | } | ... | ... |
... | @@ -15,6 +15,10 @@ | ... | @@ -15,6 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.net.intent.impl; | 16 | package org.onlab.onos.net.intent.impl; |
17 | 17 | ||
18 | +import java.util.Arrays; | ||
19 | +import java.util.List; | ||
20 | +import java.util.Set; | ||
21 | + | ||
18 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
19 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
20 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -32,13 +36,10 @@ import org.onlab.onos.net.intent.IntentCompiler; | ... | @@ -32,13 +36,10 @@ import org.onlab.onos.net.intent.IntentCompiler; |
32 | import org.onlab.onos.net.intent.IntentExtensionService; | 36 | import org.onlab.onos.net.intent.IntentExtensionService; |
33 | import org.onlab.onos.net.intent.PathIntent; | 37 | import org.onlab.onos.net.intent.PathIntent; |
34 | import org.onlab.onos.net.topology.LinkWeight; | 38 | import org.onlab.onos.net.topology.LinkWeight; |
39 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
35 | import org.onlab.onos.net.topology.PathService; | 40 | import org.onlab.onos.net.topology.PathService; |
36 | import org.onlab.onos.net.topology.TopologyEdge; | 41 | import org.onlab.onos.net.topology.TopologyEdge; |
37 | 42 | ||
38 | -import java.util.Arrays; | ||
39 | -import java.util.List; | ||
40 | -import java.util.Set; | ||
41 | - | ||
42 | import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; | 43 | import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; |
43 | 44 | ||
44 | /** | 45 | /** |
... | @@ -85,7 +86,7 @@ public class HostToHostIntentCompiler | ... | @@ -85,7 +86,7 @@ public class HostToHostIntentCompiler |
85 | TrafficSelector selector = builder(intent.selector()) | 86 | TrafficSelector selector = builder(intent.selector()) |
86 | .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); | 87 | .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); |
87 | return new PathIntent(intent.appId(), selector, intent.treatment(), | 88 | return new PathIntent(intent.appId(), selector, intent.treatment(), |
88 | - path); | 89 | + path, new LinkResourceRequest[0]); |
89 | } | 90 | } |
90 | 91 | ||
91 | private Path getPath(HostId one, HostId two) { | 92 | private Path getPath(HostId one, HostId two) { | ... | ... |
... | @@ -15,9 +15,6 @@ | ... | @@ -15,9 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.net.intent.impl; | 16 | package org.onlab.onos.net.intent.impl; |
17 | 17 | ||
18 | -import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
19 | -import static org.slf4j.LoggerFactory.getLogger; | ||
20 | - | ||
21 | import java.util.Iterator; | 18 | import java.util.Iterator; |
22 | import java.util.List; | 19 | import java.util.List; |
23 | 20 | ||
... | @@ -41,10 +38,15 @@ import org.onlab.onos.net.flow.TrafficTreatment; | ... | @@ -41,10 +38,15 @@ import org.onlab.onos.net.flow.TrafficTreatment; |
41 | import org.onlab.onos.net.intent.IntentExtensionService; | 38 | import org.onlab.onos.net.intent.IntentExtensionService; |
42 | import org.onlab.onos.net.intent.IntentInstaller; | 39 | import org.onlab.onos.net.intent.IntentInstaller; |
43 | import org.onlab.onos.net.intent.PathIntent; | 40 | import org.onlab.onos.net.intent.PathIntent; |
41 | +import org.onlab.onos.net.resource.LinkResourceAllocations; | ||
42 | +import org.onlab.onos.net.resource.LinkResourceService; | ||
44 | import org.slf4j.Logger; | 43 | import org.slf4j.Logger; |
45 | 44 | ||
46 | import com.google.common.collect.Lists; | 45 | import com.google.common.collect.Lists; |
47 | 46 | ||
47 | +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
48 | +import static org.slf4j.LoggerFactory.getLogger; | ||
49 | + | ||
48 | /** | 50 | /** |
49 | * Installer for {@link PathIntent packet path connectivity intents}. | 51 | * Installer for {@link PathIntent packet path connectivity intents}. |
50 | */ | 52 | */ |
... | @@ -59,6 +61,9 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -59,6 +61,9 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 61 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
60 | protected CoreService coreService; | 62 | protected CoreService coreService; |
61 | 63 | ||
64 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
65 | + protected LinkResourceService resourceService; | ||
66 | + | ||
62 | private ApplicationId appId; | 67 | private ApplicationId appId; |
63 | 68 | ||
64 | @Activate | 69 | @Activate |
... | @@ -74,6 +79,11 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -74,6 +79,11 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
74 | 79 | ||
75 | @Override | 80 | @Override |
76 | public List<FlowRuleBatchOperation> install(PathIntent intent) { | 81 | public List<FlowRuleBatchOperation> install(PathIntent intent) { |
82 | + LinkResourceAllocations allocations = allocateBandwidth(intent); | ||
83 | + if (allocations == null) { | ||
84 | + log.debug("Insufficient bandwidth available to install path intent {}", intent); | ||
85 | + return null; | ||
86 | + } | ||
77 | TrafficSelector.Builder builder = | 87 | TrafficSelector.Builder builder = |
78 | DefaultTrafficSelector.builder(intent.selector()); | 88 | DefaultTrafficSelector.builder(intent.selector()); |
79 | Iterator<Link> links = intent.path().links().iterator(); | 89 | Iterator<Link> links = intent.path().links().iterator(); |
... | @@ -117,6 +127,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -117,6 +127,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
117 | return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 127 | return Lists.newArrayList(new FlowRuleBatchOperation(rules)); |
118 | } | 128 | } |
119 | 129 | ||
130 | + private LinkResourceAllocations allocateBandwidth(PathIntent intent) { | ||
131 | + return resourceService.requestResources(intent.resourceRequests()[0]); | ||
132 | + } | ||
133 | + | ||
120 | // TODO refactor below this line... ---------------------------- | 134 | // TODO refactor below this line... ---------------------------- |
121 | 135 | ||
122 | /** | 136 | /** | ... | ... |
... | @@ -15,6 +15,10 @@ | ... | @@ -15,6 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.net.intent.impl; | 16 | package org.onlab.onos.net.intent.impl; |
17 | 17 | ||
18 | +import java.util.ArrayList; | ||
19 | +import java.util.List; | ||
20 | +import java.util.Set; | ||
21 | + | ||
18 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
19 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
20 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -31,15 +35,12 @@ import org.onlab.onos.net.intent.IntentExtensionService; | ... | @@ -31,15 +35,12 @@ import org.onlab.onos.net.intent.IntentExtensionService; |
31 | import org.onlab.onos.net.intent.PathIntent; | 35 | import org.onlab.onos.net.intent.PathIntent; |
32 | import org.onlab.onos.net.intent.PointToPointIntent; | 36 | import org.onlab.onos.net.intent.PointToPointIntent; |
33 | import org.onlab.onos.net.provider.ProviderId; | 37 | import org.onlab.onos.net.provider.ProviderId; |
38 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
34 | import org.onlab.onos.net.topology.LinkWeight; | 39 | import org.onlab.onos.net.topology.LinkWeight; |
35 | import org.onlab.onos.net.topology.Topology; | 40 | import org.onlab.onos.net.topology.Topology; |
36 | import org.onlab.onos.net.topology.TopologyEdge; | 41 | import org.onlab.onos.net.topology.TopologyEdge; |
37 | import org.onlab.onos.net.topology.TopologyService; | 42 | import org.onlab.onos.net.topology.TopologyService; |
38 | 43 | ||
39 | -import java.util.ArrayList; | ||
40 | -import java.util.List; | ||
41 | -import java.util.Set; | ||
42 | - | ||
43 | import static java.util.Arrays.asList; | 44 | import static java.util.Arrays.asList; |
44 | 45 | ||
45 | /** | 46 | /** |
... | @@ -76,7 +77,7 @@ public class PointToPointIntentCompiler | ... | @@ -76,7 +77,7 @@ public class PointToPointIntentCompiler |
76 | links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false)); | 77 | links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false)); |
77 | 78 | ||
78 | return asList(createPathIntent(new DefaultPath(PID, links, path.cost() + 2, | 79 | return asList(createPathIntent(new DefaultPath(PID, links, path.cost() + 2, |
79 | - path.annotations()), intent)); | 80 | + path.annotations()), intent)); |
80 | } | 81 | } |
81 | 82 | ||
82 | /** | 83 | /** |
... | @@ -89,7 +90,8 @@ public class PointToPointIntentCompiler | ... | @@ -89,7 +90,8 @@ public class PointToPointIntentCompiler |
89 | private Intent createPathIntent(Path path, | 90 | private Intent createPathIntent(Path path, |
90 | PointToPointIntent intent) { | 91 | PointToPointIntent intent) { |
91 | return new PathIntent(intent.appId(), | 92 | return new PathIntent(intent.appId(), |
92 | - intent.selector(), intent.treatment(), path); | 93 | + intent.selector(), intent.treatment(), path, |
94 | + new LinkResourceRequest[0]); | ||
93 | } | 95 | } |
94 | 96 | ||
95 | /** | 97 | /** | ... | ... |
1 | +package org.onlab.onos.net.intent.impl; | ||
2 | + | ||
3 | +import java.util.ArrayList; | ||
4 | +import java.util.Arrays; | ||
5 | +import java.util.List; | ||
6 | +import java.util.Set; | ||
7 | + | ||
8 | +import org.apache.felix.scr.annotations.Activate; | ||
9 | +import org.apache.felix.scr.annotations.Component; | ||
10 | +import org.apache.felix.scr.annotations.Deactivate; | ||
11 | +import org.apache.felix.scr.annotations.Reference; | ||
12 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
13 | +import org.onlab.onos.net.ConnectPoint; | ||
14 | +import org.onlab.onos.net.DefaultEdgeLink; | ||
15 | +import org.onlab.onos.net.DefaultPath; | ||
16 | +import org.onlab.onos.net.Link; | ||
17 | +import org.onlab.onos.net.Path; | ||
18 | +import org.onlab.onos.net.intent.Intent; | ||
19 | +import org.onlab.onos.net.intent.IntentCompiler; | ||
20 | +import org.onlab.onos.net.intent.IntentExtensionService; | ||
21 | +import org.onlab.onos.net.intent.PathIntent; | ||
22 | +import org.onlab.onos.net.intent.PointToPointIntent; | ||
23 | +import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint; | ||
24 | +import org.onlab.onos.net.provider.ProviderId; | ||
25 | +import org.onlab.onos.net.resource.BandwidthResourceRequest; | ||
26 | +import org.onlab.onos.net.resource.DefaultLinkResourceRequest; | ||
27 | +import org.onlab.onos.net.resource.LinkResourceRequest; | ||
28 | +import org.onlab.onos.net.resource.LinkResourceService; | ||
29 | +import org.onlab.onos.net.resource.ResourceRequest; | ||
30 | +import org.onlab.onos.net.resource.ResourceType; | ||
31 | +import org.onlab.onos.net.topology.LinkWeight; | ||
32 | +import org.onlab.onos.net.topology.Topology; | ||
33 | +import org.onlab.onos.net.topology.TopologyEdge; | ||
34 | +import org.onlab.onos.net.topology.TopologyService; | ||
35 | + | ||
36 | +/** | ||
37 | + * A intent compiler for {@link org.onlab.onos.net.intent.HostToHostIntent}. | ||
38 | + */ | ||
39 | +@Component(immediate = true) | ||
40 | +public class PointToPointIntentWithBandwidthConstraintCompiler | ||
41 | + implements IntentCompiler<PointToPointIntentWithBandwidthConstraint> { | ||
42 | + | ||
43 | + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true); | ||
44 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
45 | + protected IntentExtensionService intentManager; | ||
46 | + | ||
47 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
48 | + protected TopologyService topologyService; | ||
49 | + | ||
50 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
51 | + protected LinkResourceService resourceService; | ||
52 | + | ||
53 | + @Activate | ||
54 | + public void activate() { | ||
55 | + intentManager.registerCompiler(PointToPointIntentWithBandwidthConstraint.class, this); | ||
56 | + } | ||
57 | + | ||
58 | + @Deactivate | ||
59 | + public void deactivate() { | ||
60 | + intentManager.unregisterCompiler(PointToPointIntent.class); | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public List<Intent> compile(PointToPointIntentWithBandwidthConstraint intent) { | ||
65 | + Path path = getPath(intent.ingressPoint(), intent.egressPoint(), intent.bandwidthRequest()); | ||
66 | + | ||
67 | + List<Link> links = new ArrayList<>(); | ||
68 | + links.add(DefaultEdgeLink.createEdgeLink(intent.ingressPoint(), true)); | ||
69 | + links.addAll(path.links()); | ||
70 | + links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false)); | ||
71 | + | ||
72 | + return Arrays.asList(createPathIntent(new DefaultPath(PID, links, path.cost() + 2, | ||
73 | + path.annotations()), | ||
74 | + intent)); | ||
75 | + } | ||
76 | + | ||
77 | + /** | ||
78 | + * Creates a path intent from the specified path and original | ||
79 | + * connectivity intent. | ||
80 | + * | ||
81 | + * @param path path to create an intent for | ||
82 | + * @param intent original intent | ||
83 | + */ | ||
84 | + private Intent createPathIntent(Path path, | ||
85 | + PointToPointIntentWithBandwidthConstraint intent) { | ||
86 | + LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(), | ||
87 | + path.links()) | ||
88 | + // TODO - this seems awkward, maybe allow directly attaching a BandwidthRequest | ||
89 | + .addBandwidthRequest(intent.bandwidthRequest().bandwidth().toDouble()); | ||
90 | + LinkResourceRequest bandwidthRequest = request.build(); | ||
91 | + LinkResourceRequest[] bandwidthRequests = {bandwidthRequest}; | ||
92 | + return new PathIntent(intent.appId(), | ||
93 | + intent.selector(), intent.treatment(), path, | ||
94 | + bandwidthRequests); | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
98 | + * Computes a path between two ConnectPoints. | ||
99 | + * | ||
100 | + * @param one start of the path | ||
101 | + * @param two end of the path | ||
102 | + * @return Path between the two | ||
103 | + * @throws org.onlab.onos.net.intent.impl.PathNotFoundException if a path cannot be found | ||
104 | + */ | ||
105 | + private Path getPath(ConnectPoint one, ConnectPoint two, final BandwidthResourceRequest bandwidthRequest) { | ||
106 | + Topology topology = topologyService.currentTopology(); | ||
107 | + LinkWeight weight = new LinkWeight() { | ||
108 | + @Override | ||
109 | + public double weight(TopologyEdge edge) { | ||
110 | + if (bandwidthRequest != null) { | ||
111 | + double allocatedBandwidth = 0.0; | ||
112 | + Iterable<ResourceRequest> availableResources = resourceService.getAvailableResources(edge.link()); | ||
113 | + for (ResourceRequest availableResource : availableResources) { | ||
114 | + if (availableResource.type() == ResourceType.BANDWIDTH) { | ||
115 | + BandwidthResourceRequest bandwidthRequest = (BandwidthResourceRequest) availableResource; | ||
116 | + allocatedBandwidth += bandwidthRequest.bandwidth().toDouble(); | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + // TODO this needs to be discovered from switch/ports somehow | ||
121 | + double maxBandwidth = 1000; | ||
122 | + | ||
123 | + double availableBandwidth = maxBandwidth - allocatedBandwidth; | ||
124 | + if (availableBandwidth >= bandwidthRequest.bandwidth().toDouble()) { | ||
125 | + return 1; | ||
126 | + } else { | ||
127 | + return -1; | ||
128 | + } | ||
129 | + } else { | ||
130 | + return 1; | ||
131 | + } | ||
132 | + } | ||
133 | + }; | ||
134 | + | ||
135 | + Set<Path> paths = topologyService.getPaths(topology, | ||
136 | + one.deviceId(), | ||
137 | + two.deviceId(), | ||
138 | + weight); | ||
139 | + | ||
140 | + if (paths.isEmpty()) { | ||
141 | + throw new PathNotFoundException("No packet path from " + one + " to " + two); | ||
142 | + } | ||
143 | + // TODO: let's be more intelligent about this eventually | ||
144 | + return paths.iterator().next(); | ||
145 | + } | ||
146 | +} |
... | @@ -17,6 +17,7 @@ package org.onlab.onos.net.resource.impl; | ... | @@ -17,6 +17,7 @@ package org.onlab.onos.net.resource.impl; |
17 | 17 | ||
18 | import static org.slf4j.LoggerFactory.getLogger; | 18 | import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | +import java.util.ArrayList; | ||
20 | import java.util.HashMap; | 21 | import java.util.HashMap; |
21 | import java.util.Iterator; | 22 | import java.util.Iterator; |
22 | import java.util.Map; | 23 | import java.util.Map; |
... | @@ -50,6 +51,8 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -50,6 +51,8 @@ public class LinkResourceManager implements LinkResourceService { |
50 | 51 | ||
51 | private final Logger log = getLogger(getClass()); | 52 | private final Logger log = getLogger(getClass()); |
52 | 53 | ||
54 | + LinkResourceAllocations savedAllocations; | ||
55 | + | ||
53 | @Activate | 56 | @Activate |
54 | public void activate() { | 57 | public void activate() { |
55 | log.info("Started"); | 58 | log.info("Started"); |
... | @@ -64,6 +67,8 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -64,6 +67,8 @@ public class LinkResourceManager implements LinkResourceService { |
64 | return Sets.newHashSet(Lambda.valueOf(7)); | 67 | return Sets.newHashSet(Lambda.valueOf(7)); |
65 | } | 68 | } |
66 | 69 | ||
70 | + double usedBandwidth = 0.0; | ||
71 | + | ||
67 | @Override | 72 | @Override |
68 | public LinkResourceAllocations requestResources(LinkResourceRequest req) { | 73 | public LinkResourceAllocations requestResources(LinkResourceRequest req) { |
69 | // TODO implement it using a resource data store. | 74 | // TODO implement it using a resource data store. |
... | @@ -75,6 +80,7 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -75,6 +80,7 @@ public class LinkResourceManager implements LinkResourceService { |
75 | log.info("requestResources() always returns requested bandwidth"); | 80 | log.info("requestResources() always returns requested bandwidth"); |
76 | BandwidthResourceRequest br = (BandwidthResourceRequest) r; | 81 | BandwidthResourceRequest br = (BandwidthResourceRequest) r; |
77 | alloc = new BandwidthResourceAllocation(br.bandwidth()); | 82 | alloc = new BandwidthResourceAllocation(br.bandwidth()); |
83 | + usedBandwidth += br.bandwidth().toDouble(); | ||
78 | break; | 84 | break; |
79 | case LAMBDA: | 85 | case LAMBDA: |
80 | log.info("requestResources() always returns lambda 7"); | 86 | log.info("requestResources() always returns lambda 7"); |
... | @@ -92,7 +98,8 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -92,7 +98,8 @@ public class LinkResourceManager implements LinkResourceService { |
92 | for (Link link : req.links()) { | 98 | for (Link link : req.links()) { |
93 | allocations.put(link, Sets.newHashSet(alloc)); | 99 | allocations.put(link, Sets.newHashSet(alloc)); |
94 | } | 100 | } |
95 | - return new DefaultLinkResourceAllocations(req, allocations); | 101 | + savedAllocations = new DefaultLinkResourceAllocations(req, allocations); |
102 | + return savedAllocations; | ||
96 | } | 103 | } |
97 | 104 | ||
98 | @Override | 105 | @Override |
... | @@ -115,8 +122,11 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -115,8 +122,11 @@ public class LinkResourceManager implements LinkResourceService { |
115 | 122 | ||
116 | @Override | 123 | @Override |
117 | public Iterable<LinkResourceAllocations> getAllocations(Link link) { | 124 | public Iterable<LinkResourceAllocations> getAllocations(Link link) { |
118 | - // TODO Auto-generated method stub | 125 | + ArrayList<LinkResourceAllocations> retval = new ArrayList<>(0); |
119 | - return null; | 126 | + if (savedAllocations != null) { |
127 | + retval.add(savedAllocations); | ||
128 | + } | ||
129 | + return retval; | ||
120 | } | 130 | } |
121 | 131 | ||
122 | @Override | 132 | @Override |
... | @@ -127,8 +137,10 @@ public class LinkResourceManager implements LinkResourceService { | ... | @@ -127,8 +137,10 @@ public class LinkResourceManager implements LinkResourceService { |
127 | 137 | ||
128 | @Override | 138 | @Override |
129 | public Iterable<ResourceRequest> getAvailableResources(Link link) { | 139 | public Iterable<ResourceRequest> getAvailableResources(Link link) { |
130 | - // TODO Auto-generated method stub | 140 | + BandwidthResourceRequest bw = new BandwidthResourceRequest(usedBandwidth); |
131 | - return null; | 141 | + ArrayList<ResourceRequest> result = new ArrayList<>(); |
142 | + result.add(bw); | ||
143 | + return result; | ||
132 | } | 144 | } |
133 | 145 | ||
134 | @Override | 146 | @Override | ... | ... |
-
Please register or login to post a comment