Ray Milkey

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
...@@ -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 }
......
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())
......
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
......