Thomas Vachuska
Committed by Gerrit Code Review

Merge "Prototype bandwidth reservation"

...@@ -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 /**
...@@ -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
......