Prototype bandwidth reservation
This is a prototype of the bandwidth reservation implementation. There is no bandwidth discovery, it is all faked. The bandwidth is specified by allocating a special Intent used for demonstration purposes. This code also uses faked out interfaces in the Resource Manager, and will need to be refactored when the real Resource Manager is in place. Change-Id: I1f9a16b4144f5440bb529014a6a6f0f21d22839e
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