Thomas Vachuska

adding constaints to intent API

Showing 21 changed files with 693 additions and 381 deletions
...@@ -27,8 +27,7 @@ import org.onlab.onos.net.flow.TrafficSelector; ...@@ -27,8 +27,7 @@ import org.onlab.onos.net.flow.TrafficSelector;
27 import org.onlab.onos.net.flow.TrafficTreatment; 27 import org.onlab.onos.net.flow.TrafficTreatment;
28 import org.onlab.onos.net.intent.Intent; 28 import org.onlab.onos.net.intent.Intent;
29 import org.onlab.onos.net.intent.IntentService; 29 import org.onlab.onos.net.intent.IntentService;
30 -import org.onlab.onos.net.intent.PointToPointIntentWithBandwidthConstraint; 30 +import org.onlab.onos.net.intent.PointToPointIntent;
31 -import org.onlab.onos.net.resource.BandwidthResourceRequest;
32 31
33 import static org.onlab.onos.net.DeviceId.deviceId; 32 import static org.onlab.onos.net.DeviceId.deviceId;
34 import static org.onlab.onos.net.PortNumber.portNumber; 33 import static org.onlab.onos.net.PortNumber.portNumber;
...@@ -73,9 +72,10 @@ public class AddPointToPointIntentWithBandwidthConstraintCommand extends Connect ...@@ -73,9 +72,10 @@ public class AddPointToPointIntentWithBandwidthConstraintCommand extends Connect
73 TrafficSelector selector = buildTrafficSelector(); 72 TrafficSelector selector = buildTrafficSelector();
74 TrafficTreatment treatment = builder().build(); 73 TrafficTreatment treatment = builder().build();
75 74
76 - Intent intent = new PointToPointIntentWithBandwidthConstraint( 75 + // FIXME: add bandwitdh constraint
76 + Intent intent = new PointToPointIntent(
77 appId(), selector, treatment, 77 appId(), selector, treatment,
78 - ingress, egress, new BandwidthResourceRequest(bandwidth)); 78 + ingress, egress);
79 service.submit(intent); 79 service.submit(intent);
80 } 80 }
81 81
......
...@@ -78,6 +78,9 @@ public class IntentsListCommand extends AbstractShellCommand { ...@@ -78,6 +78,9 @@ public class IntentsListCommand extends AbstractShellCommand {
78 if (!ci.treatment().instructions().isEmpty()) { 78 if (!ci.treatment().instructions().isEmpty()) {
79 print(" treatment=%s", ci.treatment().instructions()); 79 print(" treatment=%s", ci.treatment().instructions());
80 } 80 }
81 + if (ci.constraints() != null && !ci.constraints().isEmpty()) {
82 + print(" constraints=%s", ci.constraints());
83 + }
81 } 84 }
82 85
83 if (intent instanceof PointToPointIntent) { 86 if (intent instanceof PointToPointIntent) {
......
...@@ -23,6 +23,7 @@ import org.onlab.onos.net.flow.TrafficSelector; ...@@ -23,6 +23,7 @@ import org.onlab.onos.net.flow.TrafficSelector;
23 import org.onlab.onos.net.flow.TrafficTreatment; 23 import org.onlab.onos.net.flow.TrafficTreatment;
24 24
25 import java.util.Collection; 25 import java.util.Collection;
26 +import java.util.List;
26 27
27 import static com.google.common.base.Preconditions.checkNotNull; 28 import static com.google.common.base.Preconditions.checkNotNull;
28 29
...@@ -40,10 +41,14 @@ public abstract class ConnectivityIntent extends Intent { ...@@ -40,10 +41,14 @@ public abstract class ConnectivityIntent extends Intent {
40 41
41 private final TrafficSelector selector; 42 private final TrafficSelector selector;
42 private final TrafficTreatment treatment; 43 private final TrafficTreatment treatment;
44 + private final List<Constraint> constraints;
43 45
44 /** 46 /**
45 * Creates a connectivity intent that matches on the specified selector 47 * Creates a connectivity intent that matches on the specified selector
46 * and applies the specified treatment. 48 * and applies the specified treatment.
49 + * <p>
50 + * Path will be chosen without any constraints.
51 + * </p>
47 * 52 *
48 * @param id intent identifier 53 * @param id intent identifier
49 * @param appId application identifier 54 * @param appId application identifier
...@@ -56,9 +61,33 @@ public abstract class ConnectivityIntent extends Intent { ...@@ -56,9 +61,33 @@ public abstract class ConnectivityIntent extends Intent {
56 Collection<NetworkResource> resources, 61 Collection<NetworkResource> resources,
57 TrafficSelector selector, 62 TrafficSelector selector,
58 TrafficTreatment treatment) { 63 TrafficTreatment treatment) {
64 + this(id, appId, resources, selector, treatment, null);
65 + }
66 +
67 + /**
68 + * Creates a connectivity intent that matches on the specified selector
69 + * and applies the specified treatment.
70 + * <p>
71 + * Path will be optimized based on the first constraint if one is given.
72 + * </p>
73 + *
74 + * @param id intent identifier
75 + * @param appId application identifier
76 + * @param resources required network resources (optional)
77 + * @param selector traffic selector
78 + * @param treatment treatment
79 + * @param constraints optional prioritized list of constraints
80 + * @throws NullPointerException if the selector or treatement is null
81 + */
82 + protected ConnectivityIntent(IntentId id, ApplicationId appId,
83 + Collection<NetworkResource> resources,
84 + TrafficSelector selector,
85 + TrafficTreatment treatment,
86 + List<Constraint> constraints) {
59 super(id, appId, resources); 87 super(id, appId, resources);
60 this.selector = checkNotNull(selector); 88 this.selector = checkNotNull(selector);
61 this.treatment = checkNotNull(treatment); 89 this.treatment = checkNotNull(treatment);
90 + this.constraints = constraints;
62 } 91 }
63 92
64 /** 93 /**
...@@ -68,6 +97,7 @@ public abstract class ConnectivityIntent extends Intent { ...@@ -68,6 +97,7 @@ public abstract class ConnectivityIntent extends Intent {
68 super(); 97 super();
69 this.selector = null; 98 this.selector = null;
70 this.treatment = null; 99 this.treatment = null;
100 + this.constraints = null;
71 } 101 }
72 102
73 /** 103 /**
...@@ -89,13 +119,22 @@ public abstract class ConnectivityIntent extends Intent { ...@@ -89,13 +119,22 @@ public abstract class ConnectivityIntent extends Intent {
89 } 119 }
90 120
91 /** 121 /**
122 + * Returns the set of connectivity constraints.
123 + *
124 + * @return list of intent constraints
125 + */
126 + public List<Constraint> constraints() {
127 + return constraints;
128 + }
129 +
130 + /**
92 * Produces a collection of network resources from the given links. 131 * Produces a collection of network resources from the given links.
93 * 132 *
94 * @param links collection of links 133 * @param links collection of links
95 * @return collection of link resources 134 * @return collection of link resources
96 */ 135 */
97 protected static Collection<NetworkResource> resources(Collection<Link> links) { 136 protected static Collection<NetworkResource> resources(Collection<Link> links) {
98 - return ImmutableSet.<NetworkResource>copyOf(links); 137 + return ImmutableSet.<NetworkResource>copyOf((Iterable<? extends NetworkResource>) links);
99 } 138 }
100 139
101 } 140 }
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent;
17 +
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.Path;
20 +import org.onlab.onos.net.resource.LinkResourceService;
21 +
22 +/**
23 + * Representation of a connectivity constraint capable of evaluating a link
24 + * and determining the cost of traversing that link in the context of this
25 + * constraint.
26 + */
27 +public interface Constraint {
28 +
29 + // TODO: Consider separating cost vs viability.
30 +
31 + /**
32 + * Evaluates the specified link and provides the cost for its traversal.
33 + *
34 + * @param link link to be evaluated
35 + * @param resourceService resource service for validating availability of
36 + * link resources
37 + * @return cost of link traversal
38 + */
39 + double cost(Link link, LinkResourceService resourceService);
40 +
41 + /**
42 + * Validates that the specified path satisfies the constraint.
43 + *
44 + * @param path path to be validated
45 + * @param resourceService resource service for validating availability of
46 + * link resources
47 + * @return cost of link traversal
48 + */
49 + boolean validate(Path path, LinkResourceService resourceService);
50 +
51 +}
...@@ -21,6 +21,8 @@ import org.onlab.onos.net.HostId; ...@@ -21,6 +21,8 @@ import org.onlab.onos.net.HostId;
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 23
24 +import java.util.List;
25 +
24 import static com.google.common.base.Preconditions.checkNotNull; 26 import static com.google.common.base.Preconditions.checkNotNull;
25 27
26 /** 28 /**
...@@ -44,11 +46,30 @@ public final class HostToHostIntent extends ConnectivityIntent { ...@@ -44,11 +46,30 @@ public final class HostToHostIntent extends ConnectivityIntent {
44 public HostToHostIntent(ApplicationId appId, HostId one, HostId two, 46 public HostToHostIntent(ApplicationId appId, HostId one, HostId two,
45 TrafficSelector selector, 47 TrafficSelector selector,
46 TrafficTreatment treatment) { 48 TrafficTreatment treatment) {
49 + this(appId, one, two, selector, treatment, null);
50 + }
51 +
52 + /**
53 + * Creates a new host-to-host intent with the supplied host pair.
54 + *
55 + * @param appId application identifier
56 + * @param one first host
57 + * @param two second host
58 + * @param selector action
59 + * @param treatment ingress port
60 + * @param constraints optional prioritized list of path selection constraints
61 + * @throws NullPointerException if {@code one} or {@code two} is null.
62 + */
63 + public HostToHostIntent(ApplicationId appId, HostId one, HostId two,
64 + TrafficSelector selector,
65 + TrafficTreatment treatment,
66 + List<Constraint> constraints) {
47 super(id(HostToHostIntent.class, min(one, two), max(one, two), 67 super(id(HostToHostIntent.class, min(one, two), max(one, two),
48 - selector, treatment), 68 + selector, treatment, constraints),
49 - appId, null, selector, treatment); 69 + appId, null, selector, treatment, constraints);
50 this.one = checkNotNull(one); 70 this.one = checkNotNull(one);
51 this.two = checkNotNull(two); 71 this.two = checkNotNull(two);
72 +
52 } 73 }
53 74
54 private static HostId min(HostId one, HostId two) { 75 private static HostId min(HostId one, HostId two) {
......
...@@ -51,6 +51,15 @@ public final class IntentId implements BatchOperationTarget { ...@@ -51,6 +51,15 @@ public final class IntentId implements BatchOperationTarget {
51 this.fingerprint = fingerprint; 51 this.fingerprint = fingerprint;
52 } 52 }
53 53
54 + /**
55 + * Returns the backing fingerprint.
56 + *
57 + * @return the fingerprint
58 + */
59 + public long fingerprint() {
60 + return fingerprint;
61 + }
62 +
54 @Override 63 @Override
55 public int hashCode() { 64 public int hashCode() {
56 return (int) (fingerprint ^ (fingerprint >>> 32)); 65 return (int) (fingerprint ^ (fingerprint >>> 32));
......
...@@ -15,16 +15,11 @@ ...@@ -15,16 +15,11 @@
15 */ 15 */
16 package org.onlab.onos.net.intent; 16 package org.onlab.onos.net.intent;
17 17
18 -import java.util.List;
19 -
20 import com.google.common.base.MoreObjects; 18 import com.google.common.base.MoreObjects;
21 -import com.google.common.collect.ImmutableList;
22 -
23 import org.onlab.onos.core.ApplicationId; 19 import org.onlab.onos.core.ApplicationId;
24 import org.onlab.onos.net.Path; 20 import org.onlab.onos.net.Path;
25 import org.onlab.onos.net.flow.TrafficSelector; 21 import org.onlab.onos.net.flow.TrafficSelector;
26 import org.onlab.onos.net.flow.TrafficTreatment; 22 import org.onlab.onos.net.flow.TrafficTreatment;
27 -import org.onlab.onos.net.resource.LinkResourceRequest;
28 23
29 /** 24 /**
30 * Abstraction of explicitly path specified connectivity intent. 25 * Abstraction of explicitly path specified connectivity intent.
...@@ -32,7 +27,6 @@ import org.onlab.onos.net.resource.LinkResourceRequest; ...@@ -32,7 +27,6 @@ import org.onlab.onos.net.resource.LinkResourceRequest;
32 public class PathIntent extends ConnectivityIntent { 27 public class PathIntent extends ConnectivityIntent {
33 28
34 private final Path path; 29 private final Path path;
35 - private final List<LinkResourceRequest> resourceRequests;
36 30
37 /** 31 /**
38 * Creates a new point-to-point intent with the supplied ingress/egress 32 * Creates a new point-to-point intent with the supplied ingress/egress
...@@ -42,15 +36,13 @@ public class PathIntent extends ConnectivityIntent { ...@@ -42,15 +36,13 @@ public class PathIntent extends ConnectivityIntent {
42 * @param selector traffic selector 36 * @param selector traffic selector
43 * @param treatment treatment 37 * @param treatment treatment
44 * @param path traversed links 38 * @param path traversed links
45 - * @param resourceRequests link resource request
46 * @throws NullPointerException {@code path} is null 39 * @throws NullPointerException {@code path} is null
47 */ 40 */
48 public PathIntent(ApplicationId appId, TrafficSelector selector, 41 public PathIntent(ApplicationId appId, TrafficSelector selector,
49 - TrafficTreatment treatment, Path path, LinkResourceRequest[] resourceRequests) { 42 + TrafficTreatment treatment, Path path) {
50 super(id(PathIntent.class, selector, treatment, path), appId, 43 super(id(PathIntent.class, selector, treatment, path), appId,
51 resources(path.links()), selector, treatment); 44 resources(path.links()), selector, treatment);
52 this.path = path; 45 this.path = path;
53 - this.resourceRequests = ImmutableList.copyOf(resourceRequests);
54 } 46 }
55 47
56 /** 48 /**
...@@ -59,7 +51,6 @@ public class PathIntent extends ConnectivityIntent { ...@@ -59,7 +51,6 @@ public class PathIntent extends ConnectivityIntent {
59 protected PathIntent() { 51 protected PathIntent() {
60 super(); 52 super();
61 this.path = null; 53 this.path = null;
62 - this.resourceRequests = ImmutableList.of();
63 } 54 }
64 55
65 /** 56 /**
...@@ -76,10 +67,6 @@ public class PathIntent extends ConnectivityIntent { ...@@ -76,10 +67,6 @@ public class PathIntent extends ConnectivityIntent {
76 return true; 67 return true;
77 } 68 }
78 69
79 - // TODO: consider changing return type
80 - public LinkResourceRequest[] resourceRequests() {
81 - return resourceRequests.toArray(new LinkResourceRequest[resourceRequests.size()]);
82 - }
83 70
84 @Override 71 @Override
85 public String toString() { 72 public String toString() {
......
...@@ -16,10 +16,15 @@ ...@@ -16,10 +16,15 @@
16 package org.onlab.onos.net.intent; 16 package org.onlab.onos.net.intent;
17 17
18 import com.google.common.base.MoreObjects; 18 import com.google.common.base.MoreObjects;
19 +import com.google.common.collect.ImmutableList;
19 import org.onlab.onos.core.ApplicationId; 20 import org.onlab.onos.core.ApplicationId;
20 import org.onlab.onos.net.ConnectPoint; 21 import org.onlab.onos.net.ConnectPoint;
22 +import org.onlab.onos.net.Link;
21 import org.onlab.onos.net.flow.TrafficSelector; 23 import org.onlab.onos.net.flow.TrafficSelector;
22 import org.onlab.onos.net.flow.TrafficTreatment; 24 import org.onlab.onos.net.flow.TrafficTreatment;
25 +import org.onlab.onos.net.intent.constraint.LinkTypeConstraint;
26 +
27 +import java.util.List;
23 28
24 import static com.google.common.base.Preconditions.checkNotNull; 29 import static com.google.common.base.Preconditions.checkNotNull;
25 30
...@@ -33,7 +38,7 @@ public class PointToPointIntent extends ConnectivityIntent { ...@@ -33,7 +38,7 @@ public class PointToPointIntent extends ConnectivityIntent {
33 38
34 /** 39 /**
35 * Creates a new point-to-point intent with the supplied ingress/egress 40 * Creates a new point-to-point intent with the supplied ingress/egress
36 - * ports. 41 + * ports and with built-in link type constraint to avoid optical links.
37 * 42 *
38 * @param appId application identifier 43 * @param appId application identifier
39 * @param selector traffic selector 44 * @param selector traffic selector
...@@ -46,8 +51,30 @@ public class PointToPointIntent extends ConnectivityIntent { ...@@ -46,8 +51,30 @@ public class PointToPointIntent extends ConnectivityIntent {
46 TrafficTreatment treatment, 51 TrafficTreatment treatment,
47 ConnectPoint ingressPoint, 52 ConnectPoint ingressPoint,
48 ConnectPoint egressPoint) { 53 ConnectPoint egressPoint) {
49 - super(id(PointToPointIntent.class, selector, treatment, ingressPoint, egressPoint), 54 + this(appId, selector, treatment, ingressPoint, egressPoint,
50 - appId, null, selector, treatment); 55 + ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)));
56 + }
57 +
58 + /**
59 + * Creates a new point-to-point intent with the supplied ingress/egress
60 + * ports and constraints.
61 + *
62 + * @param appId application identifier
63 + * @param selector traffic selector
64 + * @param treatment treatment
65 + * @param ingressPoint ingress port
66 + * @param egressPoint egress port
67 + * @param constraints optional list of constraints
68 + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
69 + */
70 + public PointToPointIntent(ApplicationId appId, TrafficSelector selector,
71 + TrafficTreatment treatment,
72 + ConnectPoint ingressPoint,
73 + ConnectPoint egressPoint,
74 + List<Constraint> constraints) {
75 + super(id(PointToPointIntent.class, selector, treatment,
76 + ingressPoint, egressPoint, constraints),
77 + appId, null, selector, treatment, constraints);
51 this.ingressPoint = checkNotNull(ingressPoint); 78 this.ingressPoint = checkNotNull(ingressPoint);
52 this.egressPoint = checkNotNull(egressPoint); 79 this.egressPoint = checkNotNull(egressPoint);
53 } 80 }
...@@ -89,6 +116,7 @@ public class PointToPointIntent extends ConnectivityIntent { ...@@ -89,6 +116,7 @@ public class PointToPointIntent extends ConnectivityIntent {
89 .add("treatment", treatment()) 116 .add("treatment", treatment())
90 .add("ingress", ingressPoint) 117 .add("ingress", ingressPoint)
91 .add("egress", egressPoint) 118 .add("egress", egressPoint)
119 + .add("constraints", constraints())
92 .toString(); 120 .toString();
93 } 121 }
94 122
......
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 - * @param bandwidthResourceRequest bandwidth resource request
50 - * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
51 - */
52 - public PointToPointIntentWithBandwidthConstraint(ApplicationId appId, TrafficSelector selector,
53 - TrafficTreatment treatment,
54 - ConnectPoint ingressPoint,
55 - ConnectPoint egressPoint,
56 - BandwidthResourceRequest bandwidthResourceRequest) {
57 - super(id(PointToPointIntentWithBandwidthConstraint.class, selector,
58 - treatment, ingressPoint, egressPoint, bandwidthResourceRequest.bandwidth()),
59 - appId, null, selector, treatment);
60 - this.ingressPoint = checkNotNull(ingressPoint);
61 - this.egressPoint = checkNotNull(egressPoint);
62 - this.bandwidthResourceRequest = bandwidthResourceRequest;
63 - }
64 -
65 - /**
66 - * Constructor for serializer.
67 - */
68 - protected PointToPointIntentWithBandwidthConstraint() {
69 - super();
70 - this.ingressPoint = null;
71 - this.egressPoint = null;
72 - bandwidthResourceRequest = new BandwidthResourceRequest(0.0);
73 - }
74 -
75 - /**
76 - * Returns the port on which the ingress traffic should be connected to
77 - * the egress.
78 - *
79 - * @return ingress port
80 - */
81 - public ConnectPoint ingressPoint() {
82 - return ingressPoint;
83 - }
84 -
85 - /**
86 - * Returns the port on which the traffic should egress.
87 - *
88 - * @return egress port
89 - */
90 - public ConnectPoint egressPoint() {
91 - return egressPoint;
92 - }
93 -
94 - public BandwidthResourceRequest bandwidthRequest() {
95 - return this.bandwidthResourceRequest;
96 - }
97 -
98 - @Override
99 - public String toString() {
100 - return MoreObjects.toStringHelper(getClass())
101 - .add("id", id())
102 - .add("appId", appId())
103 - .add("selector", selector())
104 - .add("treatment", treatment())
105 - .add("ingress", ingressPoint)
106 - .add("egress", egressPoint)
107 - .add("bandwidth", bandwidthResourceRequest.bandwidth().toString())
108 - .toString();
109 - }
110 -
111 -}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.resource.Bandwidth;
20 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
21 +import org.onlab.onos.net.resource.LinkResourceService;
22 +import org.onlab.onos.net.resource.ResourceRequest;
23 +import org.onlab.onos.net.resource.ResourceType;
24 +
25 +import java.util.Objects;
26 +
27 +import static com.google.common.base.MoreObjects.toStringHelper;
28 +import static com.google.common.base.Preconditions.checkNotNull;
29 +
30 +/**
31 + * Constraint that evaluates links based on available bandwidths.
32 + */
33 +public class BandwidthConstraint extends BooleanConstraint {
34 +
35 + private final Bandwidth bandwidth;
36 +
37 + /**
38 + * Creates a new bandwidth constraint.
39 + *
40 + * @param bandwidth required bandwidth
41 + */
42 + public BandwidthConstraint(Bandwidth bandwidth) {
43 + this.bandwidth = checkNotNull(bandwidth, "Bandwidth cannot be null");
44 + }
45 +
46 + @Override
47 + public boolean isValid(Link link, LinkResourceService resourceService) {
48 + for (ResourceRequest request : resourceService.getAvailableResources(link)) {
49 + if (request.type() == ResourceType.BANDWIDTH) {
50 + BandwidthResourceRequest brr = (BandwidthResourceRequest) request;
51 + if (brr.bandwidth().toDouble() >= bandwidth.toDouble()) {
52 + return true;
53 + }
54 + }
55 + }
56 + return false;
57 + }
58 +
59 + /**
60 + * Returns the bandwidth required by this constraint.
61 + *
62 + * @return required bandwidth
63 + */
64 + public Bandwidth bandwidth() {
65 + return bandwidth;
66 + }
67 +
68 + @Override
69 + public int hashCode() {
70 + return Objects.hash(bandwidth);
71 + }
72 +
73 + @Override
74 + public boolean equals(Object obj) {
75 + if (this == obj) {
76 + return true;
77 + }
78 + if (obj == null || getClass() != obj.getClass()) {
79 + return false;
80 + }
81 + final BandwidthConstraint other = (BandwidthConstraint) obj;
82 + return Objects.equals(this.bandwidth, other.bandwidth);
83 + }
84 +
85 + @Override
86 + public String toString() {
87 + return toStringHelper(this).add("bandwidth", bandwidth).toString();
88 + }
89 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.Path;
20 +import org.onlab.onos.net.intent.Constraint;
21 +import org.onlab.onos.net.resource.LinkResourceService;
22 +
23 +/**
24 + * Abstract base class for various constraints that evaluate link viability
25 + * in a yes/no fashion.
26 + */
27 +public abstract class BooleanConstraint implements Constraint {
28 +
29 + /**
30 + * Returns true if the specified link satisfies the constraint.
31 + *
32 + * @param link link to be validated
33 + * @param resourceService resource service for checking available link resources
34 + * @return true if link is viable
35 + */
36 + public abstract boolean isValid(Link link, LinkResourceService resourceService);
37 +
38 + @Override
39 + public double cost(Link link, LinkResourceService resourceService) {
40 + return isValid(link, resourceService) ? +1 : -1;
41 + }
42 +
43 + @Override
44 + public boolean validate(Path path, LinkResourceService resourceService) {
45 + for (Link link : path.links()) {
46 + if (isValid(link, resourceService)) {
47 + return false;
48 + }
49 + }
50 + return true;
51 + }
52 +
53 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.resource.Lambda;
20 +import org.onlab.onos.net.resource.LinkResourceService;
21 +import org.onlab.onos.net.resource.ResourceRequest;
22 +import org.onlab.onos.net.resource.ResourceType;
23 +
24 +import java.util.Objects;
25 +
26 +import static com.google.common.base.MoreObjects.toStringHelper;
27 +
28 +/**
29 + * Constraint that evaluates links based on available lambda.
30 + */
31 +public class LambdaConstraint extends BooleanConstraint {
32 +
33 + private final Lambda lambda;
34 +
35 + /**
36 + * Creates a new optical lambda constraint.
37 + *
38 + * @param lambda optional lambda to indicate a specific lambda
39 + */
40 + public LambdaConstraint(Lambda lambda) {
41 + this.lambda = lambda;
42 + }
43 +
44 + @Override
45 + public boolean isValid(Link link, LinkResourceService resourceService) {
46 + for (ResourceRequest request : resourceService.getAvailableResources(link)) {
47 + if (request.type() == ResourceType.LAMBDA) {
48 + return true;
49 + }
50 + }
51 + return false;
52 + }
53 +
54 + /**
55 + * Returns the lambda required by this constraint.
56 + *
57 + * @return required lambda
58 + */
59 + public Lambda lambda() {
60 + return lambda;
61 + }
62 +
63 + @Override
64 + public int hashCode() {
65 + return Objects.hash(lambda);
66 + }
67 +
68 + @Override
69 + public boolean equals(Object obj) {
70 + if (this == obj) {
71 + return true;
72 + }
73 + if (obj == null || getClass() != obj.getClass()) {
74 + return false;
75 + }
76 + final LambdaConstraint other = (LambdaConstraint) obj;
77 + return Objects.equals(this.lambda, other.lambda);
78 + }
79 +
80 + @Override
81 + public String toString() {
82 + return toStringHelper(this).add("lambda", lambda).toString();
83 + }
84 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.constraint;
17 +
18 +import com.google.common.collect.ImmutableSet;
19 +import org.onlab.onos.net.Link;
20 +import org.onlab.onos.net.resource.LinkResourceService;
21 +
22 +import java.util.Objects;
23 +import java.util.Set;
24 +
25 +import static com.google.common.base.MoreObjects.toStringHelper;
26 +import static com.google.common.base.Preconditions.checkArgument;
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +/**
30 + * Constraint that evaluates links based on their type.
31 + */
32 +public class LinkTypeConstraint extends BooleanConstraint {
33 +
34 + private final Set<Link.Type> types;
35 + private final boolean isInclusive;
36 +
37 + /**
38 + * Creates a new constraint for requesting connectivity using or avoiding
39 + * the specified link types.
40 + *
41 + * @param inclusive indicates whether the given link types are to be
42 + * permitted or avoided
43 + * @param types link types
44 + */
45 + public LinkTypeConstraint(boolean inclusive, Link.Type... types) {
46 + checkNotNull(types, "Link types cannot be null");
47 + checkArgument(types.length > 0, "There must be more than one type");
48 + this.types = ImmutableSet.copyOf(types);
49 + this.isInclusive = inclusive;
50 + }
51 +
52 + @Override
53 + public boolean isValid(Link link, LinkResourceService resourceService) {
54 + boolean contains = types.contains(link.type());
55 + return isInclusive ? contains : !contains;
56 + }
57 +
58 + /**
59 + * Returns the set of link types.
60 + *
61 + * @return set of link types
62 + */
63 + public Set<Link.Type> types() {
64 + return types;
65 + }
66 +
67 + /**
68 + * Indicates if the constraint is inclusive or exclusive.
69 + *
70 + * @return true if inclusive
71 + */
72 + public boolean isInclusive() {
73 + return isInclusive;
74 + }
75 +
76 + @Override
77 + public int hashCode() {
78 + return Objects.hash(types, isInclusive);
79 + }
80 +
81 + @Override
82 + public boolean equals(Object obj) {
83 + if (this == obj) {
84 + return true;
85 + }
86 + if (obj == null || getClass() != obj.getClass()) {
87 + return false;
88 + }
89 + final LinkTypeConstraint other = (LinkTypeConstraint) obj;
90 + return Objects.equals(this.types, other.types) && Objects.equals(this.isInclusive, other.isInclusive);
91 + }
92 +
93 + @Override
94 + public String toString() {
95 + return toStringHelper(this)
96 + .add("inclusive", isInclusive)
97 + .add("types", types)
98 + .toString();
99 + }
100 +}
...@@ -20,9 +20,12 @@ import java.util.HashSet; ...@@ -20,9 +20,12 @@ import java.util.HashSet;
20 import java.util.Set; 20 import java.util.Set;
21 21
22 import org.onlab.onos.net.Link; 22 import org.onlab.onos.net.Link;
23 +import org.onlab.onos.net.intent.Constraint;
23 import org.onlab.onos.net.intent.IntentId; 24 import org.onlab.onos.net.intent.IntentId;
24 25
25 import com.google.common.collect.ImmutableSet; 26 import com.google.common.collect.ImmutableSet;
27 +import org.onlab.onos.net.intent.constraint.BandwidthConstraint;
28 +import org.onlab.onos.net.intent.constraint.LambdaConstraint;
26 29
27 /** 30 /**
28 * Implementation of {@link LinkResourceRequest}. 31 * Implementation of {@link LinkResourceRequest}.
...@@ -125,6 +128,18 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest { ...@@ -125,6 +128,18 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest {
125 return this; 128 return this;
126 } 129 }
127 130
131 + @Override
132 + public LinkResourceRequest.Builder addConstraint(Constraint constraint) {
133 + if (constraint instanceof LambdaConstraint) {
134 + return addLambdaRequest();
135 + } else if (constraint instanceof BandwidthConstraint) {
136 + BandwidthConstraint bw = (BandwidthConstraint) constraint;
137 + return addBandwidthRequest(bw.bandwidth().toDouble());
138 + }
139 + return this;
140 + }
141 +
142 +
128 /** 143 /**
129 * Returns link resource request. 144 * Returns link resource request.
130 * 145 *
......
...@@ -19,6 +19,7 @@ import java.util.Collection; ...@@ -19,6 +19,7 @@ import java.util.Collection;
19 import java.util.Set; 19 import java.util.Set;
20 20
21 import org.onlab.onos.net.Link; 21 import org.onlab.onos.net.Link;
22 +import org.onlab.onos.net.intent.Constraint;
22 import org.onlab.onos.net.intent.IntentId; 23 import org.onlab.onos.net.intent.IntentId;
23 24
24 /** 25 /**
...@@ -67,6 +68,14 @@ public interface LinkResourceRequest extends ResourceRequest { ...@@ -67,6 +68,14 @@ public interface LinkResourceRequest extends ResourceRequest {
67 public Builder addBandwidthRequest(double bandwidth); 68 public Builder addBandwidthRequest(double bandwidth);
68 69
69 /** 70 /**
71 + * Adds the resources required for a constraint.
72 + *
73 + * @param constraint the constraint
74 + * @return self
75 + */
76 + public Builder addConstraint(Constraint constraint);
77 +
78 + /**
70 * Returns link resource request. 79 * Returns link resource request.
71 * 80 *
72 * @return link resource request 81 * @return link resource request
......
...@@ -18,7 +18,6 @@ package org.onlab.onos.net.intent; ...@@ -18,7 +18,6 @@ package org.onlab.onos.net.intent;
18 import org.junit.Test; 18 import org.junit.Test;
19 import org.onlab.onos.net.NetTestTools; 19 import org.onlab.onos.net.NetTestTools;
20 import org.onlab.onos.net.Path; 20 import org.onlab.onos.net.Path;
21 -import org.onlab.onos.net.resource.LinkResourceRequest;
22 21
23 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertEquals;
24 23
...@@ -40,11 +39,11 @@ public class PathIntentTest extends ConnectivityIntentTest { ...@@ -40,11 +39,11 @@ public class PathIntentTest extends ConnectivityIntentTest {
40 39
41 @Override 40 @Override
42 protected PathIntent createOne() { 41 protected PathIntent createOne() {
43 - return new PathIntent(APPID, MATCH, NOP, PATH1, new LinkResourceRequest[0]); 42 + return new PathIntent(APPID, MATCH, NOP, PATH1);
44 } 43 }
45 44
46 @Override 45 @Override
47 protected PathIntent createAnother() { 46 protected PathIntent createAnother() {
48 - return new PathIntent(APPID, MATCH, NOP, PATH2, new LinkResourceRequest[0]); 47 + return new PathIntent(APPID, MATCH, NOP, PATH2);
49 } 48 }
50 } 49 }
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net.intent.impl;
17 +
18 +import org.apache.felix.scr.annotations.Component;
19 +import org.apache.felix.scr.annotations.Reference;
20 +import org.apache.felix.scr.annotations.ReferenceCardinality;
21 +import org.onlab.onos.net.ElementId;
22 +import org.onlab.onos.net.Path;
23 +import org.onlab.onos.net.intent.ConnectivityIntent;
24 +import org.onlab.onos.net.intent.Constraint;
25 +import org.onlab.onos.net.intent.IntentCompiler;
26 +import org.onlab.onos.net.intent.IntentExtensionService;
27 +import org.onlab.onos.net.provider.ProviderId;
28 +import org.onlab.onos.net.resource.LinkResourceService;
29 +import org.onlab.onos.net.topology.LinkWeight;
30 +import org.onlab.onos.net.topology.PathService;
31 +import org.onlab.onos.net.topology.TopologyEdge;
32 +
33 +import java.util.Iterator;
34 +import java.util.List;
35 +import java.util.Set;
36 +
37 +/**
38 + * Base class for compilers of various
39 + * {@link org.onlab.onos.net.intent.ConnectivityIntent connectivity intents}.
40 + */
41 +@Component(immediate = true)
42 +public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
43 + implements IntentCompiler<T> {
44 +
45 + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
46 +
47 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 + protected IntentExtensionService intentManager;
49 +
50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected PathService pathService;
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected LinkResourceService resourceService;
55 +
56 + /**
57 + * Returns an edge-weight capable of evaluating links on the basis of the
58 + * specified constraints.
59 + *
60 + * @param constraints path constraints
61 + * @return edge-weight function
62 + */
63 + protected LinkWeight weight(List<Constraint> constraints) {
64 + return new ConstraintBasedLinkWeight(constraints);
65 + }
66 +
67 + /**
68 + * Validates the specified path against the given constraints.
69 + *
70 + * @param path path to be checked
71 + * @return true if the path passes all constraints
72 + */
73 + protected boolean checkPath(Path path, List<Constraint> constraints) {
74 + for (Constraint constraint : constraints) {
75 + if (!constraint.validate(path, resourceService)) {
76 + return false;
77 + }
78 + }
79 + return true;
80 + }
81 +
82 + /**
83 + * Computes a path between two ConnectPoints.
84 + *
85 + * @param one start of the path
86 + * @param two end of the path
87 + * @return Path between the two
88 + * @throws PathNotFoundException if a path cannot be found
89 + */
90 + protected Path getPath(ConnectivityIntent intent,
91 + ElementId one, ElementId two) {
92 + Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
93 + if (paths.isEmpty()) {
94 + throw new PathNotFoundException("No packet path from " + one + " to " + two);
95 + }
96 + // TODO: let's be more intelligent about this eventually
97 + return paths.iterator().next();
98 + }
99 +
100 + /**
101 + * Edge-weight capable of evaluating link cost using a set of constraints.
102 + */
103 + protected class ConstraintBasedLinkWeight implements LinkWeight {
104 +
105 + private final List<Constraint> constraints;
106 +
107 + /**
108 + * Creates a new edge-weight function capable of evaluating links
109 + * on the basis of the specified constraints.
110 + *
111 + * @param constraints path constraints
112 + */
113 + ConstraintBasedLinkWeight(List<Constraint> constraints) {
114 + this.constraints = constraints;
115 + }
116 +
117 + @Override
118 + public double weight(TopologyEdge edge) {
119 + if (constraints == null) {
120 + return 1.0;
121 + }
122 +
123 + // iterate over all constraints in order and return the weight of
124 + // the first one with fast fail over the first failure
125 + Iterator<Constraint> it = constraints.iterator();
126 + double cost = it.next().cost(edge.link(), resourceService);
127 + while (it.hasNext() && cost > 0) {
128 + if (it.next().cost(edge.link(), resourceService) < 0) {
129 + return -1;
130 + }
131 + }
132 + return cost;
133 + }
134 + }
135 +
136 +}
...@@ -15,30 +15,21 @@ ...@@ -15,30 +15,21 @@
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 -
22 import org.apache.felix.scr.annotations.Activate; 18 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 20 import org.apache.felix.scr.annotations.Deactivate;
25 import org.apache.felix.scr.annotations.Reference; 21 import org.apache.felix.scr.annotations.Reference;
26 import org.apache.felix.scr.annotations.ReferenceCardinality; 22 import org.apache.felix.scr.annotations.ReferenceCardinality;
27 import org.onlab.onos.net.Host; 23 import org.onlab.onos.net.Host;
28 -import org.onlab.onos.net.HostId;
29 -import org.onlab.onos.net.Link;
30 import org.onlab.onos.net.Path; 24 import org.onlab.onos.net.Path;
31 import org.onlab.onos.net.flow.TrafficSelector; 25 import org.onlab.onos.net.flow.TrafficSelector;
32 import org.onlab.onos.net.host.HostService; 26 import org.onlab.onos.net.host.HostService;
33 import org.onlab.onos.net.intent.HostToHostIntent; 27 import org.onlab.onos.net.intent.HostToHostIntent;
34 import org.onlab.onos.net.intent.Intent; 28 import org.onlab.onos.net.intent.Intent;
35 -import org.onlab.onos.net.intent.IntentCompiler;
36 -import org.onlab.onos.net.intent.IntentExtensionService;
37 import org.onlab.onos.net.intent.PathIntent; 29 import org.onlab.onos.net.intent.PathIntent;
38 -import org.onlab.onos.net.topology.LinkWeight; 30 +
39 -import org.onlab.onos.net.resource.LinkResourceRequest; 31 +import java.util.Arrays;
40 -import org.onlab.onos.net.topology.PathService; 32 +import java.util.List;
41 -import org.onlab.onos.net.topology.TopologyEdge;
42 33
43 import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; 34 import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder;
44 35
...@@ -47,13 +38,7 @@ import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; ...@@ -47,13 +38,7 @@ import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder;
47 */ 38 */
48 @Component(immediate = true) 39 @Component(immediate = true)
49 public class HostToHostIntentCompiler 40 public class HostToHostIntentCompiler
50 - implements IntentCompiler<HostToHostIntent> { 41 + extends ConnectivityIntentCompiler<HostToHostIntent> {
51 -
52 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 - protected IntentExtensionService intentManager;
54 -
55 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 - protected PathService pathService;
57 42
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 43 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 protected HostService hostService; 44 protected HostService hostService;
...@@ -70,8 +55,8 @@ public class HostToHostIntentCompiler ...@@ -70,8 +55,8 @@ public class HostToHostIntentCompiler
70 55
71 @Override 56 @Override
72 public List<Intent> compile(HostToHostIntent intent) { 57 public List<Intent> compile(HostToHostIntent intent) {
73 - Path pathOne = getPath(intent.one(), intent.two()); 58 + Path pathOne = getPath(intent, intent.one(), intent.two());
74 - Path pathTwo = getPath(intent.two(), intent.one()); 59 + Path pathTwo = getPath(intent, intent.two(), intent.one());
75 60
76 Host one = hostService.getHost(intent.one()); 61 Host one = hostService.getHost(intent.one());
77 Host two = hostService.getHost(intent.two()); 62 Host two = hostService.getHost(intent.two());
...@@ -85,22 +70,7 @@ public class HostToHostIntentCompiler ...@@ -85,22 +70,7 @@ public class HostToHostIntentCompiler
85 HostToHostIntent intent) { 70 HostToHostIntent intent) {
86 TrafficSelector selector = builder(intent.selector()) 71 TrafficSelector selector = builder(intent.selector())
87 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); 72 .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
88 - return new PathIntent(intent.appId(), selector, intent.treatment(), 73 + return new PathIntent(intent.appId(), selector, intent.treatment(), path);
89 - path, new LinkResourceRequest[0]);
90 } 74 }
91 75
92 - private Path getPath(HostId one, HostId two) {
93 - Set<Path> paths = pathService.getPaths(one, two, new LinkWeight() {
94 - @Override
95 - public double weight(TopologyEdge edge) {
96 - return edge.link().type() == Link.Type.OPTICAL ? -1 : +1;
97 - }
98 - });
99 -
100 - if (paths.isEmpty()) {
101 - throw new PathNotFoundException("No path from host " + one + " to " + two);
102 - }
103 - // TODO: let's be more intelligent about this eventually
104 - return paths.iterator().next();
105 - }
106 } 76 }
......
...@@ -35,10 +35,13 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation; ...@@ -35,10 +35,13 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
35 import org.onlab.onos.net.flow.FlowRuleBatchOperation; 35 import org.onlab.onos.net.flow.FlowRuleBatchOperation;
36 import org.onlab.onos.net.flow.TrafficSelector; 36 import org.onlab.onos.net.flow.TrafficSelector;
37 import org.onlab.onos.net.flow.TrafficTreatment; 37 import org.onlab.onos.net.flow.TrafficTreatment;
38 +import org.onlab.onos.net.intent.Constraint;
38 import org.onlab.onos.net.intent.IntentExtensionService; 39 import org.onlab.onos.net.intent.IntentExtensionService;
39 import org.onlab.onos.net.intent.IntentInstaller; 40 import org.onlab.onos.net.intent.IntentInstaller;
40 import org.onlab.onos.net.intent.PathIntent; 41 import org.onlab.onos.net.intent.PathIntent;
42 +import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
41 import org.onlab.onos.net.resource.LinkResourceAllocations; 43 import org.onlab.onos.net.resource.LinkResourceAllocations;
44 +import org.onlab.onos.net.resource.LinkResourceRequest;
42 import org.onlab.onos.net.resource.LinkResourceService; 45 import org.onlab.onos.net.resource.LinkResourceService;
43 import org.slf4j.Logger; 46 import org.slf4j.Logger;
44 47
...@@ -79,13 +82,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -79,13 +82,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
79 82
80 @Override 83 @Override
81 public List<FlowRuleBatchOperation> install(PathIntent intent) { 84 public List<FlowRuleBatchOperation> install(PathIntent intent) {
82 - if (intent.resourceRequests().length > 0) { 85 + LinkResourceAllocations allocations = allocateResources(intent);
83 - LinkResourceAllocations allocations = allocateBandwidth(intent);
84 - if (allocations == null) {
85 - log.debug("Insufficient bandwidth available to install path intent {}", intent);
86 - return null;
87 - }
88 - }
89 86
90 TrafficSelector.Builder builder = 87 TrafficSelector.Builder builder =
91 DefaultTrafficSelector.builder(intent.selector()); 88 DefaultTrafficSelector.builder(intent.selector());
...@@ -110,6 +107,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -110,6 +107,10 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
110 107
111 @Override 108 @Override
112 public List<FlowRuleBatchOperation> uninstall(PathIntent intent) { 109 public List<FlowRuleBatchOperation> uninstall(PathIntent intent) {
110 + LinkResourceAllocations allocatedResources = resourceService.getAllocations(intent.id());
111 + if (allocatedResources != null) {
112 + resourceService.releaseResources(allocatedResources);
113 + }
113 TrafficSelector.Builder builder = 114 TrafficSelector.Builder builder =
114 DefaultTrafficSelector.builder(intent.selector()); 115 DefaultTrafficSelector.builder(intent.selector());
115 Iterator<Link> links = intent.path().links().iterator(); 116 Iterator<Link> links = intent.path().links().iterator();
...@@ -130,8 +131,23 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -130,8 +131,23 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
130 return Lists.newArrayList(new FlowRuleBatchOperation(rules)); 131 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
131 } 132 }
132 133
133 - private LinkResourceAllocations allocateBandwidth(PathIntent intent) { 134 + /**
134 - return resourceService.requestResources(intent.resourceRequests()[0]); 135 + * Allocate resources required for an intent.
136 + *
137 + * @param intent intent to allocate resource for
138 + * @return allocated resources if any are required, null otherwise
139 + */
140 + private LinkResourceAllocations allocateResources(PathIntent intent) {
141 + if (intent.constraints() == null) {
142 + return null;
143 + }
144 + LinkResourceRequest.Builder builder =
145 + DefaultLinkResourceRequest.builder(intent.id(), intent.path().links());
146 + for (Constraint constraint : intent.constraints()) {
147 + builder.addConstraint(constraint);
148 + }
149 + LinkResourceRequest request = builder.build();
150 + return request.resources().isEmpty() ? null : resourceService.requestResources(request);
135 } 151 }
136 152
137 // TODO refactor below this line... ---------------------------- 153 // TODO refactor below this line... ----------------------------
......
...@@ -15,31 +15,20 @@ ...@@ -15,31 +15,20 @@
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 -
22 import org.apache.felix.scr.annotations.Activate; 18 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 20 import org.apache.felix.scr.annotations.Deactivate;
25 -import org.apache.felix.scr.annotations.Reference;
26 -import org.apache.felix.scr.annotations.ReferenceCardinality;
27 -import org.onlab.onos.net.ConnectPoint;
28 import org.onlab.onos.net.DefaultEdgeLink; 21 import org.onlab.onos.net.DefaultEdgeLink;
29 import org.onlab.onos.net.DefaultPath; 22 import org.onlab.onos.net.DefaultPath;
30 import org.onlab.onos.net.Link; 23 import org.onlab.onos.net.Link;
31 import org.onlab.onos.net.Path; 24 import org.onlab.onos.net.Path;
32 import org.onlab.onos.net.intent.Intent; 25 import org.onlab.onos.net.intent.Intent;
33 -import org.onlab.onos.net.intent.IntentCompiler;
34 -import org.onlab.onos.net.intent.IntentExtensionService;
35 import org.onlab.onos.net.intent.PathIntent; 26 import org.onlab.onos.net.intent.PathIntent;
36 import org.onlab.onos.net.intent.PointToPointIntent; 27 import org.onlab.onos.net.intent.PointToPointIntent;
37 import org.onlab.onos.net.provider.ProviderId; 28 import org.onlab.onos.net.provider.ProviderId;
38 -import org.onlab.onos.net.resource.LinkResourceRequest; 29 +
39 -import org.onlab.onos.net.topology.LinkWeight; 30 +import java.util.ArrayList;
40 -import org.onlab.onos.net.topology.Topology; 31 +import java.util.List;
41 -import org.onlab.onos.net.topology.TopologyEdge;
42 -import org.onlab.onos.net.topology.TopologyService;
43 32
44 import static java.util.Arrays.asList; 33 import static java.util.Arrays.asList;
45 34
...@@ -48,14 +37,11 @@ import static java.util.Arrays.asList; ...@@ -48,14 +37,11 @@ import static java.util.Arrays.asList;
48 */ 37 */
49 @Component(immediate = true) 38 @Component(immediate = true)
50 public class PointToPointIntentCompiler 39 public class PointToPointIntentCompiler
51 - implements IntentCompiler<PointToPointIntent> { 40 + extends ConnectivityIntentCompiler<PointToPointIntent> {
52 41
53 - private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true); 42 + // TODO: use off-the-shell core provider ID
54 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 43 + private static final ProviderId PID =
55 - protected IntentExtensionService intentManager; 44 + new ProviderId("core", "org.onlab.onos.core", true);
56 -
57 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 - protected TopologyService topologyService;
59 45
60 @Activate 46 @Activate
61 public void activate() { 47 public void activate() {
...@@ -69,14 +55,15 @@ public class PointToPointIntentCompiler ...@@ -69,14 +55,15 @@ public class PointToPointIntentCompiler
69 55
70 @Override 56 @Override
71 public List<Intent> compile(PointToPointIntent intent) { 57 public List<Intent> compile(PointToPointIntent intent) {
72 - Path path = getPath(intent.ingressPoint(), intent.egressPoint()); 58 + Path path = getPath(intent, intent.ingressPoint().deviceId(),
59 + intent.egressPoint().deviceId());
73 60
74 List<Link> links = new ArrayList<>(); 61 List<Link> links = new ArrayList<>();
75 links.add(DefaultEdgeLink.createEdgeLink(intent.ingressPoint(), true)); 62 links.add(DefaultEdgeLink.createEdgeLink(intent.ingressPoint(), true));
76 links.addAll(path.links()); 63 links.addAll(path.links());
77 links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false)); 64 links.add(DefaultEdgeLink.createEdgeLink(intent.egressPoint(), false));
78 65
79 - return asList(createPathIntent(new DefaultPath(PID, links, path.cost() + 2, 66 + return asList(createPathIntent(new DefaultPath(PID, links, path.cost(),
80 path.annotations()), intent)); 67 path.annotations()), intent));
81 } 68 }
82 69
...@@ -90,34 +77,7 @@ public class PointToPointIntentCompiler ...@@ -90,34 +77,7 @@ public class PointToPointIntentCompiler
90 private Intent createPathIntent(Path path, 77 private Intent createPathIntent(Path path,
91 PointToPointIntent intent) { 78 PointToPointIntent intent) {
92 return new PathIntent(intent.appId(), 79 return new PathIntent(intent.appId(),
93 - intent.selector(), intent.treatment(), path, 80 + intent.selector(), intent.treatment(), path);
94 - new LinkResourceRequest[0]);
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 PathNotFoundException if a path cannot be found
104 - */
105 - private Path getPath(ConnectPoint one, ConnectPoint two) {
106 - Topology topology = topologyService.currentTopology();
107 - LinkWeight weight = new LinkWeight() {
108 - @Override
109 - public double weight(TopologyEdge edge) {
110 - return edge.link().type() == Link.Type.OPTICAL ? -1 : +1;
111 - }
112 - };
113 -
114 - Set<Path> paths = topologyService.getPaths(topology, one.deviceId(),
115 - two.deviceId(), weight);
116 - if (paths.isEmpty()) {
117 - throw new PathNotFoundException("No packet path from " + one + " to " + two);
118 } 81 }
119 82
120 - // TODO: let's be more intelligent about this eventually
121 - return paths.iterator().next();
122 - }
123 } 83 }
......
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 -}