Priyanka B
Committed by Gerrit Code Review

[ONOS-4051] Path computation algorithm implementation (Coding & UT).

Change-Id: If94be2ba2a010a203003b7ce38289b516ab20f59
...@@ -18,8 +18,10 @@ package org.onosproject.pce.pceservice; ...@@ -18,8 +18,10 @@ package org.onosproject.pce.pceservice;
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS; 19 import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
20 20
21 +import java.util.Collections;
21 import java.util.Iterator; 22 import java.util.Iterator;
22 import java.util.List; 23 import java.util.List;
24 +import java.util.Set;
23 25
24 import org.apache.felix.scr.annotations.Activate; 26 import org.apache.felix.scr.annotations.Activate;
25 import org.apache.felix.scr.annotations.Component; 27 import org.apache.felix.scr.annotations.Component;
...@@ -34,8 +36,15 @@ import org.onosproject.incubator.net.tunnel.Tunnel; ...@@ -34,8 +36,15 @@ import org.onosproject.incubator.net.tunnel.Tunnel;
34 import org.onosproject.incubator.net.tunnel.TunnelId; 36 import org.onosproject.incubator.net.tunnel.TunnelId;
35 import org.onosproject.incubator.net.tunnel.TunnelService; 37 import org.onosproject.incubator.net.tunnel.TunnelService;
36 import org.onosproject.net.DeviceId; 38 import org.onosproject.net.DeviceId;
39 +import org.onosproject.net.Path;
37 import org.onosproject.net.intent.Constraint; 40 import org.onosproject.net.intent.Constraint;
41 +import org.onosproject.net.device.DeviceService;
42 +import org.onosproject.net.resource.ResourceService;
43 +import org.onosproject.net.topology.LinkWeight;
44 +import org.onosproject.net.topology.PathService;
45 +import org.onosproject.net.topology.TopologyEdge;
38 import org.onosproject.pce.pceservice.api.PceService; 46 import org.onosproject.pce.pceservice.api.PceService;
47 +import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
39 import org.onosproject.store.serializers.KryoNamespaces; 48 import org.onosproject.store.serializers.KryoNamespaces;
40 import org.onosproject.store.service.DistributedSet; 49 import org.onosproject.store.service.DistributedSet;
41 import org.onosproject.store.service.Serializer; 50 import org.onosproject.store.service.Serializer;
...@@ -43,6 +52,8 @@ import org.onosproject.store.service.StorageService; ...@@ -43,6 +52,8 @@ import org.onosproject.store.service.StorageService;
43 import org.slf4j.Logger; 52 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory; 53 import org.slf4j.LoggerFactory;
45 54
55 +import com.google.common.collect.ImmutableList;
56 +
46 /** 57 /**
47 * Implementation of PCE service. 58 * Implementation of PCE service.
48 */ 59 */
...@@ -66,6 +77,15 @@ public class PceManager implements PceService { ...@@ -66,6 +77,15 @@ public class PceManager implements PceService {
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected StorageService storageService; 78 protected StorageService storageService;
68 79
80 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 + protected PathService pathService;
82 +
83 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 + protected ResourceService resourceService;
85 +
86 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 + protected DeviceService deviceService;
88 +
69 private ApplicationId appId; 89 private ApplicationId appId;
70 90
71 /** 91 /**
...@@ -92,6 +112,36 @@ public class PceManager implements PceService { ...@@ -92,6 +112,36 @@ public class PceManager implements PceService {
92 log.info("Stopped"); 112 log.info("Stopped");
93 } 113 }
94 114
115 + /**
116 + * Returns an edge-weight capable of evaluating links on the basis of the
117 + * specified constraints.
118 + *
119 + * @param constraints path constraints
120 + * @return edge-weight function
121 + */
122 + private LinkWeight weight(List<Constraint> constraints) {
123 + return new TeConstraintBasedLinkWeight(constraints);
124 + }
125 +
126 + /**
127 + * Computes a path between two devices.
128 + *
129 + * @param src ingress device
130 + * @param dst egress device
131 + * @param constraints path constraints
132 + * @return computed path based on constraints
133 + */
134 + protected Set<Path> computePath(DeviceId src, DeviceId dst, List<Constraint> constraints) {
135 + if (pathService == null) {
136 + return null;
137 + }
138 + Set<Path> paths = pathService.getPaths(src, dst, weight(constraints));
139 + if (!paths.isEmpty()) {
140 + return paths;
141 + }
142 + return null;
143 + }
144 +
95 //[TODO:] handle requests in queue 145 //[TODO:] handle requests in queue
96 @Override 146 @Override
97 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, 147 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
...@@ -103,8 +153,8 @@ public class PceManager implements PceService { ...@@ -103,8 +153,8 @@ public class PceManager implements PceService {
103 checkNotNull(lspType); 153 checkNotNull(lspType);
104 154
105 // TODO: compute and setup path. 155 // TODO: compute and setup path.
106 - 156 + //TODO: gets the path based on constraints and creates a tunnel in network via tunnel manager
107 - return true; 157 + return computePath(src, dst, constraints) != null ? true : false;
108 } 158 }
109 159
110 160
...@@ -159,4 +209,44 @@ public class PceManager implements PceService { ...@@ -159,4 +209,44 @@ public class PceManager implements PceService {
159 return value; 209 return value;
160 } 210 }
161 211
212 + protected class TeConstraintBasedLinkWeight implements LinkWeight {
213 +
214 + private final List<Constraint> constraints;
215 +
216 + /**
217 + * Creates a new edge-weight function capable of evaluating links
218 + * on the basis of the specified constraints.
219 + *
220 + * @param constraints path constraints
221 + */
222 + public TeConstraintBasedLinkWeight(List<Constraint> constraints) {
223 + if (constraints == null) {
224 + this.constraints = Collections.emptyList();
225 + } else {
226 + this.constraints = ImmutableList.copyOf(constraints);
227 + }
228 + }
229 +
230 + @Override
231 + public double weight(TopologyEdge edge) {
232 + if (!constraints.iterator().hasNext()) {
233 + //Takes default cost/hopcount as 1 if no constraints specified
234 + return 1.0;
235 + }
236 +
237 + Iterator<Constraint> it = constraints.iterator();
238 + double cost = 1;
239 +
240 + //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
241 + while (it.hasNext() && cost > 0) {
242 + Constraint constraint = it.next();
243 + if (constraint instanceof CapabilityConstraint) {
244 + cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
245 + } else {
246 + cost = constraint.cost(edge.link(), resourceService::isAvailable);
247 + }
248 + }
249 + return cost;
250 + }
251 + }
162 } 252 }
...\ No newline at end of file ...\ No newline at end of file
......
1 +/*
2 + * Copyright 2016-present 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.onosproject.pce.pceservice.constraint;
17 +
18 +import org.onosproject.net.AnnotationKeys;
19 +import org.onosproject.net.Device;
20 +import org.onosproject.net.Link;
21 +import org.onosproject.net.device.DeviceService;
22 +import org.onosproject.net.intent.ResourceContext;
23 +import org.onosproject.net.intent.constraint.BooleanConstraint;
24 +
25 +import java.util.Objects;
26 +
27 +import static com.google.common.base.MoreObjects.toStringHelper;
28 +
29 +/**
30 + * Constraint that evaluates whether devices satisfies capability.
31 + */
32 +public final class CapabilityConstraint extends BooleanConstraint {
33 +
34 + private final CapabilityType capabilityType;
35 + public static final String PCECC_CAPABILITY = "pceccCapability";
36 + public static final String SR_CAPABILITY = "srCapability";
37 + public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
38 + public static final String LSRID = "lsrId";
39 + public static final String L3 = "L3";
40 + public static final String TRUE = "true";
41 +
42 + /**
43 + * Represents about capability type.
44 + */
45 + public enum CapabilityType {
46 + /**
47 + * Signifies that path is created via signaling mode.
48 + */
49 + WITH_SIGNALLING(0),
50 +
51 + /**
52 + * Signifies that path is created via SR mode.
53 + */
54 + SR_WITHOUT_SIGNALLING(1),
55 +
56 + /**
57 + * Signifies that path is created via without signaling and without SR mode.
58 + */
59 + WITHOUT_SIGNALLING_AND_WITHOUT_SR(2);
60 +
61 + int value;
62 +
63 + /**
64 + * Assign val with the value as the capability type.
65 + *
66 + * @param val capability type
67 + */
68 + CapabilityType(int val) {
69 + value = val;
70 + }
71 +
72 + /**
73 + * Returns value of capability type.
74 + *
75 + * @return capability type
76 + */
77 + public byte type() {
78 + return (byte) value;
79 + }
80 + }
81 +
82 + // Constructor for serialization
83 + private CapabilityConstraint() {
84 + capabilityType = null;
85 + }
86 +
87 + /**
88 + * Creates a new capability constraint.
89 + *
90 + * @param capabilityType type of capability device supports
91 + */
92 + public CapabilityConstraint(CapabilityType capabilityType) {
93 + this.capabilityType = capabilityType;
94 + }
95 +
96 + /**
97 + * Creates a new capability constraint.
98 + *
99 + * @param capabilityType type of capability device supports
100 + * @return instance of CapabilityConstraint for specified capability type
101 + */
102 + public static CapabilityConstraint of(CapabilityType capabilityType) {
103 + return new CapabilityConstraint(capabilityType);
104 + }
105 +
106 + /**
107 + * Obtains type of capability.
108 + *
109 + * @return type of capability
110 + */
111 + public CapabilityType capabilityType() {
112 + return capabilityType;
113 + }
114 +
115 + /**
116 + * Validates the link based on capability constraint.
117 + *
118 + * @param link to validate source and destination based on capability constraint
119 + * @param deviceService instance of DeviceService
120 + * @return true if link satisfies capability constraint otherwise false
121 + */
122 + public boolean isValidLink(Link link, DeviceService deviceService) {
123 + if (deviceService == null) {
124 + return false;
125 + }
126 +
127 + Device srcDevice = deviceService.getDevice(link.src().deviceId());
128 + Device dstDevice = deviceService.getDevice(link.dst().deviceId());
129 +
130 + //TODO: Usage of annotations are for transient solution. In future will be replaces with the
131 + // network config service / Projection model.
132 + // L3 device
133 + if (srcDevice == null
134 + || dstDevice == null
135 + || srcDevice.annotations().value(AnnotationKeys.TYPE) == null
136 + || dstDevice.annotations().value(AnnotationKeys.TYPE) == null
137 + || !srcDevice.annotations().value(AnnotationKeys.TYPE).equals(L3)
138 + || !dstDevice.annotations().value(AnnotationKeys.TYPE).equals(L3)) {
139 + return false;
140 + }
141 +
142 + String scrLsrId = srcDevice.annotations().value(LSRID);
143 + String dstLsrId = dstDevice.annotations().value(LSRID);
144 +
145 + Device srcCapDevice = null;
146 + Device dstCapDevice = null;
147 +
148 + // Get Capability device
149 + Iterable<Device> devices = deviceService.getAvailableDevices();
150 + for (Device dev : devices) {
151 + if (dev.annotations().value(LSRID).equals(scrLsrId)) {
152 + srcCapDevice = dev;
153 + } else if (dev.annotations().value(LSRID).equals(dstLsrId)) {
154 + dstCapDevice = dev;
155 + }
156 + }
157 +
158 + if (srcCapDevice == null || dstCapDevice == null) {
159 + return false;
160 + }
161 +
162 + switch (capabilityType) {
163 + case WITH_SIGNALLING:
164 + return true;
165 + case WITHOUT_SIGNALLING_AND_WITHOUT_SR:
166 + if (srcCapDevice.annotations().value(PCECC_CAPABILITY) != null
167 + && dstCapDevice.annotations().value(PCECC_CAPABILITY) != null) {
168 + return srcCapDevice.annotations().value(PCECC_CAPABILITY).equals(TRUE)
169 + && dstCapDevice.annotations().value(PCECC_CAPABILITY).equals(TRUE);
170 + }
171 + return false;
172 + case SR_WITHOUT_SIGNALLING:
173 + if (srcCapDevice.annotations().value(LABEL_STACK_CAPABILITY) != null
174 + && dstCapDevice.annotations().value(LABEL_STACK_CAPABILITY) != null
175 + && srcCapDevice.annotations().value(SR_CAPABILITY) != null
176 + && dstCapDevice.annotations().value(SR_CAPABILITY) != null) {
177 + return srcCapDevice.annotations().value(LABEL_STACK_CAPABILITY).equals(TRUE)
178 + && dstCapDevice.annotations().value(LABEL_STACK_CAPABILITY).equals(TRUE)
179 + && srcCapDevice.annotations().value(SR_CAPABILITY).equals(TRUE)
180 + && dstCapDevice.annotations().value(SR_CAPABILITY).equals(TRUE);
181 + }
182 + return false;
183 + default:
184 + return false;
185 + }
186 + }
187 +
188 + @Override
189 + public boolean isValid(Link link, ResourceContext context) {
190 + return false;
191 + //Do nothing instead using isValidLink needs device service to validate link
192 + }
193 +
194 + @Override
195 + public int hashCode() {
196 + return Objects.hash(capabilityType);
197 + }
198 +
199 + @Override
200 + public boolean equals(Object obj) {
201 + if (this == obj) {
202 + return true;
203 + }
204 +
205 + if (obj instanceof CapabilityConstraint) {
206 + CapabilityConstraint other = (CapabilityConstraint) obj;
207 + return Objects.equals(this.capabilityType, other.capabilityType);
208 + }
209 +
210 + return false;
211 + }
212 +
213 + @Override
214 + public String toString() {
215 + return toStringHelper(this)
216 + .add("capabilityType", capabilityType)
217 + .toString();
218 + }
219 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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.onosproject.pce.pceservice.constraint;
17 +
18 +import org.onosproject.net.Link;
19 +import org.onosproject.net.Path;
20 +import org.onosproject.net.intent.ResourceContext;
21 +import org.onosproject.net.intent.Constraint;
22 +
23 +import java.util.Objects;
24 +
25 +import static com.google.common.base.MoreObjects.toStringHelper;
26 +import static com.google.common.base.Preconditions.checkNotNull;
27 +
28 +/**
29 + * Constraint that evaluates whether cost for a link is available, if yes return cost for that link.
30 + */
31 +public final class CostConstraint implements Constraint {
32 +
33 + /**
34 + * Represents about cost types.
35 + */
36 + public enum Type {
37 + /**
38 + * Signifies that cost is IGP cost.
39 + */
40 + COST(1),
41 +
42 + /**
43 + * Signifies that cost is TE cost.
44 + */
45 + TE_COST(2);
46 +
47 + int value;
48 +
49 + /**
50 + * Assign val with the value as the Cost type.
51 + *
52 + * @param val Cost type
53 + */
54 + Type(int val) {
55 + value = val;
56 + }
57 +
58 + /**
59 + * Returns value of Cost type.
60 + *
61 + * @return Cost type
62 + */
63 + public byte type() {
64 + return (byte) value;
65 + }
66 + }
67 +
68 + private final Type type;
69 + public static final String TE_COST = "teCost";
70 + public static final String COST = "cost";
71 +
72 + // Constructor for serialization
73 + private CostConstraint() {
74 + this.type = null;
75 + }
76 +
77 + /**
78 + * Creates a new cost constraint.
79 + *
80 + * @param type of a link
81 + */
82 + public CostConstraint(Type type) {
83 + this.type = checkNotNull(type, "Type cannot be null");
84 + }
85 +
86 + /**
87 + * Creates new CostConstraint with specified cost type.
88 + *
89 + * @param type of cost
90 + * @return instance of CostConstraint
91 + */
92 + public static CostConstraint of(Type type) {
93 + return new CostConstraint(type);
94 + }
95 +
96 + /**
97 + * Returns the type of a cost specified in a constraint.
98 + *
99 + * @return required cost type
100 + */
101 + public Type type() {
102 + return type;
103 + }
104 +
105 + @Override
106 + public int hashCode() {
107 + return Objects.hash(type);
108 + }
109 +
110 + @Override
111 + public boolean equals(Object obj) {
112 + if (this == obj) {
113 + return true;
114 + }
115 +
116 + if (obj instanceof CostConstraint) {
117 + CostConstraint other = (CostConstraint) obj;
118 + return Objects.equals(this.type, other.type);
119 + }
120 +
121 + return false;
122 + }
123 +
124 + @Override
125 + public String toString() {
126 + return toStringHelper(this)
127 + .add("type", type)
128 + .toString();
129 + }
130 +
131 + @Override
132 + public double cost(Link link, ResourceContext context) {
133 + //TODO: Usage of annotations are for transient solution. In future will be replaces with the
134 + // network config service / Projection model.
135 + switch (type) {
136 + case COST:
137 + if (link.annotations().value(COST) != null) {
138 + return Double.parseDouble(link.annotations().value(COST));
139 + }
140 +
141 + //If cost annotations absent return -1[It is not L3 device]
142 + return -1;
143 + case TE_COST:
144 + if (link.annotations().value(TE_COST) != null) {
145 + return Double.parseDouble(link.annotations().value(TE_COST));
146 + }
147 +
148 + //If TE cost annotations absent return -1[It is not L3 device]
149 + return -1;
150 + default:
151 + return -1;
152 + }
153 + }
154 +
155 + @Override
156 + public boolean validate(Path path, ResourceContext context) {
157 + // TODO Auto-generated method stub
158 + return false;
159 + }
160 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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.onosproject.pce.pceservice.constraint;
17 +
18 +import org.onlab.util.Bandwidth;
19 +import org.onosproject.net.Link;
20 +import org.onosproject.net.intent.ResourceContext;
21 +import org.onosproject.net.intent.constraint.BooleanConstraint;
22 +import org.onosproject.net.resource.Resources;
23 +
24 +import java.util.List;
25 +import java.util.Objects;
26 +import java.util.stream.Stream;
27 +
28 +import static com.google.common.base.MoreObjects.toStringHelper;
29 +
30 +/**
31 + * Constraint that evaluates whether links satisfies sharedbandwidth request.
32 + */
33 +public final class SharedBandwidthConstraint extends BooleanConstraint {
34 +
35 + private final List<Link> links;
36 + private final Bandwidth sharedBwValue;
37 + private final Bandwidth requestBwValue;
38 + //temporary variable declared to hold changed bandwidth value
39 + private Bandwidth changedBwValue;
40 +
41 + // Constructor for serialization
42 + private SharedBandwidthConstraint() {
43 + links = null;
44 + sharedBwValue = null;
45 + requestBwValue = null;
46 + }
47 +
48 + /**
49 + * Creates a new SharedBandwidth constraint.
50 + *
51 + * @param links shared links
52 + * @param sharedBwValue shared bandwidth of the links
53 + * @param requestBwValue requested bandwidth value
54 + */
55 + public SharedBandwidthConstraint(List<Link> links, Bandwidth sharedBwValue, Bandwidth requestBwValue) {
56 + this.links = links;
57 + this.sharedBwValue = sharedBwValue;
58 + this.requestBwValue = requestBwValue;
59 + }
60 +
61 + /**
62 + * Creates a new SharedBandwidth constraint.
63 + *
64 + * @param links shared links
65 + * @param sharedBwValue shared bandwidth of the links
66 + * @param requestBwValue requested bandwidth value
67 + * @return SharedBandwidth instance
68 + */
69 + public static SharedBandwidthConstraint of(List<Link> links, Bandwidth sharedBwValue, Bandwidth requestBwValue) {
70 + return new SharedBandwidthConstraint(links, sharedBwValue, requestBwValue);
71 + }
72 +
73 + /**
74 + * Obtains shared links.
75 + *
76 + * @return shared links
77 + */
78 + public List<Link> links() {
79 + return links;
80 + }
81 +
82 + /**
83 + * Obtains shared bandwidth of the links.
84 + *
85 + * @return shared bandwidth
86 + */
87 + public Bandwidth sharedBwValue() {
88 + return sharedBwValue;
89 + }
90 +
91 + /**
92 + * Obtains requested bandwidth value.
93 + *
94 + * @return requested bandwidth value
95 + */
96 + public Bandwidth requestBwValue() {
97 + return requestBwValue;
98 + }
99 +
100 + @Override
101 + public boolean isValid(Link link, ResourceContext context) {
102 + changedBwValue = requestBwValue;
103 + if (links.contains(link)) {
104 + changedBwValue = requestBwValue.isGreaterThan(sharedBwValue) ? requestBwValue.subtract(sharedBwValue)
105 + : Bandwidth.bps(0);
106 + }
107 +
108 + return Stream
109 + .of(link.src(), link.dst())
110 + .map(cp -> Resources.continuous(cp.deviceId(), cp.port(), Bandwidth.class).resource(
111 + changedBwValue.bps())).allMatch(context::isAvailable);
112 + }
113 +
114 + @Override
115 + public int hashCode() {
116 + return Objects.hash(requestBwValue, sharedBwValue, links);
117 + }
118 +
119 + @Override
120 + public boolean equals(Object obj) {
121 + if (this == obj) {
122 + return true;
123 + }
124 +
125 + if (obj instanceof SharedBandwidthConstraint) {
126 + SharedBandwidthConstraint other = (SharedBandwidthConstraint) obj;
127 + return Objects.equals(this.requestBwValue, other.requestBwValue)
128 + && Objects.equals(this.sharedBwValue, other.sharedBwValue)
129 + && Objects.equals(this.links, other.links);
130 + }
131 +
132 + return false;
133 + }
134 +
135 + @Override
136 + public String toString() {
137 + return toStringHelper(this)
138 + .add("requestBwValue", requestBwValue)
139 + .add("sharedBwValue", sharedBwValue)
140 + .add("links", links)
141 + .toString();
142 + }
143 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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 +
17 +/**
18 + * Constraints for path computation for PCE service.
19 + */
20 +package org.onosproject.pce.pceservice.constraint;
1 +/*
2 + * Copyright 2016-present 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.onosproject.pce.pceservice;
17 +
18 +import org.junit.After;
19 +import org.junit.Before;
20 +import org.junit.Test;
21 +import org.onlab.graph.AbstractGraphPathSearch;
22 +import org.onlab.graph.AdjacencyListsGraph;
23 +import org.onlab.graph.DijkstraGraphSearch;
24 +import org.onlab.graph.Graph;
25 +import org.onlab.graph.GraphPathSearch;
26 +import org.onlab.packet.ChassisId;
27 +import org.onlab.util.Bandwidth;
28 +import org.onlab.util.Tools;
29 +import org.onosproject.net.AnnotationKeys;
30 +import org.onosproject.net.ConnectPoint;
31 +import org.onosproject.net.DefaultAnnotations;
32 +import org.onosproject.net.DefaultDevice;
33 +import org.onosproject.net.DefaultLink;
34 +import org.onosproject.net.DefaultPath;
35 +import org.onosproject.net.Device;
36 +import org.onosproject.net.DeviceId;
37 +import org.onosproject.net.Link;
38 +import org.onosproject.net.Path;
39 +import org.onosproject.net.PortNumber;
40 +import org.onosproject.net.intent.Constraint;
41 +import org.onosproject.net.intent.IntentId;
42 +import org.onosproject.net.Device.Type;
43 +import org.onosproject.net.intent.constraint.BandwidthConstraint;
44 +import org.onosproject.net.device.DeviceServiceAdapter;
45 +import org.onosproject.net.resource.ContinuousResource;
46 +import org.onosproject.net.resource.ContinuousResourceId;
47 +import org.onosproject.net.resource.DiscreteResource;
48 +import org.onosproject.net.resource.DiscreteResourceId;
49 +import org.onosproject.net.resource.Resource;
50 +import org.onosproject.net.resource.ResourceAllocation;
51 +import org.onosproject.net.resource.ResourceConsumer;
52 +import org.onosproject.net.resource.ResourceId;
53 +import org.onosproject.net.resource.Resources;
54 +import org.onosproject.net.provider.ProviderId;
55 +import org.onosproject.net.topology.DefaultTopologyEdge;
56 +import org.onosproject.net.topology.DefaultTopologyVertex;
57 +import org.onosproject.net.topology.LinkWeight;
58 +import org.onosproject.net.topology.TopologyEdge;
59 +import org.onosproject.net.topology.TopologyVertex;
60 +import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
61 +import org.onosproject.pce.pceservice.constraint.CostConstraint;
62 +import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
63 +
64 +import com.google.common.collect.ImmutableList;
65 +import com.google.common.collect.ImmutableSet;
66 +
67 +import java.util.Collections;
68 +import java.util.HashMap;
69 +import java.util.HashSet;
70 +import java.util.Iterator;
71 +import java.util.LinkedList;
72 +import java.util.List;
73 +import java.util.Map;
74 +import java.util.Optional;
75 +import java.util.Set;
76 +import java.util.stream.Collectors;
77 +
78 +import static org.hamcrest.MatcherAssert.assertThat;
79 +import static org.hamcrest.core.Is.is;
80 +import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
81 +import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
82 +import static com.google.common.collect.ImmutableSet.of;
83 +import static org.onosproject.net.resource.Resources.continuous;
84 +import static org.onosproject.net.Link.Type.DIRECT;
85 +import static org.onosproject.net.Link.State.ACTIVE;
86 +import static org.onosproject.net.DeviceId.deviceId;
87 +import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
88 +import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
89 +
90 +/**
91 + * Test for CSPF path computation.
92 + */
93 +public class PathComputationTest {
94 +
95 + private final MockPathResourceService resourceService = new MockPathResourceService();
96 + private final MockDeviceService deviceService = new MockDeviceService();
97 + private PceManager pceManager = new PceManager();
98 + public static ProviderId providerId = new ProviderId("pce", "foo");
99 + private static final String DEVICE1 = "D001";
100 + private static final String DEVICE2 = "D002";
101 + private static final String DEVICE3 = "D003";
102 + private static final String DEVICE4 = "D004";
103 + private static final String DEVICE5 = "D005";
104 + public static final String PCEPDEVICE1 = "PD001";
105 + public static final String PCEPDEVICE2 = "PD002";
106 + public static final String PCEPDEVICE3 = "PD003";
107 + public static final String PCEPDEVICE4 = "PD004";
108 + private static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
109 + private static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
110 + private static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
111 + private static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
112 + private static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
113 + private static final String ANNOTATION_COST = "cost";
114 + private static final String ANNOTATION_TE_COST = "teCost";
115 + private static final String UNKNOWN = "unknown";
116 + public static final String LSRID = "lsrId";
117 + public static final String L3 = "L3";
118 + public static final String PCECC_CAPABILITY = "pceccCapability";
119 + public static final String SR_CAPABILITY = "srCapability";
120 + public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
121 +
122 + @Before
123 + public void startUp() {
124 + pceManager.resourceService = resourceService;
125 + pceManager.deviceService = deviceService;
126 + }
127 +
128 + /**
129 + * Selects path computation algorithm.
130 + *
131 + * @return graph path search algorithm
132 + */
133 + private AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
134 + return new DijkstraGraphSearch<>();
135 + }
136 +
137 + /**
138 + * Returns link for two devices.
139 + *
140 + * @param device source device
141 + * @param port source port
142 + * @param device2 destination device
143 + * @param port2 destination port
144 + * @return link
145 + */
146 + private Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
147 + ConnectPoint src = new ConnectPoint(DeviceId.deviceId(device), PortNumber.portNumber(port));
148 + ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(device2), PortNumber.portNumber(port2));
149 + Link curLink;
150 + DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
151 + if (setCost) {
152 + annotationBuilder.set(ANNOTATION_COST, String.valueOf(value));
153 + } else {
154 + annotationBuilder.set(ANNOTATION_TE_COST, String.valueOf(value));
155 + }
156 +
157 + //TODO:If cost not set cost : default value case
158 + curLink = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
159 + .providerId(PathComputationTest.providerId).annotations(annotationBuilder.build()).build();
160 + return curLink;
161 + }
162 +
163 + @After
164 + public void tearDown() {
165 + pceManager.resourceService = null;
166 + pceManager.deviceService = null;
167 + }
168 +
169 + /**
170 + * Returns an edge-weight capable of evaluating links on the basis of the
171 + * specified constraints.
172 + *
173 + * @param constraints path constraints
174 + * @return edge-weight function
175 + */
176 + private LinkWeight weight(List<Constraint> constraints) {
177 + return new MockTeConstraintBasedLinkWeight(constraints);
178 + }
179 +
180 + private Set<Path> computePath(Link link1, Link link2, Link link3, Link link4, List<Constraint> constraints) {
181 + Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4),
182 + of(new DefaultTopologyEdge(D1, D2, link1),
183 + new DefaultTopologyEdge(D2, D4, link2),
184 + new DefaultTopologyEdge(D1, D3, link3),
185 + new DefaultTopologyEdge(D3, D4, link4)));
186 +
187 + GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
188 + graphSearch().search(graph, D1, D4, weight(constraints), ALL_PATHS);
189 + ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
190 + for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
191 + builder.add(networkPath(path));
192 + }
193 + return builder.build();
194 + }
195 +
196 + private class MockDeviceService extends DeviceServiceAdapter {
197 + List<Device> devices = new LinkedList<>();
198 +
199 + private void addDevice(Device dev) {
200 + devices.add(dev);
201 + }
202 +
203 + @Override
204 + public Device getDevice(DeviceId deviceId) {
205 + for (Device dev : devices) {
206 + if (dev.id().equals(deviceId)) {
207 + return dev;
208 + }
209 + }
210 + return null;
211 + }
212 +
213 + @Override
214 + public Iterable<Device> getAvailableDevices() {
215 + return devices;
216 + }
217 + }
218 +
219 + private class MockTeConstraintBasedLinkWeight implements LinkWeight {
220 +
221 + private final List<Constraint> constraints;
222 +
223 + /**
224 + * Creates a new edge-weight function capable of evaluating links
225 + * on the basis of the specified constraints.
226 + *
227 + * @param constraints path constraints
228 + */
229 + MockTeConstraintBasedLinkWeight(List<Constraint> constraints) {
230 + if (constraints == null) {
231 + this.constraints = Collections.emptyList();
232 + } else {
233 + this.constraints = ImmutableList.copyOf(constraints);
234 + }
235 + }
236 +
237 + public double weight(TopologyEdge edge) {
238 + if (!constraints.iterator().hasNext()) {
239 + //Takes default cost/hopcount as 1 if no constraints specified
240 + return 1.0;
241 + }
242 +
243 + Iterator<Constraint> it = constraints.iterator();
244 + double cost = 1;
245 +
246 + //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
247 + while (it.hasNext() && cost > 0) {
248 + Constraint constraint = it.next();
249 + if (constraint instanceof CapabilityConstraint) {
250 + cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
251 + } else {
252 + cost = constraint.cost(edge.link(), resourceService::isAvailable);
253 + }
254 + }
255 + return cost;
256 + }
257 + }
258 +
259 + private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
260 + List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
261 + return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
262 + }
263 +
264 + /**
265 + * Test Resource service for path computation.
266 + */
267 + private class MockPathResourceService extends ResourceServiceAdapter {
268 + private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
269 + private Map<ResourceId, List<ResourceAllocation>> resourcesAllocations = new HashMap<>();
270 +
271 + @Override
272 + public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
273 + for (Resource resource: resources) {
274 + if (resource instanceof ContinuousResource) {
275 + List<ResourceAllocation> allocs = new LinkedList<>();
276 + allocs.add(new ResourceAllocation(resource, consumer));
277 + resourcesAllocations.put(resource.id(), allocs);
278 + }
279 + }
280 + return resources.stream()
281 + .map(x -> new ResourceAllocation(x, consumer))
282 + .collect(Collectors.toList());
283 + }
284 +
285 + @Override
286 + public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
287 + if (id instanceof ContinuousResourceId) {
288 + return resourcesAllocations.get(id);
289 + }
290 + DiscreteResource discrete = Resources.discrete((DiscreteResourceId) id).resource();
291 + return Optional.ofNullable(assignment.get(discrete))
292 + .map(x -> ImmutableList.of(new ResourceAllocation(discrete, x)))
293 + .orElse(ImmutableList.of());
294 + }
295 +
296 + @Override
297 + public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
298 + return getAvailableResources(parent).stream()
299 + .filter(x -> x.isTypeOf(cls))
300 + .collect(Collectors.toSet());
301 + }
302 +
303 + @Override
304 + public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
305 + return getAvailableResources(parent).stream()
306 + .filter(x -> x.isTypeOf(cls))
307 + .flatMap(x -> Tools.stream(x.valueAs(cls)))
308 + .collect(Collectors.toSet());
309 + }
310 +
311 + @Override
312 + public boolean isAvailable(Resource resource) {
313 + if (resource instanceof DiscreteResource) {
314 + return true;
315 + }
316 +
317 + if (resource instanceof ContinuousResource) {
318 + List<ResourceAllocation> resalloc = resourcesAllocations.get(resource.id());
319 +
320 + if ((resalloc != null) && (!resalloc.isEmpty())) {
321 + if (((ContinuousResource) resalloc.iterator().next().resource()).value()
322 + >= ((ContinuousResource) resource).value()) {
323 + return true;
324 + }
325 + }
326 + }
327 + return false;
328 + }
329 + }
330 +
331 + /**
332 + * All links with different costs with L1-L2 as least cost path.
333 + */
334 + @Test
335 + public void testpathComputationCase1() {
336 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
337 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
338 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
339 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
340 +
341 + CostConstraint costConst = CostConstraint.of(COST);
342 + List<Constraint> constraints = new LinkedList<>();
343 + constraints.add(costConst);
344 +
345 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
346 +
347 + List<Link> links = new LinkedList<>();
348 +
349 + links.add(link1);
350 + links.add(link2);
351 +
352 + assertThat(paths.iterator().next().links(), is(links));
353 + assertThat(paths.iterator().next().cost(), is((double) 70));
354 + }
355 +
356 + /**
357 + * Links with same cost 100 except link3.
358 + */
359 + @Test
360 + public void testpathComputationCase2() {
361 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 100);
362 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
363 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 1000);
364 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
365 +
366 + CostConstraint costConst = CostConstraint.of(COST);
367 + List<Constraint> constraints = new LinkedList<>();
368 + constraints.add(costConst);
369 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
370 +
371 + List<Link> links = new LinkedList<>();
372 + links.add(link1);
373 + links.add(link2);
374 +
375 + assertThat(paths.iterator().next().links(), is(links));
376 + assertThat(paths.iterator().next().cost(), is((double) 200));
377 + }
378 +
379 + /**
380 + * Path which satisfy bandwidth as a constraint with 10bps.
381 + */
382 + @Test
383 + public void testpathComputationCase3() {
384 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
385 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
386 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
387 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
388 +
389 + List<Resource> resources = new LinkedList<>();
390 +
391 + resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class)
392 + .resource(50));
393 + resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class)
394 + .resource(50));
395 + resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class)
396 + .resource(100));
397 + resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class)
398 + .resource(100));
399 +
400 + resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class)
401 + .resource(50));
402 + resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class)
403 + .resource(50));
404 + resources.add(continuous(link3.dst().deviceId(), link3.src().port(), Bandwidth.class)
405 + .resource(100));
406 + resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class)
407 + .resource(100));
408 +
409 + resourceService.allocate(IntentId.valueOf(70), resources);
410 +
411 + BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(10.0));
412 +
413 + List<Constraint> constraints = new LinkedList<>();
414 + constraints.add(bandwidthConst);
415 +
416 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
417 +
418 + assertThat(paths.iterator().next().cost(), is((double) 2));
419 + }
420 +
421 + /**
422 + * Path which satisfy bandwidth as a constraint with 60bps.
423 + */
424 + @Test
425 + public void testpathComputationCase4() {
426 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
427 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 50);
428 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
429 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
430 +
431 + List<Resource> resources = new LinkedList<>();
432 +
433 + resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
434 + resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
435 + resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
436 + resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
437 +
438 + resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
439 + resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
440 + resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
441 + resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
442 +
443 + resourceService.allocate(IntentId.valueOf(70), resources);
444 +
445 + BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(60.0));
446 +
447 + List<Constraint> constraints = new LinkedList<>();
448 + constraints.add(bandwidthConst);
449 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
450 +
451 + assertThat(paths.iterator().next().cost(), is((double) 2));
452 + }
453 +
454 + /**
455 + * Shared bandwidth as L1, L2 with its value 10 bps and bandwidth constraint as 20 bps.
456 + */
457 + @Test
458 + public void testpathComputationCase5() {
459 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
460 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
461 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
462 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
463 +
464 + List<Resource> resources = new LinkedList<>();
465 +
466 + resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
467 + resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
468 + resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
469 + resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
470 +
471 + resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
472 + resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
473 + resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
474 + resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
475 + resourceService.allocate(IntentId.valueOf(70), resources);
476 +
477 + List<Constraint> constraints = new LinkedList<>();
478 +
479 + List<Link> sharedLinks = new LinkedList<>();
480 +
481 + List<Link> links = new LinkedList<>();
482 + links.add(link1);
483 + links.add(link2);
484 +
485 + CostConstraint costConst = CostConstraint.of(COST);
486 + sharedLinks.addAll(links);
487 + SharedBandwidthConstraint sharedBw = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(10),
488 + Bandwidth.bps(20.0));
489 + constraints.add(sharedBw);
490 + constraints.add(costConst);
491 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
492 + assertThat(paths.iterator().next().links(), is(links));
493 + assertThat(paths.iterator().next().cost(), is((double) 70));
494 + }
495 +
496 + /**
497 + * Shared bandwidth as L1, L2 with its value 20 bps and bandwidth constraint as 10 bps.
498 + */
499 + @Test
500 + public void testpathComputationCase6() {
501 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
502 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
503 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
504 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
505 +
506 + List<Resource> resources = new LinkedList<>();
507 +
508 + resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
509 + resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
510 + resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
511 + resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
512 +
513 + resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
514 + resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
515 + resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
516 + resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
517 + resourceService.allocate(IntentId.valueOf(70), resources);
518 +
519 + List<Constraint> constraints = new LinkedList<>();
520 +
521 + List<Link> sharedLinks = new LinkedList<>();
522 +
523 + List<Link> links = new LinkedList<>();
524 + links.add(link1);
525 + links.add(link2);
526 + CostConstraint costConst = CostConstraint.of(COST);
527 + sharedLinks.addAll(links);
528 + SharedBandwidthConstraint sharedBwConst = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(20),
529 + Bandwidth.bps(10.0));
530 + constraints.add(sharedBwConst);
531 + constraints.add(costConst);
532 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
533 +
534 + assertThat(paths.iterator().next().links(), is(links));
535 + assertThat(paths.iterator().next().cost(), is((double) 70));
536 + }
537 +
538 + /**
539 + * Path without constraints.
540 + */
541 + @Test
542 + public void testpathComputationCase7() {
543 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
544 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
545 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
546 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
547 + List<Constraint> constraints = new LinkedList<>();
548 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
549 +
550 + assertThat(paths.iterator().next().cost(), is((double) 2));
551 + }
552 +
553 + /**
554 + * With TeCost as a constraints.
555 + */
556 + @Test
557 + public void testpathComputationCase8() {
558 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
559 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
560 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
561 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
562 +
563 + CostConstraint tecostConst = CostConstraint.of(TE_COST);
564 +
565 + List<Constraint> constraints = new LinkedList<>();
566 + constraints.add(tecostConst);
567 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
568 +
569 + List<Link> links = new LinkedList<>();
570 + links.add(link1);
571 + links.add(link2);
572 + assertThat(paths.iterator().next().links(), is(links));
573 + assertThat(paths.iterator().next().cost(), is((double) 70));
574 + }
575 +
576 + /**
577 + * With device supporting RSVP capability as a constraints.
578 + */
579 + @Test
580 + public void testpathComputationCase9() {
581 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
582 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
583 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
584 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
585 +
586 + CostConstraint tecostConst = CostConstraint.of(TE_COST);
587 + CapabilityConstraint capabilityConst = CapabilityConstraint
588 + .of(CapabilityConstraint.CapabilityType.WITH_SIGNALLING);
589 +
590 + List<Constraint> constraints = new LinkedList<>();
591 + constraints.add(capabilityConst);
592 + constraints.add(tecostConst);
593 + //Device1
594 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
595 + builder.set(AnnotationKeys.TYPE, L3);
596 + builder.set(LSRID, "1.1.1.1");
597 + addDevice(DEVICE1, builder);
598 +
599 + //Device2
600 + builder = DefaultAnnotations.builder();
601 + builder.set(AnnotationKeys.TYPE, L3);
602 + builder.set(LSRID, "2.2.2.2");
603 + addDevice(DEVICE2, builder);
604 +
605 + //Device3
606 + builder = DefaultAnnotations.builder();
607 + builder.set(AnnotationKeys.TYPE, L3);
608 + builder.set(LSRID, "3.3.3.3");
609 + addDevice(DEVICE3, builder);
610 +
611 + //Device4
612 + builder = DefaultAnnotations.builder();
613 + builder.set(AnnotationKeys.TYPE, L3);
614 + builder.set(LSRID, "4.4.4.4");
615 + addDevice(DEVICE4, builder);
616 +
617 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
618 +
619 + List<Link> links = new LinkedList<>();
620 + links.add(link1);
621 + links.add(link2);
622 + assertThat(paths.iterator().next().links(), is(links));
623 + assertThat(paths.iterator().next().cost(), is((double) 70));
624 + }
625 +
626 + /**
627 + * Devices supporting CR capability.
628 + */
629 + @Test
630 + public void testpathComputationCase10() {
631 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
632 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
633 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
634 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
635 +
636 + CapabilityConstraint capabilityConst = CapabilityConstraint
637 + .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
638 +
639 + List<Constraint> constraints = new LinkedList<>();
640 + constraints.add(capabilityConst);
641 + CostConstraint costConst = CostConstraint.of(COST);
642 + constraints.add(costConst);
643 + //Device1
644 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
645 + builder.set(AnnotationKeys.TYPE, L3);
646 + builder.set(LSRID, "1.1.1.1");
647 + addDevice(DEVICE1, builder);
648 + builder.set(PCECC_CAPABILITY, "true");
649 + addDevice(PCEPDEVICE1, builder);
650 +
651 + //Device2
652 + builder = DefaultAnnotations.builder();
653 + builder.set(AnnotationKeys.TYPE, L3);
654 + builder.set(LSRID, "2.2.2.2");
655 + addDevice(DEVICE2, builder);
656 + builder.set(PCECC_CAPABILITY, "true");
657 + addDevice(PCEPDEVICE2, builder);
658 +
659 + //Device3
660 + builder = DefaultAnnotations.builder();
661 + builder.set(AnnotationKeys.TYPE, L3);
662 + builder.set(LSRID, "3.3.3.3");
663 + addDevice(DEVICE3, builder);
664 + builder.set(PCECC_CAPABILITY, "true");
665 + addDevice(PCEPDEVICE3, builder);
666 +
667 + //Device4
668 + builder = DefaultAnnotations.builder();
669 + builder.set(AnnotationKeys.TYPE, L3);
670 + builder.set(LSRID, "4.4.4.4");
671 + addDevice(DEVICE4, builder);
672 + builder.set(PCECC_CAPABILITY, "true");
673 + addDevice(PCEPDEVICE4, builder);
674 +
675 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
676 +
677 + List<Link> links = new LinkedList<>();
678 + links.add(link1);
679 + links.add(link2);
680 + assertThat(paths.iterator().next().links(), is(links));
681 + assertThat(paths.iterator().next().cost(), is((double) 70));
682 + }
683 +
684 + /**
685 + * Device supporting SR capability.
686 + */
687 + @Test
688 + public void testpathComputationCase11() {
689 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
690 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
691 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
692 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
693 +
694 + CapabilityConstraint capabilityConst = CapabilityConstraint
695 + .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
696 +
697 + List<Constraint> constraints = new LinkedList<>();
698 + constraints.add(capabilityConst);
699 + CostConstraint costConst = CostConstraint.of(COST);
700 + constraints.add(costConst);
701 + //Device1
702 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
703 + builder.set(AnnotationKeys.TYPE, L3);
704 + builder.set(LSRID, "1.1.1.1");
705 + addDevice(DEVICE1, builder);
706 + builder.set(SR_CAPABILITY, "true");
707 + builder.set(LABEL_STACK_CAPABILITY, "true");
708 + addDevice(PCEPDEVICE1, builder);
709 +
710 + //Device2
711 + builder = DefaultAnnotations.builder();
712 + builder.set(AnnotationKeys.TYPE, L3);
713 + builder.set(LSRID, "2.2.2.2");
714 + addDevice(DEVICE2, builder);
715 + builder.set(SR_CAPABILITY, "true");
716 + builder.set(LABEL_STACK_CAPABILITY, "true");
717 + addDevice(PCEPDEVICE2, builder);
718 +
719 + //Device3
720 + builder = DefaultAnnotations.builder();
721 + builder.set(AnnotationKeys.TYPE, L3);
722 + builder.set(LSRID, "3.3.3.3");
723 + addDevice(DEVICE3, builder);
724 + builder.set(SR_CAPABILITY, "true");
725 + builder.set(LABEL_STACK_CAPABILITY, "true");
726 + addDevice(PCEPDEVICE3, builder);
727 +
728 + //Device4
729 + builder = DefaultAnnotations.builder();
730 + builder.set(AnnotationKeys.TYPE, L3);
731 + builder.set(LSRID, "4.4.4.4");
732 + addDevice(DEVICE4, builder);
733 + builder.set(SR_CAPABILITY, "true");
734 + builder.set(LABEL_STACK_CAPABILITY, "true");
735 + addDevice(PCEPDEVICE4, builder);
736 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
737 +
738 + List<Link> links = new LinkedList<>();
739 + links.add(link1);
740 + links.add(link2);
741 + assertThat(paths.iterator().next().links(), is(links));
742 + assertThat(paths.iterator().next().cost(), is((double) 70));
743 + }
744 +
745 + /**
746 + * Path with TE and SR capability constraint.
747 + */
748 + @Test
749 + public void testpathComputationCase12() {
750 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
751 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
752 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
753 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
754 +
755 + CostConstraint tecostConst = CostConstraint.of(TE_COST);
756 + CapabilityConstraint capabilityConst = CapabilityConstraint
757 + .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
758 +
759 + List<Constraint> constraints = new LinkedList<>();
760 +
761 + constraints.add(capabilityConst);
762 + constraints.add(tecostConst);
763 + //Device1
764 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
765 + builder.set(AnnotationKeys.TYPE, L3);
766 + builder.set(LSRID, "1.1.1.1");
767 + addDevice(DEVICE1, builder);
768 + builder.set(SR_CAPABILITY, "true");
769 + builder.set(LABEL_STACK_CAPABILITY, "true");
770 + addDevice(PCEPDEVICE1, builder);
771 +
772 + //Device2
773 + builder = DefaultAnnotations.builder();
774 + builder.set(AnnotationKeys.TYPE, L3);
775 + builder.set(LSRID, "2.2.2.2");
776 + addDevice(DEVICE2, builder);
777 + builder.set(SR_CAPABILITY, "true");
778 + builder.set(LABEL_STACK_CAPABILITY, "true");
779 + addDevice(PCEPDEVICE2, builder);
780 +
781 + //Device3
782 + builder = DefaultAnnotations.builder();
783 + builder.set(AnnotationKeys.TYPE, L3);
784 + builder.set(LSRID, "3.3.3.3");
785 + addDevice(DEVICE3, builder);
786 + builder.set(SR_CAPABILITY, "true");
787 + builder.set(LABEL_STACK_CAPABILITY, "true");
788 + addDevice(PCEPDEVICE3, builder);
789 +
790 + //Device4
791 + builder = DefaultAnnotations.builder();
792 + builder.set(AnnotationKeys.TYPE, L3);
793 + builder.set(LSRID, "4.4.4.4");
794 + addDevice(DEVICE4, builder);
795 + builder.set(SR_CAPABILITY, "true");
796 + builder.set(LABEL_STACK_CAPABILITY, "true");
797 + addDevice(PCEPDEVICE4, builder);
798 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
799 +
800 + List<Link> links = new LinkedList<>();
801 + links.add(link1);
802 + links.add(link2);
803 + assertThat(paths.iterator().next().links(), is(links));
804 + assertThat(paths.iterator().next().cost(), is((double) 70));
805 + }
806 +
807 + /**
808 + * Path with capability constraint and with default cost.
809 + */
810 + @Test
811 + public void testpathComputationCase13() {
812 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
813 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
814 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
815 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
816 +
817 + CapabilityConstraint capabilityConst = CapabilityConstraint
818 + .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
819 +
820 + List<Constraint> constraints = new LinkedList<>();
821 + constraints.add(capabilityConst);
822 + //Device1
823 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
824 + builder.set(AnnotationKeys.TYPE, L3);
825 + builder.set(LSRID, "1.1.1.1");
826 + addDevice(DEVICE1, builder);
827 + builder.set(SR_CAPABILITY, "true");
828 + builder.set(LABEL_STACK_CAPABILITY, "true");
829 + addDevice(PCEPDEVICE1, builder);
830 +
831 + //Device2
832 + builder = DefaultAnnotations.builder();
833 + builder.set(AnnotationKeys.TYPE, L3);
834 + builder.set(LSRID, "2.2.2.2");
835 + addDevice(DEVICE2, builder);
836 + builder.set(SR_CAPABILITY, "true");
837 + builder.set(LABEL_STACK_CAPABILITY, "true");
838 + addDevice(PCEPDEVICE2, builder);
839 +
840 + //Device3
841 + builder = DefaultAnnotations.builder();
842 + builder.set(AnnotationKeys.TYPE, L3);
843 + builder.set(LSRID, "3.3.3.3");
844 + addDevice(DEVICE3, builder);
845 + builder.set(SR_CAPABILITY, "true");
846 + builder.set(LABEL_STACK_CAPABILITY, "true");
847 + addDevice(PCEPDEVICE3, builder);
848 +
849 + //Device4
850 + builder = DefaultAnnotations.builder();
851 + builder.set(AnnotationKeys.TYPE, L3);
852 + builder.set(LSRID, "4.4.4.4");
853 + addDevice(DEVICE4, builder);
854 + builder.set(SR_CAPABILITY, "true");
855 + builder.set(LABEL_STACK_CAPABILITY, "true");
856 + addDevice(PCEPDEVICE4, builder);
857 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
858 +
859 + List<Link> links = new LinkedList<>();
860 + links.add(link1);
861 + links.add(link2);
862 + assertThat(paths.iterator().next().cost(), is((double) 2));
863 + }
864 +
865 + /**
866 + * Test case with empty constraints.
867 + */
868 + @Test
869 + public void testpathComputationCase14() {
870 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
871 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
872 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
873 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
874 +
875 + List<Constraint> constraints = new LinkedList<>();
876 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
877 +
878 + assertThat(paths.iterator().next().cost(), is((double) 2));
879 + }
880 +
881 + /**
882 + * Test case with constraints as null.
883 + */
884 + @Test
885 + public void testpathComputationCase15() {
886 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
887 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
888 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
889 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
890 +
891 + List<Constraint> constraints = null;
892 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
893 +
894 + assertThat(paths.iterator().next().cost(), is((double) 2));
895 + }
896 +
897 + /**
898 + * Path with cost constraint.
899 + */
900 + @Test
901 + public void testpathComputationCase16() {
902 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
903 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
904 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
905 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
906 + Link link5 = addLink(DEVICE4, 90, DEVICE5, 100, true, 20);
907 +
908 + CostConstraint costConst = CostConstraint.of(COST);
909 +
910 + List<Constraint> constraints = new LinkedList<>();
911 + constraints.add(costConst);
912 + Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4, D5),
913 + of(new DefaultTopologyEdge(D1, D2, link1),
914 + new DefaultTopologyEdge(D2, D4, link2),
915 + new DefaultTopologyEdge(D1, D3, link3),
916 + new DefaultTopologyEdge(D3, D4, link4),
917 + new DefaultTopologyEdge(D4, D5, link5)));
918 +
919 + GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
920 + graphSearch().search(graph, D1, D5, weight(constraints), ALL_PATHS);
921 + ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
922 + for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
923 + builder.add(networkPath(path));
924 + }
925 +
926 + List<Link> links = new LinkedList<>();
927 + links.add(link3);
928 + links.add(link4);
929 + links.add(link5);
930 + assertThat(builder.build().iterator().next().links(), is(links));
931 + assertThat(builder.build().iterator().next().cost(), is((double) 40));
932 + }
933 +
934 + /**
935 + * D3 doesn't support capability constraint, so path is L1-L2.
936 + */
937 + @Test
938 + public void testpathComputationCase17() {
939 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
940 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
941 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
942 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
943 +
944 + CapabilityConstraint capabilityConst = CapabilityConstraint
945 + .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
946 +
947 + List<Constraint> constraints = new LinkedList<>();
948 + constraints.add(capabilityConst);
949 + //Device1
950 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
951 + builder.set(AnnotationKeys.TYPE, L3);
952 + builder.set(LSRID, "1.1.1.1");
953 + addDevice(DEVICE1, builder);
954 + builder.set(PCECC_CAPABILITY, "true");
955 + addDevice(PCEPDEVICE1, builder);
956 +
957 + //Device2
958 + builder = DefaultAnnotations.builder();
959 + builder.set(AnnotationKeys.TYPE, L3);
960 + builder.set(LSRID, "2.2.2.2");
961 + addDevice(DEVICE2, builder);
962 + builder.set(PCECC_CAPABILITY, "true");
963 + addDevice(PCEPDEVICE2, builder);
964 +
965 + //Device4
966 + builder = DefaultAnnotations.builder();
967 + builder.set(AnnotationKeys.TYPE, L3);
968 + builder.set(LSRID, "4.4.4.4");
969 + addDevice(DEVICE4, builder);
970 + builder.set(PCECC_CAPABILITY, "true");
971 + addDevice(PCEPDEVICE4, builder);
972 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
973 +
974 + List<Link> links = new LinkedList<>();
975 + links.add(link1);
976 + links.add(link2);
977 +
978 + assertThat(paths.iterator().next().links(), is(links));
979 + assertThat(paths.iterator().next().cost(), is((double) 2));
980 + }
981 +
982 + /**
983 + * L2 doesn't support cost constraint and D3 doesn't support capability constraint, both constraint fails hence no
984 + * path.
985 + */
986 + @Test
987 + public void testpathComputationCase18() {
988 + Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
989 + Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
990 + Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
991 + Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
992 +
993 + CapabilityConstraint capabilityConst = CapabilityConstraint
994 + .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
995 + CostConstraint costConst = CostConstraint.of(COST);
996 + List<Constraint> constraints = new LinkedList<>();
997 + constraints.add(capabilityConst);
998 + constraints.add(costConst);
999 + //Device1
1000 + DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
1001 + builder.set(AnnotationKeys.TYPE, L3);
1002 + builder.set(LSRID, "1.1.1.1");
1003 + addDevice(DEVICE2, builder);
1004 + builder.set(PCECC_CAPABILITY, "true");
1005 + addDevice(PCEPDEVICE1, builder);
1006 +
1007 + //Device2
1008 + builder = DefaultAnnotations.builder();
1009 + builder.set(AnnotationKeys.TYPE, L3);
1010 + builder.set(LSRID, "2.2.2.2");
1011 + addDevice(DEVICE2, builder);
1012 + builder.set(PCECC_CAPABILITY, "true");
1013 + addDevice(PCEPDEVICE2, builder);
1014 +
1015 + //Device4
1016 + builder = DefaultAnnotations.builder();
1017 + builder.set(AnnotationKeys.TYPE, L3);
1018 + builder.set(LSRID, "4.4.4.4");
1019 + addDevice(DEVICE4, builder);
1020 + builder.set(PCECC_CAPABILITY, "true");
1021 + addDevice(PCEPDEVICE4, builder);
1022 + Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
1023 +
1024 + assertThat(paths, is(new HashSet<>()));
1025 + }
1026 +
1027 + private void addDevice(String device, DefaultAnnotations.Builder builder) {
1028 + deviceService.addDevice(new DefaultDevice(ProviderId.NONE, deviceId(device), Type.ROUTER,
1029 + UNKNOWN, UNKNOWN, UNKNOWN,
1030 + UNKNOWN, new ChassisId(), builder.build()));
1031 + }
1032 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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.onosproject.pce.pceservice;
17 +
18 +import org.onosproject.net.resource.DiscreteResourceId;
19 +import org.onosproject.net.resource.ResourceAllocation;
20 +import org.onosproject.net.resource.ResourceConsumer;
21 +import org.onosproject.net.resource.ResourceId;
22 +import org.onosproject.net.resource.ResourceListener;
23 +import org.onosproject.net.resource.Resource;
24 +import org.onosproject.net.resource.ResourceService;
25 +
26 +import java.util.Collection;
27 +import java.util.List;
28 +import java.util.Set;
29 +
30 +/**
31 + * Adapter for resource service for path computation.
32 + */
33 +public class ResourceServiceAdapter implements ResourceService {
34 +
35 + @Override
36 + public void addListener(ResourceListener listener) {
37 + // TODO Auto-generated method stub
38 + }
39 +
40 + @Override
41 + public void removeListener(ResourceListener listener) {
42 + // TODO Auto-generated method stub
43 + }
44 +
45 + @Override
46 + public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
47 + // TODO Auto-generated method stub
48 + return null;
49 + }
50 +
51 + @Override
52 + public boolean release(List<ResourceAllocation> allocations) {
53 + // TODO Auto-generated method stub
54 + return false;
55 + }
56 +
57 + @Override
58 + public boolean release(ResourceConsumer consumer) {
59 + // TODO Auto-generated method stub
60 + return false;
61 + }
62 +
63 + @Override
64 + public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
65 + // TODO Auto-generated method stub
66 + return null;
67 + }
68 +
69 + @Override
70 + public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
71 + // TODO Auto-generated method stub
72 + return null;
73 + }
74 +
75 + @Override
76 + public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
77 + // TODO Auto-generated method stub
78 + return null;
79 + }
80 +
81 + @Override
82 + public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
83 + // TODO Auto-generated method stub
84 + return null;
85 + }
86 +
87 + @Override
88 + public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
89 + // TODO Auto-generated method stub
90 + return null;
91 + }
92 +
93 + @Override
94 + public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
95 + // TODO Auto-generated method stub
96 + return null;
97 + }
98 +
99 + @Override
100 + public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
101 + // TODO Auto-generated method stub
102 + return null;
103 + }
104 +
105 + @Override
106 + public boolean isAvailable(Resource resource) {
107 + // TODO Auto-generated method stub
108 + return false;
109 + }
110 +}