Priyanka B
Committed by Gerrit Code Review

[ONOS-5187] Compute path with Explicit path objects

Change-Id: Id34dbef9bd6cfa9971d0d10adf4bbc141f03a913
Showing 22 changed files with 1143 additions and 93 deletions
...@@ -105,5 +105,10 @@ ...@@ -105,5 +105,10 @@
105 <groupId>org.onosproject</groupId> 105 <groupId>org.onosproject</groupId>
106 <artifactId>onos-app-pcep-api</artifactId> 106 <artifactId>onos-app-pcep-api</artifactId>
107 </dependency> 107 </dependency>
108 - </dependencies> 108 + <dependency>
109 + <groupId>org.easymock</groupId>
110 + <artifactId>easymock</artifactId>
111 + <scope>test</scope>
112 + </dependency>
113 + </dependencies>
109 </project> 114 </project>
......
...@@ -24,10 +24,13 @@ import org.onosproject.cli.AbstractShellCommand; ...@@ -24,10 +24,13 @@ import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.incubator.net.tunnel.Tunnel; 24 import org.onosproject.incubator.net.tunnel.Tunnel;
25 import org.onosproject.incubator.net.tunnel.TunnelId; 25 import org.onosproject.incubator.net.tunnel.TunnelId;
26 import org.onosproject.net.AnnotationKeys; 26 import org.onosproject.net.AnnotationKeys;
27 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
27 import org.onosproject.pce.pceservice.api.PceService; 28 import org.onosproject.pce.pceservice.api.PceService;
28 29
29 import org.slf4j.Logger; 30 import org.slf4j.Logger;
30 31
32 +import java.util.List;
33 +
31 /** 34 /**
32 * Supports quering PCE path. 35 * Supports quering PCE path.
33 */ 36 */
...@@ -72,17 +75,28 @@ public class PceQueryPathCommand extends AbstractShellCommand { ...@@ -72,17 +75,28 @@ public class PceQueryPathCommand extends AbstractShellCommand {
72 * @param tunnel pce tunnel 75 * @param tunnel pce tunnel
73 */ 76 */
74 void display(Tunnel tunnel) { 77 void display(Tunnel tunnel) {
75 - print("\npath-id : %s \n" + 78 + List<ExplicitPathInfo> explicitPathInfoList = AbstractShellCommand.get(PceService.class)
76 - "source : %s \n" + 79 + .explicitPathInfoList(tunnel.tunnelName().value());
77 - "destination : %s \n" + 80 +
78 - "path-type : %s \n" + 81 + print("\npath-id : %s \n" +
79 - "symbolic-path-name : %s \n" + 82 + "source : %s \n" +
83 + "destination : %s \n" +
84 + "path-type : %s \n" +
85 + "symbolic-path-name : %s \n" +
80 "constraints: \n" + 86 "constraints: \n" +
81 - " cost : %s \n" + 87 + " cost : %s \n" +
82 - " bandwidth : %s", 88 + " bandwidth : %s",
83 tunnel.tunnelId().id(), tunnel.path().src().deviceId().toString(), 89 tunnel.tunnelId().id(), tunnel.path().src().deviceId().toString(),
84 tunnel.path().dst().deviceId().toString(), 90 tunnel.path().dst().deviceId().toString(),
85 tunnel.type().name(), tunnel.tunnelName(), tunnel.annotations().value(COST_TYPE), 91 tunnel.type().name(), tunnel.tunnelName(), tunnel.annotations().value(COST_TYPE),
86 tunnel.annotations().value(AnnotationKeys.BANDWIDTH)); 92 tunnel.annotations().value(AnnotationKeys.BANDWIDTH));
93 + if (explicitPathInfoList != null) {
94 + for (ExplicitPathInfo e : explicitPathInfoList) {
95 + print("explicitPathObjects : \n" +
96 + " type : %s \n" +
97 + " value : %s ",
98 + String.valueOf(e.type().type()), e.value().toString());
99 + }
100 + }
87 } 101 }
88 } 102 }
......
...@@ -15,27 +15,35 @@ ...@@ -15,27 +15,35 @@
15 */ 15 */
16 package org.onosproject.pce.cli; 16 package org.onosproject.pce.cli;
17 17
18 +import static org.onosproject.net.Link.State.ACTIVE;
19 +import static org.onosproject.net.Link.Type.DIRECT;
18 import static org.slf4j.LoggerFactory.getLogger; 20 import static org.slf4j.LoggerFactory.getLogger;
19 21
20 import java.util.Collection; 22 import java.util.Collection;
21 import java.util.List; 23 import java.util.List;
22 import java.util.LinkedList; 24 import java.util.LinkedList;
23 25
26 +import com.google.common.collect.Lists;
27 +
24 import org.apache.karaf.shell.commands.Argument; 28 import org.apache.karaf.shell.commands.Argument;
25 import org.apache.karaf.shell.commands.Command; 29 import org.apache.karaf.shell.commands.Command;
26 import org.apache.karaf.shell.commands.Option; 30 import org.apache.karaf.shell.commands.Option;
27 -
28 import org.onlab.util.DataRateUnit; 31 import org.onlab.util.DataRateUnit;
29 import org.onosproject.cli.AbstractShellCommand; 32 import org.onosproject.cli.AbstractShellCommand;
30 import org.onosproject.incubator.net.tunnel.Tunnel; 33 import org.onosproject.incubator.net.tunnel.Tunnel;
31 import org.onosproject.incubator.net.tunnel.TunnelService; 34 import org.onosproject.incubator.net.tunnel.TunnelService;
35 +import org.onosproject.net.ConnectPoint;
36 +import org.onosproject.net.DefaultLink;
32 import org.onosproject.net.DeviceId; 37 import org.onosproject.net.DeviceId;
38 +import org.onosproject.net.NetworkResource;
39 +import org.onosproject.net.PortNumber;
33 import org.onosproject.net.intent.constraint.BandwidthConstraint; 40 import org.onosproject.net.intent.constraint.BandwidthConstraint;
34 import org.onosproject.net.intent.Constraint; 41 import org.onosproject.net.intent.Constraint;
42 +import org.onosproject.net.provider.ProviderId;
43 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
35 import org.onosproject.pce.pceservice.constraint.CostConstraint; 44 import org.onosproject.pce.pceservice.constraint.CostConstraint;
36 import org.onosproject.pce.pceservice.LspType; 45 import org.onosproject.pce.pceservice.LspType;
37 import org.onosproject.pce.pceservice.api.PceService; 46 import org.onosproject.pce.pceservice.api.PceService;
38 -
39 import org.slf4j.Logger; 47 import org.slf4j.Logger;
40 48
41 /** 49 /**
...@@ -44,6 +52,16 @@ import org.slf4j.Logger; ...@@ -44,6 +52,16 @@ import org.slf4j.Logger;
44 @Command(scope = "onos", name = "pce-setup-path", description = "Supports creating pce path.") 52 @Command(scope = "onos", name = "pce-setup-path", description = "Supports creating pce path.")
45 public class PceSetupPathCommand extends AbstractShellCommand { 53 public class PceSetupPathCommand extends AbstractShellCommand {
46 private final Logger log = getLogger(getClass()); 54 private final Logger log = getLogger(getClass());
55 + public static final byte SUBTYPE_DEVICEID = 0;
56 + public static final byte SUBTYPE_LINK = 1;
57 + public static final byte SUBTYPE_INDEX = 1;
58 + public static final byte TYPE_INDEX = 0;
59 +
60 + public static final byte DEVICEID_INDEX = 2;
61 + public static final byte SOURCE_DEVICEID_INDEX = 2;
62 + public static final byte SOURCE_PORTNO_INDEX = 3;
63 + public static final byte DESTINATION_DEVICEID_INDEX = 4;
64 + public static final byte DESTINATION_PORTNO_INDEX = 5;
47 65
48 @Argument(index = 0, name = "src", description = "source device.", required = true, multiValued = false) 66 @Argument(index = 0, name = "src", description = "source device.", required = true, multiValued = false)
49 String src = null; 67 String src = null;
...@@ -69,6 +87,15 @@ public class PceSetupPathCommand extends AbstractShellCommand { ...@@ -69,6 +87,15 @@ public class PceSetupPathCommand extends AbstractShellCommand {
69 + "Data rate unit is in BPS.", required = false, multiValued = false) 87 + "Data rate unit is in BPS.", required = false, multiValued = false)
70 double bandwidth = 0.0; 88 double bandwidth = 0.0;
71 89
90 + @Option(name = "-e", aliases = "--explicitPathObjects", description = "List of strict and loose hopes",
91 + required = false, multiValued = true)
92 + String[] explicitPathInfoStrings;
93 +
94 + //explicitPathInfo format : Type/SubType/Value(DeviceId or Link info)
95 + //If Value is Device : Type/SubType/deviceId
96 + //If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo
97 + List<ExplicitPathInfo> explicitPathInfo = Lists.newLinkedList();
98 +
72 @Override 99 @Override
73 protected void execute() { 100 protected void execute() {
74 log.info("executing pce-setup-path"); 101 log.info("executing pce-setup-path");
...@@ -114,7 +141,50 @@ public class PceSetupPathCommand extends AbstractShellCommand { ...@@ -114,7 +141,50 @@ public class PceSetupPathCommand extends AbstractShellCommand {
114 CostConstraint.Type costType = CostConstraint.Type.values()[cost - 1]; 141 CostConstraint.Type costType = CostConstraint.Type.values()[cost - 1];
115 listConstrnt.add(CostConstraint.of(costType)); 142 listConstrnt.add(CostConstraint.of(costType));
116 143
117 - if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType)) { 144 + if (explicitPathInfoStrings != null) {
145 + for (String str : explicitPathInfoStrings) {
146 + String[] splitted = str.split("/");
147 + DeviceId deviceId;
148 + NetworkResource res = null;
149 + PortNumber portNo;
150 + int explicitPathType = Integer.parseInt(splitted[TYPE_INDEX]);
151 + if ((explicitPathType < 0) || (explicitPathType > 1)) {
152 + error("Explicit path validation failed");
153 + return;
154 + }
155 +
156 + //subtype 0 = deviceId, 1 = link
157 + //subtype is required to store either as deviceId or Link
158 + if (splitted[DEVICEID_INDEX] != null && Integer.parseInt(splitted[SUBTYPE_INDEX]) == SUBTYPE_DEVICEID) {
159 + res = DeviceId.deviceId(splitted[DEVICEID_INDEX]);
160 + } else if (Integer.parseInt(splitted[SUBTYPE_INDEX]) == SUBTYPE_LINK
161 + && splitted[SOURCE_DEVICEID_INDEX] != null
162 + && splitted[SOURCE_PORTNO_INDEX] != null
163 + && splitted[DESTINATION_DEVICEID_INDEX] != null
164 + && splitted[DESTINATION_PORTNO_INDEX] != null) {
165 +
166 + deviceId = DeviceId.deviceId(splitted[SOURCE_DEVICEID_INDEX]);
167 + portNo = PortNumber.portNumber(splitted[SOURCE_PORTNO_INDEX]);
168 + ConnectPoint cpSrc = new ConnectPoint(deviceId, portNo);
169 + deviceId = DeviceId.deviceId(splitted[DESTINATION_DEVICEID_INDEX]);
170 + portNo = PortNumber.portNumber(splitted[DESTINATION_PORTNO_INDEX]);
171 + ConnectPoint cpDst = new ConnectPoint(deviceId, portNo);
172 + res = DefaultLink.builder()
173 + .providerId(ProviderId.NONE)
174 + .src(cpSrc)
175 + .dst(cpDst)
176 + .type(DIRECT)
177 + .state(ACTIVE)
178 + .build();
179 + } else {
180 + error("Explicit path validation failed");
181 + return;
182 + }
183 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.values()[explicitPathType], res);
184 + explicitPathInfo.add(obj);
185 + }
186 + }
187 + if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, explicitPathInfo)) {
118 error("Path creation failed."); 188 error("Path creation failed.");
119 } 189 }
120 } 190 }
......
...@@ -18,14 +18,18 @@ package org.onosproject.pce.pceservice; ...@@ -18,14 +18,18 @@ package org.onosproject.pce.pceservice;
18 18
19 import static com.google.common.base.MoreObjects.toStringHelper; 19 import static com.google.common.base.MoreObjects.toStringHelper;
20 20
21 +import java.util.Collection;
22 +import java.util.List;
21 import java.util.Objects; 23 import java.util.Objects;
22 24
25 +import org.onlab.rest.BaseResource;
23 import org.onlab.util.DataRateUnit; 26 import org.onlab.util.DataRateUnit;
24 import org.onosproject.incubator.net.tunnel.Tunnel; 27 import org.onosproject.incubator.net.tunnel.Tunnel;
25 import org.onosproject.incubator.net.tunnel.TunnelId; 28 import org.onosproject.incubator.net.tunnel.TunnelId;
26 import org.onosproject.net.intent.constraint.BandwidthConstraint; 29 import org.onosproject.net.intent.constraint.BandwidthConstraint;
27 import org.onosproject.net.intent.Constraint; 30 import org.onosproject.net.intent.Constraint;
28 import org.onosproject.pce.pceservice.constraint.CostConstraint; 31 import org.onosproject.pce.pceservice.constraint.CostConstraint;
32 +import org.onosproject.pce.pcestore.api.PceStore;
29 33
30 /** 34 /**
31 * Implementation of an entity which provides functionalities of pce path. 35 * Implementation of an entity which provides functionalities of pce path.
...@@ -39,6 +43,7 @@ public final class DefaultPcePath implements PcePath { ...@@ -39,6 +43,7 @@ public final class DefaultPcePath implements PcePath {
39 private String name; // symbolic-path-name 43 private String name; // symbolic-path-name
40 private Constraint costConstraint; // cost constraint 44 private Constraint costConstraint; // cost constraint
41 private Constraint bandwidthConstraint; // bandwidth constraint 45 private Constraint bandwidthConstraint; // bandwidth constraint
46 + private Collection<ExplicitPathInfo> explicitPathInfo; //list of explicit path info
42 47
43 /** 48 /**
44 * Initializes PCE path attributes. 49 * Initializes PCE path attributes.
...@@ -50,10 +55,11 @@ public final class DefaultPcePath implements PcePath { ...@@ -50,10 +55,11 @@ public final class DefaultPcePath implements PcePath {
50 * @param name symbolic-path-name 55 * @param name symbolic-path-name
51 * @param costConstrnt cost constraint 56 * @param costConstrnt cost constraint
52 * @param bandwidthConstrnt bandwidth constraint 57 * @param bandwidthConstrnt bandwidth constraint
58 + * @param explicitPathInfo list of explicit path info
53 */ 59 */
54 private DefaultPcePath(TunnelId id, String src, String dst, LspType lspType, 60 private DefaultPcePath(TunnelId id, String src, String dst, LspType lspType,
55 - String name, Constraint costConstrnt, Constraint bandwidthConstrnt) { 61 + String name, Constraint costConstrnt, Constraint bandwidthConstrnt,
56 - 62 + Collection<ExplicitPathInfo> explicitPathInfo) {
57 this.id = id; 63 this.id = id;
58 this.source = src; 64 this.source = src;
59 this.destination = dst; 65 this.destination = dst;
...@@ -61,6 +67,7 @@ public final class DefaultPcePath implements PcePath { ...@@ -61,6 +67,7 @@ public final class DefaultPcePath implements PcePath {
61 this.name = name; 67 this.name = name;
62 this.costConstraint = costConstrnt; 68 this.costConstraint = costConstrnt;
63 this.bandwidthConstraint = bandwidthConstrnt; 69 this.bandwidthConstraint = bandwidthConstrnt;
70 + this.explicitPathInfo = explicitPathInfo;
64 } 71 }
65 72
66 @Override 73 @Override
...@@ -114,6 +121,11 @@ public final class DefaultPcePath implements PcePath { ...@@ -114,6 +121,11 @@ public final class DefaultPcePath implements PcePath {
114 } 121 }
115 122
116 @Override 123 @Override
124 + public Collection<ExplicitPathInfo> explicitPathInfo() {
125 + return explicitPathInfo;
126 + }
127 +
128 + @Override
117 public PcePath copy(PcePath path) { 129 public PcePath copy(PcePath path) {
118 if (null != path.source()) { 130 if (null != path.source()) {
119 this.source = path.source(); 131 this.source = path.source();
...@@ -138,7 +150,8 @@ public final class DefaultPcePath implements PcePath { ...@@ -138,7 +150,8 @@ public final class DefaultPcePath implements PcePath {
138 150
139 @Override 151 @Override
140 public int hashCode() { 152 public int hashCode() {
141 - return Objects.hash(id, source, destination, lspType, name, costConstraint, bandwidthConstraint); 153 + return Objects.hash(id, source, destination, lspType, name, costConstraint, bandwidthConstraint,
154 + explicitPathInfo);
142 } 155 }
143 156
144 @Override 157 @Override
...@@ -154,7 +167,8 @@ public final class DefaultPcePath implements PcePath { ...@@ -154,7 +167,8 @@ public final class DefaultPcePath implements PcePath {
154 && Objects.equals(lspType, that.lspType) 167 && Objects.equals(lspType, that.lspType)
155 && Objects.equals(name, that.name) 168 && Objects.equals(name, that.name)
156 && Objects.equals(costConstraint, that.costConstraint) 169 && Objects.equals(costConstraint, that.costConstraint)
157 - && Objects.equals(bandwidthConstraint, that.bandwidthConstraint); 170 + && Objects.equals(bandwidthConstraint, that.bandwidthConstraint)
171 + && Objects.equals(explicitPathInfo, that.explicitPathInfo);
158 } 172 }
159 return false; 173 return false;
160 } 174 }
...@@ -170,6 +184,7 @@ public final class DefaultPcePath implements PcePath { ...@@ -170,6 +184,7 @@ public final class DefaultPcePath implements PcePath {
170 .add("name", name) 184 .add("name", name)
171 .add("costConstraint", costConstraint) 185 .add("costConstraint", costConstraint)
172 .add("bandwidthConstraint", bandwidthConstraint) 186 .add("bandwidthConstraint", bandwidthConstraint)
187 + .add("explicitPathInfo", explicitPathInfo)
173 .toString(); 188 .toString();
174 } 189 }
175 190
...@@ -185,7 +200,7 @@ public final class DefaultPcePath implements PcePath { ...@@ -185,7 +200,7 @@ public final class DefaultPcePath implements PcePath {
185 /** 200 /**
186 * Builder class for pce path. 201 * Builder class for pce path.
187 */ 202 */
188 - public static final class Builder implements PcePath.Builder { 203 + public static final class Builder extends BaseResource implements PcePath.Builder {
189 private TunnelId id; 204 private TunnelId id;
190 private String source; 205 private String source;
191 private String destination; 206 private String destination;
...@@ -193,6 +208,7 @@ public final class DefaultPcePath implements PcePath { ...@@ -193,6 +208,7 @@ public final class DefaultPcePath implements PcePath {
193 private String name; 208 private String name;
194 private Constraint costConstraint; 209 private Constraint costConstraint;
195 private Constraint bandwidthConstraint; 210 private Constraint bandwidthConstraint;
211 + private Collection<ExplicitPathInfo> explicitPathInfo;
196 212
197 @Override 213 @Override
198 public Builder id(String id) { 214 public Builder id(String id) {
...@@ -240,6 +256,12 @@ public final class DefaultPcePath implements PcePath { ...@@ -240,6 +256,12 @@ public final class DefaultPcePath implements PcePath {
240 } 256 }
241 257
242 @Override 258 @Override
259 + public Builder explicitPathInfo(Collection<ExplicitPathInfo> explicitPathInfo) {
260 + this.explicitPathInfo = explicitPathInfo;
261 + return this;
262 + }
263 +
264 + @Override
243 public Builder of(Tunnel tunnel) { 265 public Builder of(Tunnel tunnel) {
244 this.id = TunnelId.valueOf(tunnel.tunnelId().id()); 266 this.id = TunnelId.valueOf(tunnel.tunnelId().id());
245 this.source = tunnel.path().src().deviceId().toString(); 267 this.source = tunnel.path().src().deviceId().toString();
...@@ -264,13 +286,20 @@ public final class DefaultPcePath implements PcePath { ...@@ -264,13 +286,20 @@ public final class DefaultPcePath implements PcePath {
264 DataRateUnit.valueOf("BPS")); 286 DataRateUnit.valueOf("BPS"));
265 } 287 }
266 288
289 + PceStore pceStore = get(PceStore.class);
290 + List<ExplicitPathInfo> explicitPathInfoList = pceStore
291 + .getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value());
292 + if (explicitPathInfoList != null) {
293 + this.explicitPathInfo = explicitPathInfoList;
294 + }
295 +
267 return this; 296 return this;
268 } 297 }
269 298
270 @Override 299 @Override
271 public PcePath build() { 300 public PcePath build() {
272 return new DefaultPcePath(id, source, destination, lspType, name, 301 return new DefaultPcePath(id, source, destination, lspType, name,
273 - costConstraint, bandwidthConstraint); 302 + costConstraint, bandwidthConstraint, explicitPathInfo);
274 } 303 }
275 } 304 }
276 } 305 }
......
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.NetworkResource;
19 +
20 +import com.google.common.annotations.Beta;
21 +
22 +import java.util.Objects;
23 +
24 +/**
25 + * Representation of explicit path info consists of contraints (strict / loose) to compute path.
26 + */
27 +@Beta
28 +public final class ExplicitPathInfo {
29 +
30 + private final Type type;
31 +
32 + //Can be Link or DeviceId
33 + private final NetworkResource value;
34 +
35 + public enum Type {
36 + /**
37 + * Signifies that path includes strict node or link.
38 + */
39 + STRICT(0),
40 +
41 + /**
42 + * Signifies that path includes loose node or link.
43 + */
44 + LOOSE(1);
45 +
46 + int value;
47 +
48 + /**
49 + * Assign val with the value as the type.
50 + *
51 + * @param val type
52 + */
53 + Type(int val) {
54 + value = val;
55 + }
56 +
57 + /**
58 + * Returns value of type.
59 + *
60 + * @return type
61 + */
62 + public byte type() {
63 + return (byte) value;
64 + }
65 + }
66 +
67 + /**
68 + * Creates instance of explicit path object.
69 + *
70 + * @param type specifies whether strict or loose node/link
71 + * @param value specifies deviceId or link
72 + */
73 + public ExplicitPathInfo(Type type, NetworkResource value) {
74 + this.type = type;
75 + this.value = value;
76 + }
77 +
78 + /**
79 + * Returns explicit path type.
80 + *
81 + * @return explicit path type as strict/loose
82 + */
83 + public Type type() {
84 + return type;
85 + }
86 +
87 + /**
88 + * Returns deviceId or link.
89 + *
90 + * @return deviceId or link
91 + */
92 + public NetworkResource value() {
93 + return value;
94 + }
95 +
96 + @Override
97 + public int hashCode() {
98 + return Objects.hash(type, value);
99 + }
100 +
101 + @Override
102 + public boolean equals(Object obj) {
103 + if (this == obj) {
104 + return true;
105 + }
106 + if (obj instanceof ExplicitPathInfo) {
107 + final ExplicitPathInfo other = (ExplicitPathInfo) obj;
108 + return Objects.equals(this.type, other.type)
109 + && Objects.equals(this.value, other.value);
110 + }
111 + return false;
112 + }
113 +}
...@@ -24,6 +24,7 @@ import java.util.LinkedList; ...@@ -24,6 +24,7 @@ import java.util.LinkedList;
24 import java.util.List; 24 import java.util.List;
25 import java.util.Optional; 25 import java.util.Optional;
26 import java.util.Set; 26 import java.util.Set;
27 +
27 import org.apache.felix.scr.annotations.Activate; 28 import org.apache.felix.scr.annotations.Activate;
28 import org.apache.felix.scr.annotations.Component; 29 import org.apache.felix.scr.annotations.Component;
29 import org.apache.felix.scr.annotations.Deactivate; 30 import org.apache.felix.scr.annotations.Deactivate;
...@@ -48,9 +49,11 @@ import org.onosproject.mastership.MastershipService; ...@@ -48,9 +49,11 @@ import org.onosproject.mastership.MastershipService;
48 import org.onosproject.net.config.NetworkConfigService; 49 import org.onosproject.net.config.NetworkConfigService;
49 import org.onosproject.net.DefaultAnnotations; 50 import org.onosproject.net.DefaultAnnotations;
50 import org.onosproject.net.DefaultAnnotations.Builder; 51 import org.onosproject.net.DefaultAnnotations.Builder;
52 +import org.onosproject.net.DefaultPath;
51 import org.onosproject.net.Device; 53 import org.onosproject.net.Device;
52 import org.onosproject.net.DeviceId; 54 import org.onosproject.net.DeviceId;
53 import org.onosproject.net.Link; 55 import org.onosproject.net.Link;
56 +import org.onosproject.net.NetworkResource;
54 import org.onosproject.net.Path; 57 import org.onosproject.net.Path;
55 import org.onosproject.net.device.DeviceService; 58 import org.onosproject.net.device.DeviceService;
56 import org.onosproject.net.intent.Constraint; 59 import org.onosproject.net.intent.Constraint;
...@@ -86,6 +89,7 @@ import org.slf4j.LoggerFactory; ...@@ -86,6 +89,7 @@ import org.slf4j.LoggerFactory;
86 89
87 import com.google.common.collect.ImmutableList; 90 import com.google.common.collect.ImmutableList;
88 import com.google.common.collect.ImmutableSet; 91 import com.google.common.collect.ImmutableSet;
92 +import com.google.common.collect.Sets;
89 93
90 import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT; 94 import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
91 import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE; 95 import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
...@@ -230,10 +234,177 @@ public class PceManager implements PceService { ...@@ -230,10 +234,177 @@ public class PceManager implements PceService {
230 return ImmutableSet.of(); 234 return ImmutableSet.of();
231 } 235 }
232 236
233 - //[TODO:] handle requests in queue 237 + //Computes the partial path from partial computed path to specified dst.
238 + private List<Path> computePartialPath(List<Path> computedPath, DeviceId src, DeviceId dst,
239 + List<Constraint> constraints) {
240 + int size = computedPath.size();
241 + Path path = null;
242 + DeviceId deviceId = size == 0 ? src :
243 + computedPath.get(size - 1).dst().deviceId();
244 +
245 + Set<Path> tempComputePath = computePath(deviceId, dst, constraints);
246 + if (tempComputePath.isEmpty()) {
247 + return null;
248 + }
249 +
250 + //if path validation fails return null
251 + //Validate computed path to avoid loop in the path
252 + for (Path p : tempComputePath) {
253 + if (pathValidation(computedPath, p)) {
254 + path = p;
255 + break;
256 + }
257 + }
258 + if (path == null) {
259 + return null;
260 + }
261 +
262 + //Store the partial path result in a list
263 + computedPath.add(path);
264 + return computedPath;
265 + }
266 +
267 + private List<DeviceId> createListOfDeviceIds(List<? extends NetworkResource> list) {
268 + List<Link> links = new LinkedList<>();
269 + if (!list.isEmpty() && list.iterator().next() instanceof Path) {
270 + for (Path path : (List<Path>) list) {
271 + links.addAll(path.links());
272 + }
273 + } else if (!list.isEmpty() && list.iterator().next() instanceof Link) {
274 + links.addAll((List<Link>) list);
275 + }
276 +
277 + //List of devices for new path computed
278 + DeviceId source = null;
279 + DeviceId destination = null;
280 + List<DeviceId> devList = new LinkedList<>();
281 +
282 + for (Link l : links) {
283 + if (!devList.contains(l.src().deviceId())) {
284 + devList.add(l.src().deviceId());
285 + }
286 + if (!devList.contains(l.dst().deviceId())) {
287 + devList.add(l.dst().deviceId());
288 + }
289 + }
290 +
291 + return devList;
292 + }
293 +
294 + //To dectect loops in the path i.e if the partial paths has intersection node avoid it.
295 + private boolean pathValidation(List<Path> partialPath, Path path) {
296 +
297 + //List of devices in new path computed
298 + List<DeviceId> newPartialPathDevList;
299 + newPartialPathDevList = createListOfDeviceIds(path.links());
300 +
301 + //List of devices in partial computed path
302 + List<DeviceId> partialComputedPathDevList;
303 + partialComputedPathDevList = createListOfDeviceIds(partialPath);
304 +
305 + for (DeviceId deviceId : newPartialPathDevList) {
306 + for (DeviceId devId : partialComputedPathDevList) {
307 + if (!newPartialPathDevList.get(0).equals(deviceId) &&
308 + !partialComputedPathDevList.get(partialComputedPathDevList.size() - 1).equals(devId)
309 + && deviceId.equals(devId)) {
310 + return false;
311 + }
312 + }
313 + }
314 +
315 + return true;
316 + }
317 +
318 + //Returns final computed explicit path (list of partial computed paths).
319 + private List<Path> computeExplicitPath(List<ExplicitPathInfo> explicitPathInfo, DeviceId src, DeviceId dst,
320 + List<Constraint> constraints) {
321 + List<Path> finalComputedPath = new LinkedList<>();
322 + for (ExplicitPathInfo info : explicitPathInfo) {
323 + /*
324 + * If explicit path object is LOOSE,
325 + * 1) If specified as DeviceId (node) :
326 + * If it is source , compute from source to destination (partial computation not required),
327 + * otherwise compute from specified source to specified device
328 + * 2) If specified as Link :
329 + * Compute partial path from source to link's source , if path exists compute from link's source to dst
330 + */
331 + if (info.type().equals(ExplicitPathInfo.Type.LOOSE)) {
332 + if (info.value() instanceof DeviceId) {
333 + // If deviceId is source no need to compute
334 + if (!(info.value()).equals(src)) {
335 + finalComputedPath = computePartialPath(finalComputedPath, src, (DeviceId) info.value(),
336 + constraints);
337 + }
338 +
339 + } else if (info.value() instanceof Link) {
340 + if ((((Link) info.value()).src().deviceId().equals(src))
341 + || (!finalComputedPath.isEmpty()
342 + && finalComputedPath.get(finalComputedPath.size() - 1).dst().equals(
343 + ((Link) info.value()).src().deviceId()))) {
344 +
345 + finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).dst()
346 + .deviceId(), constraints);
347 + } else {
348 +
349 + finalComputedPath = computePartialPath(finalComputedPath, src, ((Link) info.value()).src()
350 + .deviceId(), constraints) != null ? computePartialPath(finalComputedPath, src,
351 + ((Link) info.value()).dst().deviceId(), constraints) : null;
352 + }
353 + }
354 + /*
355 + * If explicit path object is STRICT,
356 + * 1) If specified as DeviceId (node) :
357 + * Check whether partial computed path has reachable to strict specified node or
358 + * strict node is the source, if no set path as null else do nothing
359 + * 2) If specified as Link :
360 + * Check whether partial computed path has reachable to strict link's src, if yes compute
361 + * path from strict link's src to link's dst (to include specified link)
362 + */
363 + } else if (info.type().equals(ExplicitPathInfo.Type.STRICT)) {
364 + if (info.value() instanceof DeviceId) {
365 + if (!(!finalComputedPath.isEmpty() && finalComputedPath.get(finalComputedPath.size() - 1).dst()
366 + .deviceId().equals(info.value()))
367 + && !info.value().equals(src)) {
368 + finalComputedPath = null;
369 + }
370 +
371 + } else if (info.value() instanceof Link) {
372 +
373 + finalComputedPath = ((Link) info.value()).src().deviceId().equals(src)
374 + || !finalComputedPath.isEmpty()
375 + && finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId()
376 + .equals(((Link) info.value()).src().deviceId()) ? computePartialPath(
377 + finalComputedPath, src, ((Link) info.value()).dst().deviceId(), constraints) : null;
378 +
379 + }
380 + }
381 + if (finalComputedPath == null) {
382 + return null;
383 + }
384 + }
385 + // Destination is not reached in Partial computed path then compute till destination
386 + if (finalComputedPath.isEmpty() || !finalComputedPath.isEmpty()
387 + && !finalComputedPath.get(finalComputedPath.size() - 1).dst().deviceId().equals(dst)) {
388 +
389 + finalComputedPath = computePartialPath(finalComputedPath, src, dst, constraints);
390 + if (finalComputedPath == null) {
391 + return null;
392 + }
393 + }
394 +
395 + return finalComputedPath;
396 + }
397 +
234 @Override 398 @Override
235 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, 399 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
236 LspType lspType) { 400 LspType lspType) {
401 + return setupPath(src, dst, tunnelName, constraints, lspType, null);
402 + }
403 +
404 + //[TODO:] handle requests in queue
405 + @Override
406 + public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
407 + LspType lspType, List<ExplicitPathInfo> explicitPathInfo) {
237 checkNotNull(src); 408 checkNotNull(src);
238 checkNotNull(dst); 409 checkNotNull(dst);
239 checkNotNull(tunnelName); 410 checkNotNull(tunnelName);
...@@ -245,7 +416,7 @@ public class PceManager implements PceService { ...@@ -245,7 +416,7 @@ public class PceManager implements PceService {
245 416
246 if (srcDevice == null || dstDevice == null) { 417 if (srcDevice == null || dstDevice == null) {
247 // Device is not known. 418 // Device is not known.
248 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 419 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
249 return false; 420 return false;
250 } 421 }
251 422
...@@ -255,7 +426,7 @@ public class PceManager implements PceService { ...@@ -255,7 +426,7 @@ public class PceManager implements PceService {
255 426
256 if (srcLsrId == null || dstLsrId == null) { 427 if (srcLsrId == null || dstLsrId == null) {
257 // LSR id is not known. 428 // LSR id is not known.
258 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 429 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
259 return false; 430 return false;
260 } 431 }
261 432
...@@ -263,7 +434,7 @@ public class PceManager implements PceService { ...@@ -263,7 +434,7 @@ public class PceManager implements PceService {
263 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class); 434 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(srcLsrId), DeviceCapability.class);
264 if (cfg == null) { 435 if (cfg == null) {
265 log.debug("No session to ingress."); 436 log.debug("No session to ingress.");
266 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 437 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
267 return false; 438 return false;
268 } 439 }
269 440
...@@ -299,12 +470,30 @@ public class PceManager implements PceService { ...@@ -299,12 +470,30 @@ public class PceManager implements PceService {
299 constraints = new LinkedList<>(); 470 constraints = new LinkedList<>();
300 constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name()))); 471 constraints.add(CapabilityConstraint.of(CapabilityType.valueOf(lspType.name())));
301 } 472 }
473 + Set<Path> computedPathSet = Sets.newLinkedHashSet();
474 +
475 + if (explicitPathInfo != null && !explicitPathInfo.isEmpty()) {
476 + List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo, src, dst, constraints);
477 + if (finalComputedPath == null) {
478 + return false;
479 + }
302 480
303 - Set<Path> computedPathSet = computePath(src, dst, constraints); 481 + pceStore.tunnelNameExplicitPathInfoMap(tunnelName, explicitPathInfo);
482 + List<Link> links = new LinkedList<>();
483 + double totalCost = 0;
484 + // Add all partial computed paths
485 + for (Path path : finalComputedPath) {
486 + links.addAll(path.links());
487 + totalCost = totalCost + path.cost();
488 + }
489 + computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(), links, totalCost));
490 + } else {
491 + computedPathSet = computePath(src, dst, constraints);
492 + }
304 493
305 // NO-PATH 494 // NO-PATH
306 if (computedPathSet.isEmpty()) { 495 if (computedPathSet.isEmpty()) {
307 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 496 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
308 return false; 497 return false;
309 } 498 }
310 499
...@@ -339,14 +528,15 @@ public class PceManager implements PceService { ...@@ -339,14 +528,15 @@ public class PceManager implements PceService {
339 if (bwConstraintValue != 0) { 528 if (bwConstraintValue != 0) {
340 consumerId = reserveBandwidth(computedPath, bwConstraintValue, null); 529 consumerId = reserveBandwidth(computedPath, bwConstraintValue, null);
341 if (consumerId == null) { 530 if (consumerId == null) {
342 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 531 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints,
532 + lspType, explicitPathInfo));
343 return false; 533 return false;
344 } 534 }
345 } 535 }
346 536
347 TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath); 537 TunnelId tunnelId = tunnelService.setupTunnel(appId, src, tunnel, computedPath);
348 if (tunnelId == null) { 538 if (tunnelId == null) {
349 - pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType)); 539 + pceStore.addFailedPathInfo(new PcePathInfo(src, dst, tunnelName, constraints, lspType, explicitPathInfo));
350 if (consumerId != null) { 540 if (consumerId != null) {
351 resourceService.release(consumerId); 541 resourceService.release(consumerId);
352 } 542 }
...@@ -363,7 +553,7 @@ public class PceManager implements PceService { ...@@ -363,7 +553,7 @@ public class PceManager implements PceService {
363 @Override 553 @Override
364 public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) { 554 public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
365 checkNotNull(tunnelId); 555 checkNotNull(tunnelId);
366 - Set<Path> computedPathSet = null; 556 + Set<Path> computedPathSet = Sets.newLinkedHashSet();
367 Tunnel tunnel = tunnelService.queryTunnel(tunnelId); 557 Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
368 558
369 if (tunnel == null) { 559 if (tunnel == null) {
...@@ -441,8 +631,30 @@ public class PceManager implements PceService { ...@@ -441,8 +631,30 @@ public class PceManager implements PceService {
441 constraints.add(costConstraint); 631 constraints.add(costConstraint);
442 } 632 }
443 633
444 - computedPathSet = computePath(links.get(0).src().deviceId(), links.get(links.size() - 1).dst().deviceId(), 634 + List<ExplicitPathInfo> explicitPathInfo = pceStore
445 - constraints); 635 + .getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value());
636 + if (explicitPathInfo != null) {
637 + List<Path> finalComputedPath = computeExplicitPath(explicitPathInfo,
638 + tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
639 + constraints);
640 +
641 + if (finalComputedPath == null) {
642 + return false;
643 + }
644 +
645 + List<Link> totalLinks = new LinkedList<>();
646 + double totalCost = 0;
647 + //Add all partial computed paths
648 + for (Path path : finalComputedPath) {
649 + totalLinks.addAll(path.links());
650 + totalCost = totalCost + path.cost();
651 + }
652 + computedPathSet.add(new DefaultPath(finalComputedPath.iterator().next().providerId(),
653 + totalLinks, totalCost));
654 + } else {
655 + computedPathSet = computePath(tunnel.path().src().deviceId(), tunnel.path().dst().deviceId(),
656 + constraints);
657 + }
446 658
447 // NO-PATH 659 // NO-PATH
448 if (computedPathSet.isEmpty()) { 660 if (computedPathSet.isEmpty()) {
...@@ -636,7 +848,8 @@ public class PceManager implements PceService { ...@@ -636,7 +848,8 @@ public class PceManager implements PceService {
636 // then PCInitiate (Remove) 848 // then PCInitiate (Remove)
637 pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel 849 pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
638 .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList, 850 .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
639 - LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)))); 851 + LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)),
852 + pceStore.getTunnelNameExplicitPathInfoMap(tunnel.tunnelName().value())));
640 //Release that tunnel calling PCInitiate 853 //Release that tunnel calling PCInitiate
641 releasePath(tunnel.tunnelId()); 854 releasePath(tunnel.tunnelId());
642 } 855 }
...@@ -832,7 +1045,9 @@ public class PceManager implements PceService { ...@@ -832,7 +1045,9 @@ public class PceManager implements PceService {
832 List<Link> links = tunnel.path().links(); 1045 List<Link> links = tunnel.path().links();
833 pceStore.addFailedPathInfo(new PcePathInfo(links.get(0).src().deviceId(), 1046 pceStore.addFailedPathInfo(new PcePathInfo(links.get(0).src().deviceId(),
834 links.get(links.size() - 1).dst().deviceId(), 1047 links.get(links.size() - 1).dst().deviceId(),
835 - tunnel.tunnelName().value(), constraints, lspType)); 1048 + tunnel.tunnelName().value(), constraints, lspType,
1049 + pceStore.getTunnelNameExplicitPathInfoMap(tunnel
1050 + .tunnelName().value())));
836 } 1051 }
837 1052
838 break; 1053 break;
...@@ -861,6 +1076,11 @@ public class PceManager implements PceService { ...@@ -861,6 +1076,11 @@ public class PceManager implements PceService {
861 } 1076 }
862 } 1077 }
863 1078
1079 + @Override
1080 + public List<ExplicitPathInfo> explicitPathInfoList(String tunnelName) {
1081 + return pceStore.getTunnelNameExplicitPathInfoMap(tunnelName);
1082 + }
1083 +
864 //Computes path from tunnel store and also path failed to setup. 1084 //Computes path from tunnel store and also path failed to setup.
865 private void callForOptimization() { 1085 private void callForOptimization() {
866 //Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)] 1086 //Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]
...@@ -880,7 +1100,7 @@ public class PceManager implements PceService { ...@@ -880,7 +1100,7 @@ public class PceManager implements PceService {
880 */ 1100 */
881 if (mastershipService.isLocalMaster(failedPathInfo.src())) { 1101 if (mastershipService.isLocalMaster(failedPathInfo.src())) {
882 if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(), 1102 if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(),
883 - failedPathInfo.constraints(), failedPathInfo.lspType())) { 1103 + failedPathInfo.constraints(), failedPathInfo.lspType(), failedPathInfo.explicitPathInfo())) {
884 // If computation is success remove that path 1104 // If computation is success remove that path
885 pceStore.removeFailedPathInfo(failedPathInfo); 1105 pceStore.removeFailedPathInfo(failedPathInfo);
886 return true; 1106 return true;
......
...@@ -19,7 +19,8 @@ package org.onosproject.pce.pceservice; ...@@ -19,7 +19,8 @@ package org.onosproject.pce.pceservice;
19 import org.onosproject.incubator.net.tunnel.Tunnel; 19 import org.onosproject.incubator.net.tunnel.Tunnel;
20 import org.onosproject.incubator.net.tunnel.TunnelId; 20 import org.onosproject.incubator.net.tunnel.TunnelId;
21 import org.onosproject.net.intent.Constraint; 21 import org.onosproject.net.intent.Constraint;
22 -import org.onosproject.pce.pceservice.DefaultPcePath.Builder; 22 +
23 +import java.util.Collection;
23 24
24 /** 25 /**
25 * Abstraction of an entity which provides functionalities of pce path. 26 * Abstraction of an entity which provides functionalities of pce path.
...@@ -97,6 +98,13 @@ public interface PcePath { ...@@ -97,6 +98,13 @@ public interface PcePath {
97 Constraint bandwidthConstraint(); 98 Constraint bandwidthConstraint();
98 99
99 /** 100 /**
101 + * Returns the list of explicit path objects.
102 + *
103 + * @return list of explicit path objects
104 + */
105 + Collection<ExplicitPathInfo> explicitPathInfo();
106 +
107 + /**
100 * Copies only non-null or non-zero member variables. 108 * Copies only non-null or non-zero member variables.
101 * 109 *
102 * @param id path-id 110 * @param id path-id
...@@ -174,6 +182,14 @@ public interface PcePath { ...@@ -174,6 +182,14 @@ public interface PcePath {
174 Builder of(Tunnel tunnel); 182 Builder of(Tunnel tunnel);
175 183
176 /** 184 /**
185 + * Returns the builder object of ExplicitPathInfo.
186 + *
187 + * @param explicitPathInfo list of explicit path obj
188 + * @return builder object of ExplicitPathInfo
189 + */
190 + Builder explicitPathInfo(Collection<ExplicitPathInfo> explicitPathInfo);
191 +
192 + /**
177 * Builds object of pce path. 193 * Builds object of pce path.
178 * 194 *
179 * @return object of pce path. 195 * @return object of pce path.
......
...@@ -19,6 +19,7 @@ import java.util.List; ...@@ -19,6 +19,7 @@ import java.util.List;
19 19
20 import org.onosproject.net.DeviceId; 20 import org.onosproject.net.DeviceId;
21 import org.onosproject.net.intent.Constraint; 21 import org.onosproject.net.intent.Constraint;
22 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
22 import org.onosproject.pce.pceservice.LspType; 23 import org.onosproject.pce.pceservice.LspType;
23 import org.onosproject.incubator.net.tunnel.Tunnel; 24 import org.onosproject.incubator.net.tunnel.Tunnel;
24 import org.onosproject.incubator.net.tunnel.TunnelId; 25 import org.onosproject.incubator.net.tunnel.TunnelId;
...@@ -42,6 +43,20 @@ public interface PceService { ...@@ -42,6 +43,20 @@ public interface PceService {
42 boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType); 43 boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType);
43 44
44 /** 45 /**
46 + * Creates new path based on constraints and LSP type.
47 + *
48 + * @param src source device
49 + * @param dst destination device
50 + * @param tunnelName name of the tunnel
51 + * @param constraints list of constraints to be applied on path
52 + * @param lspType type of path to be setup
53 + * @param explicitPathInfo list of explicit path info
54 + * @return false on failure and true on successful path creation
55 + */
56 + boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints, LspType lspType,
57 + List<ExplicitPathInfo> explicitPathInfo);
58 +
59 + /**
45 * Updates an existing path. 60 * Updates an existing path.
46 * 61 *
47 * @param tunnelId tunnel identifier 62 * @param tunnelId tunnel identifier
...@@ -72,4 +87,12 @@ public interface PceService { ...@@ -72,4 +87,12 @@ public interface PceService {
72 * @return tunnel if path exists, otherwise null 87 * @return tunnel if path exists, otherwise null
73 */ 88 */
74 Tunnel queryPath(TunnelId tunnelId); 89 Tunnel queryPath(TunnelId tunnelId);
90 +
91 + /**
92 + * Returns list of explicit path info.
93 + *
94 + * @param tunnelName tunnel name
95 + * @return list of explicit path info
96 + */
97 + List<ExplicitPathInfo> explicitPathInfoList(String tunnelName);
75 } 98 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
19 19
20 import com.google.common.collect.ImmutableSet; 20 import com.google.common.collect.ImmutableSet;
21 21
22 +import java.util.List;
22 import java.util.Map; 23 import java.util.Map;
23 import java.util.stream.Collectors; 24 import java.util.stream.Collectors;
24 25
...@@ -33,6 +34,7 @@ import org.onlab.util.KryoNamespace; ...@@ -33,6 +34,7 @@ import org.onlab.util.KryoNamespace;
33 import org.onosproject.incubator.net.tunnel.TunnelId; 34 import org.onosproject.incubator.net.tunnel.TunnelId;
34 import org.onosproject.net.intent.constraint.BandwidthConstraint; 35 import org.onosproject.net.intent.constraint.BandwidthConstraint;
35 import org.onosproject.net.resource.ResourceConsumer; 36 import org.onosproject.net.resource.ResourceConsumer;
37 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
36 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint; 38 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
37 import org.onosproject.pce.pceservice.constraint.CostConstraint; 39 import org.onosproject.pce.pceservice.constraint.CostConstraint;
38 import org.onosproject.pce.pceservice.TunnelConsumerId; 40 import org.onosproject.pce.pceservice.TunnelConsumerId;
...@@ -69,6 +71,9 @@ public class DistributedPceStore implements PceStore { ...@@ -69,6 +71,9 @@ public class DistributedPceStore implements PceStore {
69 // List of Failed path info 71 // List of Failed path info
70 private DistributedSet<PcePathInfo> failedPathSet; 72 private DistributedSet<PcePathInfo> failedPathSet;
71 73
74 + // Maintains tunnel name mapped to explicit path info
75 + private ConsistentMap<String, List<ExplicitPathInfo>> tunnelNameExplicitPathInfoMap;
76 +
72 private static final Serializer SERIALIZER = Serializer 77 private static final Serializer SERIALIZER = Serializer
73 .using(new KryoNamespace.Builder().register(KryoNamespaces.API) 78 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
74 .register(PcePathInfo.class) 79 .register(PcePathInfo.class)
...@@ -99,6 +104,16 @@ public class DistributedPceStore implements PceStore { ...@@ -99,6 +104,16 @@ public class DistributedPceStore implements PceStore {
99 .build() 104 .build()
100 .asDistributedSet(); 105 .asDistributedSet();
101 106
107 + tunnelNameExplicitPathInfoMap = storageService.<String, List<ExplicitPathInfo>>consistentMapBuilder()
108 + .withName("onos-pce-explicitpathinfo")
109 + .withSerializer(Serializer.using(
110 + new KryoNamespace.Builder()
111 + .register(KryoNamespaces.API)
112 + .register(ExplicitPathInfo.class)
113 + .register(ExplicitPathInfo.Type.class)
114 + .build()))
115 + .build();
116 +
102 log.info("Started"); 117 log.info("Started");
103 } 118 }
104 119
...@@ -181,4 +196,18 @@ public class DistributedPceStore implements PceStore { ...@@ -181,4 +196,18 @@ public class DistributedPceStore implements PceStore {
181 } 196 }
182 return true; 197 return true;
183 } 198 }
199 +
200 + @Override
201 + public boolean tunnelNameExplicitPathInfoMap(String tunnelName, List<ExplicitPathInfo> explicitPathInfo) {
202 + checkNotNull(tunnelName);
203 + checkNotNull(explicitPathInfo);
204 + return tunnelNameExplicitPathInfoMap.put(tunnelName, explicitPathInfo) != null ? true : false;
205 + }
206 +
207 + @Override
208 + public List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName) {
209 + checkNotNull(tunnelName);
210 + return tunnelNameExplicitPathInfoMap.get(tunnelName).value();
211 + }
212 +
184 } 213 }
......
...@@ -22,6 +22,7 @@ import java.util.Objects; ...@@ -22,6 +22,7 @@ import java.util.Objects;
22 22
23 import org.onosproject.net.DeviceId; 23 import org.onosproject.net.DeviceId;
24 import org.onosproject.net.intent.Constraint; 24 import org.onosproject.net.intent.Constraint;
25 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
25 import org.onosproject.pce.pceservice.LspType; 26 import org.onosproject.pce.pceservice.LspType;
26 27
27 /** 28 /**
...@@ -40,6 +41,8 @@ public final class PcePathInfo { ...@@ -40,6 +41,8 @@ public final class PcePathInfo {
40 41
41 private LspType lspType; // lsp type 42 private LspType lspType; // lsp type
42 43
44 + private List<ExplicitPathInfo> explicitPathInfo; //Explicit path info to compute explicit path
45 +
43 /** 46 /**
44 * Initialization of member variables. 47 * Initialization of member variables.
45 * 48 *
...@@ -48,17 +51,20 @@ public final class PcePathInfo { ...@@ -48,17 +51,20 @@ public final class PcePathInfo {
48 * @param name tunnel name 51 * @param name tunnel name
49 * @param constraints list of constraints 52 * @param constraints list of constraints
50 * @param lspType lsp type 53 * @param lspType lsp type
54 + * @param explicitPathInfo explicit path info
51 */ 55 */
52 public PcePathInfo(DeviceId src, 56 public PcePathInfo(DeviceId src,
53 DeviceId dst, 57 DeviceId dst,
54 String name, 58 String name,
55 List<Constraint> constraints, 59 List<Constraint> constraints,
56 - LspType lspType) { 60 + LspType lspType,
61 + List<ExplicitPathInfo> explicitPathInfo) {
57 this.src = src; 62 this.src = src;
58 this.dst = dst; 63 this.dst = dst;
59 this.name = name; 64 this.name = name;
60 this.constraints = constraints; 65 this.constraints = constraints;
61 this.lspType = lspType; 66 this.lspType = lspType;
67 + this.explicitPathInfo = explicitPathInfo;
62 } 68 }
63 69
64 /** 70 /**
...@@ -70,6 +76,7 @@ public final class PcePathInfo { ...@@ -70,6 +76,7 @@ public final class PcePathInfo {
70 this.name = null; 76 this.name = null;
71 this.constraints = null; 77 this.constraints = null;
72 this.lspType = null; 78 this.lspType = null;
79 + this.explicitPathInfo = null;
73 } 80 }
74 81
75 /** 82 /**
...@@ -162,9 +169,27 @@ public final class PcePathInfo { ...@@ -162,9 +169,27 @@ public final class PcePathInfo {
162 this.lspType = lspType; 169 this.lspType = lspType;
163 } 170 }
164 171
172 + /**
173 + * Returns list of explicit path info.
174 + *
175 + * @return list of explicit path info
176 + */
177 + public List<ExplicitPathInfo> explicitPathInfo() {
178 + return explicitPathInfo;
179 + }
180 +
181 + /**
182 + * Sets list of explicit path info.
183 + *
184 + * @param explicitPathInfo list of explicit path info
185 + */
186 + public void explicitPathInfo(List<ExplicitPathInfo> explicitPathInfo) {
187 + this.explicitPathInfo = explicitPathInfo;
188 + }
189 +
165 @Override 190 @Override
166 public int hashCode() { 191 public int hashCode() {
167 - return Objects.hash(src, dst, name, constraints, lspType); 192 + return Objects.hash(src, dst, name, constraints, lspType, explicitPathInfo);
168 } 193 }
169 194
170 @Override 195 @Override
...@@ -178,7 +203,8 @@ public final class PcePathInfo { ...@@ -178,7 +203,8 @@ public final class PcePathInfo {
178 Objects.equals(this.dst, other.dst) && 203 Objects.equals(this.dst, other.dst) &&
179 Objects.equals(this.name, other.name) && 204 Objects.equals(this.name, other.name) &&
180 Objects.equals(this.constraints, other.constraints) && 205 Objects.equals(this.constraints, other.constraints) &&
181 - Objects.equals(this.lspType, other.lspType); 206 + Objects.equals(this.lspType, other.lspType) &&
207 + Objects.equals(this.explicitPathInfo, other.explicitPathInfo);
182 } 208 }
183 return false; 209 return false;
184 } 210 }
...@@ -187,11 +213,12 @@ public final class PcePathInfo { ...@@ -187,11 +213,12 @@ public final class PcePathInfo {
187 public String toString() { 213 public String toString() {
188 return MoreObjects.toStringHelper(getClass()) 214 return MoreObjects.toStringHelper(getClass())
189 .omitNullValues() 215 .omitNullValues()
190 - .add("Source", src.toString()) 216 + .add("Source", src)
191 - .add("Destination", dst.toString()) 217 + .add("Destination", dst)
192 - .add("Name", name.toString()) 218 + .add("Name", name)
193 - .add("Constraints", constraints.toString()) 219 + .add("Constraints", constraints)
194 - .add("LspType", lspType.toString()) 220 + .add("explicitPathInfo", explicitPathInfo)
221 + .add("LspType", lspType)
195 .toString(); 222 .toString();
196 } 223 }
197 } 224 }
......
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
15 */ 15 */
16 package org.onosproject.pce.pcestore.api; 16 package org.onosproject.pce.pcestore.api;
17 17
18 +import java.util.List;
19 +
18 import org.onosproject.incubator.net.tunnel.TunnelId; 20 import org.onosproject.incubator.net.tunnel.TunnelId;
19 import org.onosproject.net.resource.ResourceConsumer; 21 import org.onosproject.net.resource.ResourceConsumer;
22 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
20 import org.onosproject.pce.pcestore.PcePathInfo; 23 import org.onosproject.pce.pcestore.PcePathInfo;
21 24
22 import java.util.Map; 25 import java.util.Map;
...@@ -107,4 +110,21 @@ public interface PceStore { ...@@ -107,4 +110,21 @@ public interface PceStore {
107 * @return success or failure 110 * @return success or failure
108 */ 111 */
109 boolean removeFailedPathInfo(PcePathInfo failedPathInfo); 112 boolean removeFailedPathInfo(PcePathInfo failedPathInfo);
113 +
114 + /**
115 + * Adds explicit path info to the map with corresponding tunnel name.
116 + *
117 + * @param tunnelName tunnel name as key
118 + * @param explicitPathInfo list of explicit path objects
119 + * @return whether it is added to map
120 + */
121 + boolean tunnelNameExplicitPathInfoMap(String tunnelName, List<ExplicitPathInfo> explicitPathInfo);
122 +
123 + /**
124 + * Gets explicit path info based on tunnel name.
125 + *
126 + * @param tunnelName tunnel name as key
127 + * @return list of explicit path info
128 + */
129 + List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName);
110 } 130 }
......
...@@ -16,21 +16,47 @@ ...@@ -16,21 +16,47 @@
16 16
17 package org.onosproject.pce.pceservice; 17 package org.onosproject.pce.pceservice;
18 18
19 +import com.google.common.collect.Lists;
20 +
21 +import org.junit.After;
22 +import org.junit.Before;
19 import org.junit.Test; 23 import org.junit.Test;
20 24
21 import static org.hamcrest.MatcherAssert.assertThat; 25 import static org.hamcrest.MatcherAssert.assertThat;
22 import static org.hamcrest.Matchers.is; 26 import static org.hamcrest.Matchers.is;
27 +import static org.onosproject.pce.pceservice.PathComputationTest.D2;
28 +import static org.easymock.EasyMock.createMock;
23 29
24 import com.google.common.testing.EqualsTester; 30 import com.google.common.testing.EqualsTester;
25 31
32 +
33 +import org.onlab.osgi.ServiceDirectory;
34 +import org.onlab.osgi.TestServiceDirectory;
35 +import org.onlab.rest.BaseResource;
26 import org.onosproject.incubator.net.tunnel.TunnelId; 36 import org.onosproject.incubator.net.tunnel.TunnelId;
27 import org.onosproject.pce.pceservice.constraint.CostConstraint; 37 import org.onosproject.pce.pceservice.constraint.CostConstraint;
38 +import org.onosproject.pce.pcestore.api.PceStore;
28 import org.onosproject.net.intent.constraint.BandwidthConstraint; 39 import org.onosproject.net.intent.constraint.BandwidthConstraint;
29 40
41 +import java.util.List;
42 +
30 /** 43 /**
31 * Unit tests for DefaultPcePath class. 44 * Unit tests for DefaultPcePath class.
32 */ 45 */
33 public class DefaultPcePathTest { 46 public class DefaultPcePathTest {
47 + private PceStore pceStore = createMock(PceStore.class);
48 +
49 + @Before
50 + public void setup() {
51 +
52 + ServiceDirectory testDirectory = new TestServiceDirectory()
53 + .add(PceStore.class, pceStore);
54 + BaseResource.setServiceDirectory(testDirectory);
55 + }
56 +
57 + @After
58 + public void tearDownTest() {
59 + }
34 /** 60 /**
35 * Checks the operation of equals() methods. 61 * Checks the operation of equals() methods.
36 */ 62 */
...@@ -43,7 +69,9 @@ public class DefaultPcePathTest { ...@@ -43,7 +69,9 @@ public class DefaultPcePathTest {
43 final String dst1 = "bee"; 69 final String dst1 = "bee";
44 final String type1 = "1"; 70 final String type1 = "1";
45 final String name1 = "pcc"; 71 final String name1 = "pcc";
46 - 72 + final List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
73 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D2.deviceId());
74 + explicitPathInfoList.add(obj);
47 PcePath path1 = DefaultPcePath.builder() 75 PcePath path1 = DefaultPcePath.builder()
48 .source(src1) 76 .source(src1)
49 .destination(dst1) 77 .destination(dst1)
...@@ -51,6 +79,7 @@ public class DefaultPcePathTest { ...@@ -51,6 +79,7 @@ public class DefaultPcePathTest {
51 .name(name1) 79 .name(name1)
52 .costConstraint(cost1) 80 .costConstraint(cost1)
53 .bandwidthConstraint(bandwidth1) 81 .bandwidthConstraint(bandwidth1)
82 + .explicitPathInfo(explicitPathInfoList)
54 .build(); 83 .build();
55 path1.id(TunnelId.valueOf("1")); 84 path1.id(TunnelId.valueOf("1"));
56 85
...@@ -62,6 +91,7 @@ public class DefaultPcePathTest { ...@@ -62,6 +91,7 @@ public class DefaultPcePathTest {
62 .name(name1) 91 .name(name1)
63 .costConstraint(cost1) 92 .costConstraint(cost1)
64 .bandwidthConstraint(bandwidth1) 93 .bandwidthConstraint(bandwidth1)
94 + .explicitPathInfo(explicitPathInfoList)
65 .build(); 95 .build();
66 samePath1.id(TunnelId.valueOf("1")); 96 samePath1.id(TunnelId.valueOf("1"));
67 97
...@@ -80,6 +110,7 @@ public class DefaultPcePathTest { ...@@ -80,6 +110,7 @@ public class DefaultPcePathTest {
80 .name(name2) 110 .name(name2)
81 .costConstraint(cost2) 111 .costConstraint(cost2)
82 .bandwidthConstraint(bandwidth2) 112 .bandwidthConstraint(bandwidth2)
113 + .explicitPathInfo(explicitPathInfoList)
83 .build(); 114 .build();
84 path2.id(TunnelId.valueOf("2")); 115 path2.id(TunnelId.valueOf("2"));
85 116
...@@ -97,7 +128,9 @@ public class DefaultPcePathTest { ...@@ -97,7 +128,9 @@ public class DefaultPcePathTest {
97 final String dst = "deccan"; 128 final String dst = "deccan";
98 final String type = "2"; 129 final String type = "2";
99 final String name = "pcc4"; 130 final String name = "pcc4";
100 - 131 + final List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
132 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D2.deviceId());
133 + explicitPathInfoList.add(obj);
101 PcePath path = DefaultPcePath.builder() 134 PcePath path = DefaultPcePath.builder()
102 .source(src) 135 .source(src)
103 .destination(dst) 136 .destination(dst)
...@@ -105,6 +138,7 @@ public class DefaultPcePathTest { ...@@ -105,6 +138,7 @@ public class DefaultPcePathTest {
105 .name(name) 138 .name(name)
106 .costConstraint(cost) 139 .costConstraint(cost)
107 .bandwidthConstraint(bandwidth) 140 .bandwidthConstraint(bandwidth)
141 + .explicitPathInfo(explicitPathInfoList)
108 .build(); 142 .build();
109 143
110 assertThat(path.source(), is(src)); 144 assertThat(path.source(), is(src));
......
...@@ -14,10 +14,12 @@ import static org.onosproject.pce.pceservice.PathComputationTest.D1; ...@@ -14,10 +14,12 @@ import static org.onosproject.pce.pceservice.PathComputationTest.D1;
14 import static org.onosproject.pce.pceservice.PathComputationTest.D2; 14 import static org.onosproject.pce.pceservice.PathComputationTest.D2;
15 import static org.onosproject.pce.pceservice.PathComputationTest.D3; 15 import static org.onosproject.pce.pceservice.PathComputationTest.D3;
16 import static org.onosproject.pce.pceservice.PathComputationTest.D4; 16 import static org.onosproject.pce.pceservice.PathComputationTest.D4;
17 +import static org.onosproject.pce.pceservice.PathComputationTest.D5;
17 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE1; 18 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE1;
18 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE2; 19 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE2;
19 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE3; 20 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE3;
20 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE4; 21 import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE4;
22 +import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE5;
21 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID; 23 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
22 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID; 24 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
23 import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST; 25 import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
...@@ -32,6 +34,8 @@ import java.util.List; ...@@ -32,6 +34,8 @@ import java.util.List;
32 import java.util.Set; 34 import java.util.Set;
33 import java.util.concurrent.atomic.AtomicLong; 35 import java.util.concurrent.atomic.AtomicLong;
34 36
37 +import com.google.common.collect.Lists;
38 +
35 import org.junit.After; 39 import org.junit.After;
36 import org.junit.Before; 40 import org.junit.Before;
37 import org.junit.Test; 41 import org.junit.Test;
...@@ -120,9 +124,9 @@ public class PceManagerTest { ...@@ -120,9 +124,9 @@ public class PceManagerTest {
120 private static final String LABEL_STACK_CAPABILITY = "labelStackCapability"; 124 private static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
121 125
122 private TopologyGraph graph = null; 126 private TopologyGraph graph = null;
123 - private Device deviceD1, deviceD2, deviceD3, deviceD4; 127 + private Device deviceD1, deviceD2, deviceD3, deviceD4, deviceD5;
124 private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4; 128 private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
125 - private Link link1, link2, link3, link4; 129 + private Link link1, link2, link3, link4, link5, link6;
126 protected static int flowsDownloaded; 130 protected static int flowsDownloaded;
127 private TunnelListener tunnelListener; 131 private TunnelListener tunnelListener;
128 private TopologyListener listener; 132 private TopologyListener listener;
...@@ -164,12 +168,15 @@ public class PceManagerTest { ...@@ -164,12 +168,15 @@ public class PceManagerTest {
164 link2 = PathComputationTest.addLink(DEVICE2, 30, DEVICE4, 40, setCost, 20); 168 link2 = PathComputationTest.addLink(DEVICE2, 30, DEVICE4, 40, setCost, 20);
165 link3 = PathComputationTest.addLink(DEVICE1, 80, DEVICE3, 70, setCost, 100); 169 link3 = PathComputationTest.addLink(DEVICE1, 80, DEVICE3, 70, setCost, 100);
166 link4 = PathComputationTest.addLink(DEVICE3, 60, DEVICE4, 50, setCost, 80); 170 link4 = PathComputationTest.addLink(DEVICE3, 60, DEVICE4, 50, setCost, 80);
171 + link5 = PathComputationTest.addLink(DEVICE2, 60, DEVICE5, 50, setCost, 80);
172 + link6 = PathComputationTest.addLink(DEVICE4, 60, DEVICE5, 50, setCost, 80);
167 173
168 Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>(); 174 Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
169 vertexes.add(D1); 175 vertexes.add(D1);
170 vertexes.add(D2); 176 vertexes.add(D2);
171 vertexes.add(D3); 177 vertexes.add(D3);
172 vertexes.add(D4); 178 vertexes.add(D4);
179 + vertexes.add(D5);
173 180
174 this.vertexes = vertexes; 181 this.vertexes = vertexes;
175 182
...@@ -186,6 +193,12 @@ public class PceManagerTest { ...@@ -186,6 +193,12 @@ public class PceManagerTest {
186 TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4); 193 TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
187 edges.add(edge4); 194 edges.add(edge4);
188 195
196 + TopologyEdge edge5 = new DefaultTopologyEdge(D2, D5, link5);
197 + edges.add(edge5);
198 +
199 + TopologyEdge edge6 = new DefaultTopologyEdge(D4, D5, link6);
200 + edges.add(edge6);
201 +
189 this.edges = edges; 202 this.edges = edges;
190 203
191 graph = new DefaultTopologyGraph(vertexes, edges); 204 graph = new DefaultTopologyGraph(vertexes, edges);
...@@ -194,6 +207,7 @@ public class PceManagerTest { ...@@ -194,6 +207,7 @@ public class PceManagerTest {
194 DefaultAnnotations.Builder builderDev2 = DefaultAnnotations.builder(); 207 DefaultAnnotations.Builder builderDev2 = DefaultAnnotations.builder();
195 DefaultAnnotations.Builder builderDev3 = DefaultAnnotations.builder(); 208 DefaultAnnotations.Builder builderDev3 = DefaultAnnotations.builder();
196 DefaultAnnotations.Builder builderDev4 = DefaultAnnotations.builder(); 209 DefaultAnnotations.Builder builderDev4 = DefaultAnnotations.builder();
210 + DefaultAnnotations.Builder builderDev5 = DefaultAnnotations.builder();
197 211
198 // Making L3 devices 212 // Making L3 devices
199 builderDev1.set(AnnotationKeys.TYPE, L3); 213 builderDev1.set(AnnotationKeys.TYPE, L3);
...@@ -208,15 +222,20 @@ public class PceManagerTest { ...@@ -208,15 +222,20 @@ public class PceManagerTest {
208 builderDev4.set(AnnotationKeys.TYPE, L3); 222 builderDev4.set(AnnotationKeys.TYPE, L3);
209 builderDev4.set(LSRID, "4.4.4.4"); 223 builderDev4.set(LSRID, "4.4.4.4");
210 224
225 + builderDev5.set(AnnotationKeys.TYPE, L3);
226 + builderDev5.set(LSRID, "5.5.5.5");
227 +
211 deviceD1 = new MockDevice(D1.deviceId(), builderDev1.build()); 228 deviceD1 = new MockDevice(D1.deviceId(), builderDev1.build());
212 deviceD2 = new MockDevice(D2.deviceId(), builderDev2.build()); 229 deviceD2 = new MockDevice(D2.deviceId(), builderDev2.build());
213 deviceD3 = new MockDevice(D3.deviceId(), builderDev3.build()); 230 deviceD3 = new MockDevice(D3.deviceId(), builderDev3.build());
214 deviceD4 = new MockDevice(D4.deviceId(), builderDev4.build()); 231 deviceD4 = new MockDevice(D4.deviceId(), builderDev4.build());
232 + deviceD5 = new MockDevice(D5.deviceId(), builderDev5.build());
215 233
216 deviceService.addDevice(deviceD1); 234 deviceService.addDevice(deviceD1);
217 deviceService.addDevice(deviceD2); 235 deviceService.addDevice(deviceD2);
218 deviceService.addDevice(deviceD3); 236 deviceService.addDevice(deviceD3);
219 deviceService.addDevice(deviceD4); 237 deviceService.addDevice(deviceD4);
238 + deviceService.addDevice(deviceD5);
220 239
221 DeviceCapability device1Cap = netConfigRegistry.addConfig(DeviceId.deviceId("1.1.1.1"), DeviceCapability.class); 240 DeviceCapability device1Cap = netConfigRegistry.addConfig(DeviceId.deviceId("1.1.1.1"), DeviceCapability.class);
222 device1Cap.setLabelStackCap(setLabelStackCap) 241 device1Cap.setLabelStackCap(setLabelStackCap)
...@@ -242,17 +261,25 @@ public class PceManagerTest { ...@@ -242,17 +261,25 @@ public class PceManagerTest {
242 .setSrCap(setSrCap) 261 .setSrCap(setSrCap)
243 .apply(); 262 .apply();
244 263
264 + DeviceCapability device5Cap = netConfigRegistry.addConfig(DeviceId.deviceId("5.5.5.5"), DeviceCapability.class);
265 + device4Cap.setLabelStackCap(setLabelStackCap)
266 + .setLocalLabelCap(setPceccCap)
267 + .setSrCap(setSrCap)
268 + .apply();
269 +
245 if (bandwidth != 0) { 270 if (bandwidth != 0) {
246 List<Resource> resources = new LinkedList<>(); 271 List<Resource> resources = new LinkedList<>();
247 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(bandwidth)); 272 resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(bandwidth));
248 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(bandwidth)); 273 resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(bandwidth));
249 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(bandwidth)); 274 resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(bandwidth));
250 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(bandwidth)); 275 resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(bandwidth));
276 + resources.add(continuous(link5.src().deviceId(), link5.src().port(), Bandwidth.class).resource(bandwidth));
251 277
252 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(bandwidth)); 278 resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(bandwidth));
253 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(bandwidth)); 279 resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(bandwidth));
254 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(bandwidth)); 280 resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(bandwidth));
255 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(bandwidth)); 281 resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(bandwidth));
282 + resources.add(continuous(link5.dst().deviceId(), link5.dst().port(), Bandwidth.class).resource(bandwidth));
256 283
257 resourceService.allocate(IntentId.valueOf(bandwidth), resources); 284 resourceService.allocate(IntentId.valueOf(bandwidth), resources);
258 } 285 }
...@@ -268,7 +295,7 @@ public class PceManagerTest { ...@@ -268,7 +295,7 @@ public class PceManagerTest {
268 CostConstraint costConstraint = new CostConstraint(COST); 295 CostConstraint costConstraint = new CostConstraint(COST);
269 constraints.add(costConstraint); 296 constraints.add(costConstraint);
270 297
271 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 298 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
272 assertThat(result, is(true)); 299 assertThat(result, is(true));
273 } 300 }
274 301
...@@ -282,7 +309,7 @@ public class PceManagerTest { ...@@ -282,7 +309,7 @@ public class PceManagerTest {
282 CostConstraint costConstraint = new CostConstraint(COST); 309 CostConstraint costConstraint = new CostConstraint(COST);
283 constraints.add(costConstraint); 310 constraints.add(costConstraint);
284 311
285 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 312 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
286 assertThat(result, is(false)); 313 assertThat(result, is(false));
287 } 314 }
288 315
...@@ -297,7 +324,7 @@ public class PceManagerTest { ...@@ -297,7 +324,7 @@ public class PceManagerTest {
297 CostConstraint costConstraint = new CostConstraint(TE_COST); 324 CostConstraint costConstraint = new CostConstraint(TE_COST);
298 constraints.add(costConstraint); 325 constraints.add(costConstraint);
299 326
300 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 327 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
301 assertThat(result, is(true)); 328 assertThat(result, is(true));
302 } 329 }
303 330
...@@ -312,7 +339,7 @@ public class PceManagerTest { ...@@ -312,7 +339,7 @@ public class PceManagerTest {
312 CostConstraint costConstraint = new CostConstraint(TE_COST); 339 CostConstraint costConstraint = new CostConstraint(TE_COST);
313 constraints.add(costConstraint); 340 constraints.add(costConstraint);
314 341
315 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 342 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
316 assertThat(result, is(false)); 343 assertThat(result, is(false));
317 } 344 }
318 345
...@@ -328,7 +355,7 @@ public class PceManagerTest { ...@@ -328,7 +355,7 @@ public class PceManagerTest {
328 constraints.add(costConstraint); 355 constraints.add(costConstraint);
329 356
330 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, 357 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
331 - WITHOUT_SIGNALLING_AND_WITHOUT_SR); 358 + WITHOUT_SIGNALLING_AND_WITHOUT_SR, null);
332 assertThat(result, is(true)); 359 assertThat(result, is(true));
333 } 360 }
334 361
...@@ -344,7 +371,7 @@ public class PceManagerTest { ...@@ -344,7 +371,7 @@ public class PceManagerTest {
344 constraints.add(costConstraint); 371 constraints.add(costConstraint);
345 372
346 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, 373 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
347 - WITHOUT_SIGNALLING_AND_WITHOUT_SR); 374 + WITHOUT_SIGNALLING_AND_WITHOUT_SR, null);
348 assertThat(result, is(true)); 375 assertThat(result, is(true));
349 } 376 }
350 377
...@@ -360,7 +387,7 @@ public class PceManagerTest { ...@@ -360,7 +387,7 @@ public class PceManagerTest {
360 constraints.add(costConstraint); 387 constraints.add(costConstraint);
361 388
362 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, 389 boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
363 - WITHOUT_SIGNALLING_AND_WITHOUT_SR); 390 + WITHOUT_SIGNALLING_AND_WITHOUT_SR, null);
364 assertThat(result, is(false)); 391 assertThat(result, is(false));
365 } 392 }
366 393
...@@ -377,7 +404,8 @@ public class PceManagerTest { ...@@ -377,7 +404,8 @@ public class PceManagerTest {
377 constraints.add(costConstraint); 404 constraints.add(costConstraint);
378 constraints.add(bwConstraint); 405 constraints.add(bwConstraint);
379 406
380 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 407 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
408 + WITH_SIGNALLING, null);
381 assertThat(result, is(false)); 409 assertThat(result, is(false));
382 } 410 }
383 411
...@@ -394,7 +422,8 @@ public class PceManagerTest { ...@@ -394,7 +422,8 @@ public class PceManagerTest {
394 constraints.add(costConstraint); 422 constraints.add(costConstraint);
395 constraints.add(bwConstraint); 423 constraints.add(bwConstraint);
396 424
397 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 425 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123",
426 + constraints, WITH_SIGNALLING, null);
398 assertThat(result, is(false)); 427 assertThat(result, is(false));
399 } 428 }
400 429
...@@ -408,7 +437,8 @@ public class PceManagerTest { ...@@ -408,7 +437,8 @@ public class PceManagerTest {
408 CostConstraint costConstraint = new CostConstraint(TE_COST); 437 CostConstraint costConstraint = new CostConstraint(TE_COST);
409 constraints.add(costConstraint); 438 constraints.add(costConstraint);
410 439
411 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING); 440 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints,
441 + SR_WITHOUT_SIGNALLING, null);
412 assertThat(result, is(false)); 442 assertThat(result, is(false));
413 } 443 }
414 444
...@@ -425,7 +455,8 @@ public class PceManagerTest { ...@@ -425,7 +455,8 @@ public class PceManagerTest {
425 constraints.add(costConstraint); 455 constraints.add(costConstraint);
426 constraints.add(bwConstraint); 456 constraints.add(bwConstraint);
427 457
428 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING); 458 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123",
459 + constraints, SR_WITHOUT_SIGNALLING, null);
429 assertThat(result, is(true)); 460 assertThat(result, is(true));
430 } 461 }
431 462
...@@ -436,11 +467,144 @@ public class PceManagerTest { ...@@ -436,11 +467,144 @@ public class PceManagerTest {
436 public void setupPathTest13() { 467 public void setupPathTest13() {
437 build4RouterTopo(false, false, false, false, 0); 468 build4RouterTopo(false, false, false, false, 0);
438 469
439 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING); 470 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", null, WITH_SIGNALLING, null);
471 + assertThat(result, is(true));
472 + }
473 +
474 + /**
475 + * Tests path setup with explicit path with loose node D2.
476 + */
477 + @Test
478 + public void setupPathTest14() {
479 + build4RouterTopo(false, false, false, false, 0);
480 +
481 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
482 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D2.deviceId());
483 + explicitPathInfoList.add(obj);
484 +
485 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", null, WITH_SIGNALLING,
486 + explicitPathInfoList);
487 +
488 + Tunnel tunnel = pceManager.queryAllPath().iterator().next();
489 + List<Link> links = new LinkedList<>();
490 + links.add(link1);
491 + links.add(link2);
492 +
440 assertThat(result, is(true)); 493 assertThat(result, is(true));
494 + assertThat(tunnel.path().links().equals(links), is(true));
441 } 495 }
442 496
443 /** 497 /**
498 + * Tests path setup with explicit path with loose node D3.
499 + */
500 + @Test
501 + public void setupPathTest15() {
502 + build4RouterTopo(false, false, false, false, 0);
503 +
504 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
505 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D3.deviceId());
506 + explicitPathInfoList.add(obj);
507 +
508 + boolean result = pceManager.setupPath(D1.deviceId(), D5.deviceId(), "T123", null, WITH_SIGNALLING,
509 + explicitPathInfoList);
510 +
511 + Tunnel tunnel = pceManager.queryAllPath().iterator().next();
512 + List<Link> links = new LinkedList<>();
513 + links.add(link3);
514 + links.add(link4);
515 + links.add(link6);
516 +
517 + assertThat(result, is(true));
518 + assertThat(tunnel.path().links().equals(links), is(true));
519 + }
520 +
521 + /**
522 + * Tests path setup with explicit path with loose node D4 , D3 - path fails.
523 + */
524 + @Test
525 + public void setupPathTest16() {
526 + build4RouterTopo(false, false, false, false, 0);
527 +
528 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
529 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D4.deviceId());
530 + explicitPathInfoList.add(obj);
531 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D3.deviceId());
532 + explicitPathInfoList.add(obj);
533 +
534 + boolean result = pceManager.setupPath(D1.deviceId(), D5.deviceId(), "T123", null, WITH_SIGNALLING,
535 + explicitPathInfoList);
536 +
537 + assertThat(result, is(false));
538 + }
539 +
540 + /**
541 + * Tests path setup with explicit path with strict node D2 - without reacble to src - path fails.
542 + */
543 + @Test
544 + public void setupPathTest17() {
545 + build4RouterTopo(false, false, false, false, 0);
546 +
547 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
548 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
549 + explicitPathInfoList.add(obj);
550 +
551 + boolean result = pceManager.setupPath(D1.deviceId(), D5.deviceId(), "T123", null, WITH_SIGNALLING,
552 + explicitPathInfoList);
553 +
554 + assertThat(result, is(false));
555 + }
556 +
557 + /**
558 + * Tests path setup with explicit path with loose node D2, strict D2.
559 + */
560 + @Test
561 + public void setupPathTest18() {
562 + build4RouterTopo(false, false, false, false, 0);
563 +
564 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
565 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, D2.deviceId());
566 + explicitPathInfoList.add(obj);
567 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
568 + explicitPathInfoList.add(obj);
569 +
570 + boolean result = pceManager.setupPath(D1.deviceId(), D5.deviceId(), "T123", null, WITH_SIGNALLING,
571 + explicitPathInfoList);
572 +
573 + Tunnel tunnel = pceManager.queryAllPath().iterator().next();
574 + List<Link> links = new LinkedList<>();
575 + links.add(link1);
576 + links.add(link5);
577 +
578 + assertThat(result, is(true));
579 + assertThat(tunnel.path().links().equals(links), is(true));
580 + }
581 +
582 + /**
583 + * Tests path setup with explicit path with loose D1-D2, strict D2.
584 + */
585 + @Test
586 + public void setupPathTest19() {
587 + build4RouterTopo(false, false, false, false, 0);
588 +
589 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
590 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, link1);
591 + explicitPathInfoList.add(obj);
592 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
593 + explicitPathInfoList.add(obj);
594 +
595 + boolean result = pceManager.setupPath(D1.deviceId(), D5.deviceId(), "T123", null, WITH_SIGNALLING,
596 + explicitPathInfoList);
597 +
598 + Tunnel tunnel = pceManager.queryAllPath().iterator().next();
599 + List<Link> links = new LinkedList<>();
600 + links.add(link1);
601 + links.add(link5);
602 +
603 + assertThat(result, is(true));
604 + assertThat(tunnel.path().links().equals(links), is(true));
605 + }
606 +
607 + /**
444 * Tests path update with increase in bandwidth. 608 * Tests path update with increase in bandwidth.
445 */ 609 */
446 @Test 610 @Test
...@@ -454,7 +618,8 @@ public class PceManagerTest { ...@@ -454,7 +618,8 @@ public class PceManagerTest {
454 CostConstraint costConstraint = new CostConstraint(TE_COST); 618 CostConstraint costConstraint = new CostConstraint(TE_COST);
455 constraints.add(costConstraint); 619 constraints.add(costConstraint);
456 620
457 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 621 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
622 + constraints, WITH_SIGNALLING, null);
458 assertThat(result, is(true)); 623 assertThat(result, is(true));
459 624
460 // Change constraint and update it. 625 // Change constraint and update it.
...@@ -492,7 +657,8 @@ public class PceManagerTest { ...@@ -492,7 +657,8 @@ public class PceManagerTest {
492 CostConstraint costConstraint = new CostConstraint(TE_COST); 657 CostConstraint costConstraint = new CostConstraint(TE_COST);
493 constraints.add(costConstraint); 658 constraints.add(costConstraint);
494 659
495 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, SR_WITHOUT_SIGNALLING); 660 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123",
661 + constraints, SR_WITHOUT_SIGNALLING, null);
496 assertThat(result, is(true)); 662 assertThat(result, is(true));
497 663
498 // Change constraint and update it. 664 // Change constraint and update it.
...@@ -523,7 +689,8 @@ public class PceManagerTest { ...@@ -523,7 +689,8 @@ public class PceManagerTest {
523 List<Constraint> constraints = new LinkedList<Constraint>(); 689 List<Constraint> constraints = new LinkedList<Constraint>();
524 CostConstraint costConstraint = new CostConstraint(TE_COST); 690 CostConstraint costConstraint = new CostConstraint(TE_COST);
525 constraints.add(costConstraint); 691 constraints.add(costConstraint);
526 - boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 692 + boolean result = pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123",
693 + constraints, WITH_SIGNALLING, null);
527 assertThat(result, is(true)); 694 assertThat(result, is(true));
528 695
529 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath(); 696 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
...@@ -539,6 +706,51 @@ public class PceManagerTest { ...@@ -539,6 +706,51 @@ public class PceManagerTest {
539 } 706 }
540 707
541 /** 708 /**
709 + * Tests path update without cost/bandwidth constraints and with explicit path object.
710 + */
711 + @Test
712 + public void updatePathTest4() {
713 + build4RouterTopo(false, true, true, true, 100);
714 +
715 + // Setup tunnel.
716 + List<Constraint> constraints = new LinkedList<>();
717 + BandwidthConstraint bwConstraint = new BandwidthConstraint(Bandwidth.bps(60.0));
718 + constraints.add(bwConstraint);
719 + CostConstraint costConstraint = new CostConstraint(TE_COST);
720 + constraints.add(costConstraint);
721 +
722 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
723 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, link1);
724 + explicitPathInfoList.add(obj);
725 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
726 + explicitPathInfoList.add(obj);
727 +
728 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
729 + constraints, WITH_SIGNALLING, explicitPathInfoList);
730 + assertThat(result, is(true));
731 +
732 + // Change constraint and update it.
733 + constraints = new LinkedList<>();
734 + bwConstraint = new BandwidthConstraint(Bandwidth.bps(50.0));
735 + constraints.add(bwConstraint);
736 + constraints.add(costConstraint);
737 +
738 + Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
739 + assertThat(tunnels.size(), is(1));
740 +
741 + Tunnel tunnel = tunnels.iterator().next();
742 +
743 + // Stimulate the effect of LSP ids from protocol msg.
744 + tunnelService.updateTunnelWithLspIds(tunnel, "123", "1", State.ACTIVE);
745 +
746 + result = pceManager.updatePath(tunnel.tunnelId(), constraints);
747 + assertThat(result, is(true));
748 +
749 + tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
750 + assertThat(tunnels.size(), is(2));
751 + }
752 +
753 + /**
542 * Tests path release. 754 * Tests path release.
543 */ 755 */
544 @Test 756 @Test
...@@ -550,7 +762,13 @@ public class PceManagerTest { ...@@ -550,7 +762,13 @@ public class PceManagerTest {
550 constraints.add(bwConst); 762 constraints.add(bwConst);
551 constraints.add(costConstraint); 763 constraints.add(costConstraint);
552 764
553 - pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 765 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
766 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, link1);
767 + explicitPathInfoList.add(obj);
768 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
769 + explicitPathInfoList.add(obj);
770 +
771 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, explicitPathInfoList);
554 772
555 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath(); 773 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
556 assertThat(tunnels.size(), is(1)); 774 assertThat(tunnels.size(), is(1));
...@@ -573,7 +791,7 @@ public class PceManagerTest { ...@@ -573,7 +791,7 @@ public class PceManagerTest {
573 CostConstraint costConstraint = new CostConstraint(TE_COST); 791 CostConstraint costConstraint = new CostConstraint(TE_COST);
574 constraints.add(costConstraint); 792 constraints.add(costConstraint);
575 793
576 - pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING); 794 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
577 795
578 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath(); 796 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
579 assertThat(tunnels.size(), is(1)); 797 assertThat(tunnels.size(), is(1));
...@@ -587,6 +805,31 @@ public class PceManagerTest { ...@@ -587,6 +805,31 @@ public class PceManagerTest {
587 } 805 }
588 806
589 /** 807 /**
808 + * Tests path release failure.
809 + */
810 + @Test
811 + public void releasePathTest3() {
812 + build4RouterTopo(false, false, false, false, 5);
813 + List<Constraint> constraints = new LinkedList<Constraint>();
814 + CostConstraint costConstraint = new CostConstraint(TE_COST);
815 + BandwidthConstraint bwConst = new BandwidthConstraint(Bandwidth.bps(3));
816 + constraints.add(bwConst);
817 + constraints.add(costConstraint);
818 +
819 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T123", constraints, WITH_SIGNALLING, null);
820 +
821 + Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
822 + assertThat(tunnels.size(), is(1));
823 + boolean result;
824 + for (Tunnel tunnel : tunnels) {
825 + result = pceManager.releasePath(tunnel.tunnelId());
826 + assertThat(result, is(true));
827 + }
828 + tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
829 + assertThat(tunnels.size(), is(0));
830 + }
831 +
832 + /**
590 * Tests tunnel events added and removed. 833 * Tests tunnel events added and removed.
591 */ 834 */
592 @Test 835 @Test
...@@ -599,7 +842,7 @@ public class PceManagerTest { ...@@ -599,7 +842,7 @@ public class PceManagerTest {
599 constraints.add(costConstraint); 842 constraints.add(costConstraint);
600 constraints.add(bwConstraint); 843 constraints.add(bwConstraint);
601 844
602 - pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T1", constraints, SR_WITHOUT_SIGNALLING); 845 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T1", constraints, SR_WITHOUT_SIGNALLING, null);
603 assertThat(pceStore.getTunnelInfoCount(), is(1)); 846 assertThat(pceStore.getTunnelInfoCount(), is(1));
604 847
605 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath(); 848 Collection<Tunnel> tunnels = (Collection<Tunnel>) pceManager.queryAllPath();
...@@ -630,7 +873,8 @@ public class PceManagerTest { ...@@ -630,7 +873,8 @@ public class PceManagerTest {
630 constraints.add(costConstraint); 873 constraints.add(costConstraint);
631 constraints.add(bwConstraint); 874 constraints.add(bwConstraint);
632 875
633 - pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR); 876 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints,
877 + WITHOUT_SIGNALLING_AND_WITHOUT_SR, null);
634 assertThat(pceStore.getTunnelInfoCount(), is(1)); 878 assertThat(pceStore.getTunnelInfoCount(), is(1));
635 879
636 TunnelEvent event; 880 TunnelEvent event;
...@@ -670,7 +914,8 @@ public class PceManagerTest { ...@@ -670,7 +914,8 @@ public class PceManagerTest {
670 constraints.add(costConstraint); 914 constraints.add(costConstraint);
671 constraints.add(bwConstraint); 915 constraints.add(bwConstraint);
672 916
673 - pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints, WITHOUT_SIGNALLING_AND_WITHOUT_SR); 917 + pceManager.setupPath(D1.deviceId(), D2.deviceId(), "T2", constraints,
918 + WITHOUT_SIGNALLING_AND_WITHOUT_SR, null);
674 assertThat(pceStore.getTunnelInfoCount(), is(1)); 919 assertThat(pceStore.getTunnelInfoCount(), is(1));
675 assertThat(pceStore.getFailedPathInfoCount(), is(0)); 920 assertThat(pceStore.getFailedPathInfoCount(), is(0));
676 921
...@@ -708,7 +953,8 @@ public class PceManagerTest { ...@@ -708,7 +953,8 @@ public class PceManagerTest {
708 constraints.add(localBwConst); 953 constraints.add(localBwConst);
709 954
710 //Setup the path , tunnel created 955 //Setup the path , tunnel created
711 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 956 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
957 + constraints, WITH_SIGNALLING, null);
712 assertThat(result, is(true)); 958 assertThat(result, is(true));
713 assertThat(pceStore.getTunnelInfoCount(), is(1)); 959 assertThat(pceStore.getTunnelInfoCount(), is(1));
714 assertThat(pceStore.getFailedPathInfoCount(), is(0)); 960 assertThat(pceStore.getFailedPathInfoCount(), is(0));
...@@ -750,7 +996,8 @@ public class PceManagerTest { ...@@ -750,7 +996,8 @@ public class PceManagerTest {
750 constraints.add(localBwConst); 996 constraints.add(localBwConst);
751 997
752 //Setup the path , tunnel created 998 //Setup the path , tunnel created
753 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 999 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1000 + constraints, WITH_SIGNALLING, null);
754 assertThat(result, is(true)); 1001 assertThat(result, is(true));
755 1002
756 List<Event> reasons = new LinkedList<>(); 1003 List<Event> reasons = new LinkedList<>();
...@@ -788,7 +1035,8 @@ public class PceManagerTest { ...@@ -788,7 +1035,8 @@ public class PceManagerTest {
788 constraints.add(localBwConst); 1035 constraints.add(localBwConst);
789 1036
790 //Setup the path , tunnel created 1037 //Setup the path , tunnel created
791 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1038 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1039 + constraints, WITH_SIGNALLING, null);
792 assertThat(result, is(true)); 1040 assertThat(result, is(true));
793 1041
794 List<Event> reasons = new LinkedList<>(); 1042 List<Event> reasons = new LinkedList<>();
...@@ -831,7 +1079,8 @@ public class PceManagerTest { ...@@ -831,7 +1079,8 @@ public class PceManagerTest {
831 constraints.add(localBwConst); 1079 constraints.add(localBwConst);
832 1080
833 //Setup the path , tunnel created 1081 //Setup the path , tunnel created
834 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1082 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1083 + constraints, WITH_SIGNALLING, null);
835 assertThat(result, is(true)); 1084 assertThat(result, is(true));
836 1085
837 List<Event> reasons = new LinkedList<>(); 1086 List<Event> reasons = new LinkedList<>();
...@@ -869,7 +1118,8 @@ public class PceManagerTest { ...@@ -869,7 +1118,8 @@ public class PceManagerTest {
869 constraints.add(localBwConst); 1118 constraints.add(localBwConst);
870 1119
871 //Setup the path , tunnel created 1120 //Setup the path , tunnel created
872 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1121 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1122 + constraints, WITH_SIGNALLING, null);
873 assertThat(result, is(true)); 1123 assertThat(result, is(true));
874 1124
875 List<Event> reasons = new LinkedList<>(); 1125 List<Event> reasons = new LinkedList<>();
...@@ -917,7 +1167,8 @@ public class PceManagerTest { ...@@ -917,7 +1167,8 @@ public class PceManagerTest {
917 constraints.add(localBwConst); 1167 constraints.add(localBwConst);
918 1168
919 //Setup the path , tunnel created 1169 //Setup the path , tunnel created
920 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1170 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1171 + constraints, WITH_SIGNALLING, null);
921 assertThat(result, is(true)); 1172 assertThat(result, is(true));
922 1173
923 List<Event> reasons = new LinkedList<>(); 1174 List<Event> reasons = new LinkedList<>();
...@@ -958,7 +1209,8 @@ public class PceManagerTest { ...@@ -958,7 +1209,8 @@ public class PceManagerTest {
958 constraints.add(localBwConst); 1209 constraints.add(localBwConst);
959 1210
960 //Setup the path , tunnel created 1211 //Setup the path , tunnel created
961 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1212 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1213 + constraints, WITH_SIGNALLING, null);
962 assertThat(result, is(true)); 1214 assertThat(result, is(true));
963 1215
964 List<Event> reasons = new LinkedList<>(); 1216 List<Event> reasons = new LinkedList<>();
...@@ -999,7 +1251,8 @@ public class PceManagerTest { ...@@ -999,7 +1251,8 @@ public class PceManagerTest {
999 constraints.add(localBwConst); 1251 constraints.add(localBwConst);
1000 1252
1001 //Setup the path , tunnel created 1253 //Setup the path , tunnel created
1002 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1254 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1255 + constraints, WITH_SIGNALLING, null);
1003 assertThat(result, is(true)); 1256 assertThat(result, is(true));
1004 1257
1005 List<Event> reasons = new LinkedList<>(); 1258 List<Event> reasons = new LinkedList<>();
...@@ -1045,7 +1298,8 @@ public class PceManagerTest { ...@@ -1045,7 +1298,8 @@ public class PceManagerTest {
1045 constraints.add(localBwConst); 1298 constraints.add(localBwConst);
1046 1299
1047 //Setup the path , tunnel created 1300 //Setup the path , tunnel created
1048 - boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING); 1301 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1302 + constraints, WITH_SIGNALLING, null);
1049 assertThat(result, is(true)); 1303 assertThat(result, is(true));
1050 1304
1051 List<Event> reasons = new LinkedList<>(); 1305 List<Event> reasons = new LinkedList<>();
...@@ -1077,6 +1331,54 @@ public class PceManagerTest { ...@@ -1077,6 +1331,54 @@ public class PceManagerTest {
1077 assertThat(pathService.paths().iterator().next().cost(), is((double) 180)); 1331 assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
1078 } 1332 }
1079 1333
1334 + /**
1335 + * Tests resilency when link2 availability is changed.
1336 + */
1337 + @Test
1338 + public void resilencyTest12() {
1339 + build4RouterTopo(true, false, false, false, 10);
1340 +
1341 + List<Constraint> constraints = new LinkedList<Constraint>();
1342 + CostConstraint costConstraint = new CostConstraint(COST);
1343 + constraints.add(costConstraint);
1344 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1345 + constraints.add(localBwConst);
1346 +
1347 + List<ExplicitPathInfo> explicitPathInfoList = Lists.newLinkedList();
1348 + ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.LOOSE, link1);
1349 + explicitPathInfoList.add(obj);
1350 + obj = new ExplicitPathInfo(ExplicitPathInfo.Type.STRICT, D2.deviceId());
1351 + explicitPathInfoList.add(obj);
1352 +
1353 + //Setup the path , tunnel created
1354 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123",
1355 + constraints, WITH_SIGNALLING, explicitPathInfoList);
1356 + assertThat(result, is(true));
1357 + assertThat(pceStore.getTunnelInfoCount(), is(1));
1358 + assertThat(pceStore.getFailedPathInfoCount(), is(0));
1359 +
1360 + List<Event> reasons = new LinkedList<>();
1361 + final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1362 + reasons.add(linkEvent);
1363 + final TopologyEvent event = new TopologyEvent(
1364 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1365 + topology,
1366 + reasons);
1367 +
1368 + //Change Topology : remove link2
1369 + Set<TopologyEdge> tempEdges = new HashSet<>();
1370 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1371 + topologyService.changeInTopology(getGraph(null, tempEdges));
1372 + listener.event(event);
1373 +
1374 + List<Link> links = new LinkedList<>();
1375 + links.add(link3);
1376 + links.add(link4);
1377 +
1378 + //Path fails - no alternate path
1379 + assertThat(pathService.paths().iterator().hasNext(), is(false));
1380 + }
1381 +
1080 @After 1382 @After
1081 public void tearDown() { 1383 public void tearDown() {
1082 pceManager.deactivate(); 1384 pceManager.deactivate();
......
...@@ -120,7 +120,7 @@ public class DistributedPceStoreTest { ...@@ -120,7 +120,7 @@ public class DistributedPceStoreTest {
120 Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS); 120 Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS);
121 constraints1.add(bandwidth1); 121 constraints1.add(bandwidth1);
122 122
123 - failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1); 123 + failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null);
124 124
125 // Creates failedPathInfo2 125 // Creates failedPathInfo2
126 DeviceId src2 = DeviceId.deviceId("foo2"); 126 DeviceId src2 = DeviceId.deviceId("foo2");
...@@ -131,7 +131,7 @@ public class DistributedPceStoreTest { ...@@ -131,7 +131,7 @@ public class DistributedPceStoreTest {
131 Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS); 131 Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS);
132 constraints2.add(bandwidth2); 132 constraints2.add(bandwidth2);
133 133
134 - failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2); 134 + failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null);
135 135
136 // Creates failedPathInfo3 136 // Creates failedPathInfo3
137 DeviceId src3 = DeviceId.deviceId("foo3"); 137 DeviceId src3 = DeviceId.deviceId("foo3");
...@@ -142,7 +142,7 @@ public class DistributedPceStoreTest { ...@@ -142,7 +142,7 @@ public class DistributedPceStoreTest {
142 Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS); 142 Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS);
143 constraints3.add(bandwidth3); 143 constraints3.add(bandwidth3);
144 144
145 - failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3); 145 + failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null);
146 146
147 // Creates failedPathInfo4 147 // Creates failedPathInfo4
148 DeviceId src4 = DeviceId.deviceId("foo4"); 148 DeviceId src4 = DeviceId.deviceId("foo4");
...@@ -153,7 +153,7 @@ public class DistributedPceStoreTest { ...@@ -153,7 +153,7 @@ public class DistributedPceStoreTest {
153 Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS); 153 Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS);
154 constraints4.add(bandwidth4); 154 constraints4.add(bandwidth4);
155 155
156 - failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4); 156 + failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null);
157 } 157 }
158 158
159 @After 159 @After
......
...@@ -53,10 +53,10 @@ public class PcePathInfoTest { ...@@ -53,10 +53,10 @@ public class PcePathInfoTest {
53 Constraint bandwidth13 = BandwidthConstraint.of(300, DataRateUnit.BPS); 53 Constraint bandwidth13 = BandwidthConstraint.of(300, DataRateUnit.BPS);
54 constraints1.add(bandwidth13); 54 constraints1.add(bandwidth13);
55 55
56 - PcePathInfo pathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1); 56 + PcePathInfo pathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null);
57 57
58 // create same object as above object 58 // create same object as above object
59 - PcePathInfo samePathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1); 59 + PcePathInfo samePathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null);
60 60
61 // Create different object. 61 // Create different object.
62 DeviceId src2 = DeviceId.deviceId("foo2"); 62 DeviceId src2 = DeviceId.deviceId("foo2");
...@@ -69,7 +69,7 @@ public class PcePathInfoTest { ...@@ -69,7 +69,7 @@ public class PcePathInfoTest {
69 Constraint bandwidth22 = BandwidthConstraint.of(800, DataRateUnit.BPS); 69 Constraint bandwidth22 = BandwidthConstraint.of(800, DataRateUnit.BPS);
70 constraints2.add(bandwidth22); 70 constraints2.add(bandwidth22);
71 71
72 - PcePathInfo pathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2); 72 + PcePathInfo pathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null);
73 73
74 new EqualsTester().addEqualityGroup(pathInfo1, samePathInfo1) 74 new EqualsTester().addEqualityGroup(pathInfo1, samePathInfo1)
75 .addEqualityGroup(pathInfo2) 75 .addEqualityGroup(pathInfo2)
...@@ -93,7 +93,7 @@ public class PcePathInfoTest { ...@@ -93,7 +93,7 @@ public class PcePathInfoTest {
93 Constraint bandwidth3 = BandwidthConstraint.of(300, DataRateUnit.BPS); 93 Constraint bandwidth3 = BandwidthConstraint.of(300, DataRateUnit.BPS);
94 constraints.add(bandwidth3); 94 constraints.add(bandwidth3);
95 95
96 - PcePathInfo pathInfo = new PcePathInfo(src, dst, name, constraints, lspType); 96 + PcePathInfo pathInfo = new PcePathInfo(src, dst, name, constraints, lspType, null);
97 97
98 assertThat(src, is(pathInfo.src())); 98 assertThat(src, is(pathInfo.src()));
99 assertThat(dst, is(pathInfo.dst())); 99 assertThat(dst, is(pathInfo.dst()));
......
...@@ -22,13 +22,14 @@ import java.util.concurrent.ConcurrentMap; ...@@ -22,13 +22,14 @@ import java.util.concurrent.ConcurrentMap;
22 22
23 import java.util.HashMap; 23 import java.util.HashMap;
24 import java.util.HashSet; 24 import java.util.HashSet;
25 +import java.util.List;
25 import java.util.Map; 26 import java.util.Map;
26 import java.util.Set; 27 import java.util.Set;
27 import java.util.stream.Collectors; 28 import java.util.stream.Collectors;
28 29
29 import org.onosproject.incubator.net.tunnel.TunnelId; 30 import org.onosproject.incubator.net.tunnel.TunnelId;
30 -import org.onosproject.net.DeviceId;
31 import org.onosproject.net.resource.ResourceConsumer; 31 import org.onosproject.net.resource.ResourceConsumer;
32 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
32 import org.onosproject.pce.pcestore.PcePathInfo; 33 import org.onosproject.pce.pcestore.PcePathInfo;
33 import org.onosproject.pce.pcestore.api.PceStore; 34 import org.onosproject.pce.pcestore.api.PceStore;
34 35
...@@ -43,8 +44,8 @@ public class PceStoreAdapter implements PceStore { ...@@ -43,8 +44,8 @@ public class PceStoreAdapter implements PceStore {
43 // Set of Path info 44 // Set of Path info
44 private Set<PcePathInfo> failedPathInfoSet = new HashSet<>(); 45 private Set<PcePathInfo> failedPathInfoSet = new HashSet<>();
45 46
46 - // Locally maintain LSRID to device id mapping for better performance. 47 + // Locally maintain with tunnel name as key and corresponding list of explicit path object
47 - private Map<String, DeviceId> lsrIdDeviceIdMap = new HashMap<>(); 48 + private Map<String, List<ExplicitPathInfo>> tunnelNameExplicitPathInfoMap = new HashMap<>();
48 49
49 @Override 50 @Override
50 public boolean existsTunnelInfo(TunnelId tunnelId) { 51 public boolean existsTunnelInfo(TunnelId tunnelId) {
...@@ -108,4 +109,15 @@ public class PceStoreAdapter implements PceStore { ...@@ -108,4 +109,15 @@ public class PceStoreAdapter implements PceStore {
108 } 109 }
109 return true; 110 return true;
110 } 111 }
112 +
113 + @Override
114 + public boolean tunnelNameExplicitPathInfoMap(String tunnelName, List<ExplicitPathInfo> explicitPathInfo) {
115 + tunnelNameExplicitPathInfoMap.put(tunnelName, explicitPathInfo);
116 + return false;
117 + }
118 +
119 + @Override
120 + public List<ExplicitPathInfo> getTunnelNameExplicitPathInfoMap(String tunnelName) {
121 + return tunnelNameExplicitPathInfoMap.get(tunnelName);
122 + }
111 } 123 }
......
...@@ -16,9 +16,22 @@ ...@@ -16,9 +16,22 @@
16 package org.onosproject.pcerest; 16 package org.onosproject.pcerest;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 +import static org.onosproject.net.Link.State.ACTIVE;
20 +import static org.onosproject.net.Link.Type.DIRECT;
21 +
22 +import com.fasterxml.jackson.databind.node.ArrayNode;
23 +import com.google.common.collect.ImmutableList;
24 +import com.google.common.collect.Lists;
19 25
20 import org.onosproject.codec.CodecContext; 26 import org.onosproject.codec.CodecContext;
21 import org.onosproject.codec.JsonCodec; 27 import org.onosproject.codec.JsonCodec;
28 +import org.onosproject.net.ConnectPoint;
29 +import org.onosproject.net.DefaultLink;
30 +import org.onosproject.net.DeviceId;
31 +import org.onosproject.net.NetworkResource;
32 +import org.onosproject.net.PortNumber;
33 +import org.onosproject.net.provider.ProviderId;
34 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
22 import org.onosproject.pce.pceservice.PcePath; 35 import org.onosproject.pce.pceservice.PcePath;
23 import org.onosproject.pce.pceservice.DefaultPcePath; 36 import org.onosproject.pce.pceservice.DefaultPcePath;
24 import org.onosproject.net.intent.constraint.BandwidthConstraint; 37 import org.onosproject.net.intent.constraint.BandwidthConstraint;
...@@ -29,6 +42,11 @@ import org.slf4j.LoggerFactory; ...@@ -29,6 +42,11 @@ import org.slf4j.LoggerFactory;
29 import com.fasterxml.jackson.databind.node.ObjectNode; 42 import com.fasterxml.jackson.databind.node.ObjectNode;
30 import com.fasterxml.jackson.databind.JsonNode; 43 import com.fasterxml.jackson.databind.JsonNode;
31 44
45 +import java.util.Collection;
46 +import java.util.Collections;
47 +import java.util.LinkedList;
48 +import java.util.List;
49 +
32 /** 50 /**
33 * PCE path json codec. 51 * PCE path json codec.
34 */ 52 */
...@@ -42,7 +60,13 @@ public final class PcePathCodec extends JsonCodec<PcePath> { ...@@ -42,7 +60,13 @@ public final class PcePathCodec extends JsonCodec<PcePath> {
42 private static final String COST = "cost"; 60 private static final String COST = "cost";
43 private static final String BANDWIDTH = "bandwidth"; 61 private static final String BANDWIDTH = "bandwidth";
44 private static final String PATH_ID = "pathId"; 62 private static final String PATH_ID = "pathId";
63 + private static final String EXPLICIT_PATH_INFO = "explicitPathInfo";
45 private static final String MISSING_MEMBER_MESSAGE = " member is required in pce-path"; 64 private static final String MISSING_MEMBER_MESSAGE = " member is required in pce-path";
65 + public static final String JSON_NOT_NULL = "JsonNode can not be null";
66 + public static final byte SOURCE_DEVICEID_INDEX = 0;
67 + public static final byte SOURCE_PORTNO_INDEX = 1;
68 + public static final byte DESTINATION_DEVICEID_INDEX = 2;
69 + public static final byte DESTINATION_PORTNO_INDEX = 3;
46 70
47 @Override 71 @Override
48 public PcePath decode(ObjectNode json, CodecContext context) { 72 public PcePath decode(ObjectNode json, CodecContext context) {
...@@ -114,9 +138,87 @@ public final class PcePathCodec extends JsonCodec<PcePath> { ...@@ -114,9 +138,87 @@ public final class PcePathCodec extends JsonCodec<PcePath> {
114 } 138 }
115 } 139 }
116 140
141 + // Retrieve explicit path info
142 + JsonNode explicitPathInfo = json.get(EXPLICIT_PATH_INFO);
143 + if (explicitPathInfo != null) {
144 + List<ExplicitPathInfo> explicitPathInfoList =
145 + ImmutableList.copyOf(jsonNodeToExplicitPathInfo(explicitPathInfo));
146 + if (explicitPathInfoList != null) {
147 + resultBuilder.explicitPathInfo(explicitPathInfoList);
148 + }
149 + }
150 +
117 return resultBuilder.build(); 151 return resultBuilder.build();
118 } 152 }
119 153
154 + private ExplicitPathInfo createListOfExplicitPathObj(JsonNode node) {
155 + int explicitPathType = Integer.parseInt(node.get("type").asText());
156 + DeviceId deviceId;
157 + PortNumber portNo;
158 + NetworkResource res;
159 + LinkedList<ExplicitPathInfo> list = Lists.newLinkedList();
160 + if ((explicitPathType < 0) || (explicitPathType > 1)) {
161 + return null;
162 + }
163 + ExplicitPathInfo.Type type = ExplicitPathInfo.Type.values()[explicitPathType];
164 + String subType = node.get("subtype").asText();
165 + if (Integer.parseInt(subType) == 0) {
166 + res = DeviceId.deviceId(node.get("value").asText());
167 + } else if (Integer.parseInt(subType) == 1) {
168 +
169 + String[] splitted = node.get("value").asText().split("/");
170 +
171 + if (splitted[SOURCE_DEVICEID_INDEX] != null
172 + && splitted[SOURCE_PORTNO_INDEX] != null
173 + && splitted[DESTINATION_DEVICEID_INDEX] != null
174 + && splitted[DESTINATION_PORTNO_INDEX] != null) {
175 + return null;
176 + }
177 + deviceId = DeviceId.deviceId(splitted[SOURCE_DEVICEID_INDEX]);
178 + portNo = PortNumber.portNumber(splitted[SOURCE_PORTNO_INDEX]);
179 + ConnectPoint cpSrc = new ConnectPoint(deviceId, portNo);
180 + deviceId = DeviceId.deviceId(splitted[DESTINATION_DEVICEID_INDEX]);
181 + portNo = PortNumber.portNumber(splitted[DESTINATION_PORTNO_INDEX]);
182 + ConnectPoint cpDst = new ConnectPoint(deviceId, portNo);
183 + res = DefaultLink.builder()
184 + .providerId(ProviderId.NONE)
185 + .src(cpSrc)
186 + .dst(cpDst)
187 + .type(DIRECT)
188 + .state(ACTIVE)
189 + .build();
190 + } else {
191 + return null;
192 + }
193 +
194 + return new ExplicitPathInfo(type, res);
195 + }
196 +
197 + private Collection<ExplicitPathInfo> jsonNodeToExplicitPathInfo(JsonNode explicitPathInfo) {
198 + checkNotNull(explicitPathInfo, JSON_NOT_NULL);
199 +
200 + Integer i = 0;
201 + NetworkResource res;
202 + LinkedList<ExplicitPathInfo> list = Lists.newLinkedList();
203 + if (explicitPathInfo.isArray()) {
204 + for (JsonNode node : explicitPathInfo) {
205 + ExplicitPathInfo obj = createListOfExplicitPathObj(node);
206 + if (obj == null) {
207 + return null;
208 + }
209 + list.add(obj);
210 + }
211 + } else {
212 + ExplicitPathInfo obj = createListOfExplicitPathObj(explicitPathInfo);
213 + if (obj == null) {
214 + return null;
215 + }
216 + list.add(obj);
217 + }
218 +
219 + return Collections.unmodifiableCollection(list);
220 + }
221 +
120 @Override 222 @Override
121 public ObjectNode encode(PcePath path, CodecContext context) { 223 public ObjectNode encode(PcePath path, CodecContext context) {
122 checkNotNull(path, "path output cannot be null"); 224 checkNotNull(path, "path output cannot be null");
...@@ -133,6 +235,18 @@ public final class PcePathCodec extends JsonCodec<PcePath> { ...@@ -133,6 +235,18 @@ public final class PcePathCodec extends JsonCodec<PcePath> {
133 .put(COST, ((CostConstraint) path.costConstraint()).type().type()) 235 .put(COST, ((CostConstraint) path.costConstraint()).type().type())
134 .put(BANDWIDTH, ((BandwidthConstraint) path.bandwidthConstraint()).bandwidth().bps()); 236 .put(BANDWIDTH, ((BandwidthConstraint) path.bandwidthConstraint()).bandwidth().bps());
135 237
238 + if (path.explicitPathInfo() != null && !path.explicitPathInfo().isEmpty()) {
239 + ArrayNode arrayNode = context.mapper().createArrayNode();
240 + for (ExplicitPathInfo e : path.explicitPathInfo()) {
241 + ObjectNode node = context.mapper()
242 + .createObjectNode()
243 + .put("type", e.type().toString())
244 + .put("value", e.value().toString());
245 + arrayNode.add(node);
246 + }
247 + result.set(EXPLICIT_PATH_INFO, arrayNode);
248 + }
249 +
136 result.set(CONSTRAINT, constraintNode); 250 result.set(CONSTRAINT, constraintNode);
137 return result; 251 return result;
138 } 252 }
......
...@@ -35,11 +35,13 @@ import javax.ws.rs.Produces; ...@@ -35,11 +35,13 @@ import javax.ws.rs.Produces;
35 import javax.ws.rs.core.MediaType; 35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response; 36 import javax.ws.rs.core.Response;
37 37
38 +import com.google.common.collect.ImmutableList;
38 import org.onosproject.incubator.net.tunnel.Tunnel; 39 import org.onosproject.incubator.net.tunnel.Tunnel;
39 import org.onosproject.incubator.net.tunnel.TunnelId; 40 import org.onosproject.incubator.net.tunnel.TunnelId;
40 import org.onosproject.incubator.net.tunnel.TunnelService; 41 import org.onosproject.incubator.net.tunnel.TunnelService;
41 import org.onosproject.net.DeviceId; 42 import org.onosproject.net.DeviceId;
42 import org.onosproject.net.intent.Constraint; 43 import org.onosproject.net.intent.Constraint;
44 +import org.onosproject.pce.pceservice.ExplicitPathInfo;
43 import org.onosproject.pce.pceservice.api.PceService; 45 import org.onosproject.pce.pceservice.api.PceService;
44 import org.onosproject.pce.pceservice.PcePath; 46 import org.onosproject.pce.pceservice.PcePath;
45 import org.onosproject.pce.pceservice.DefaultPcePath; 47 import org.onosproject.pce.pceservice.DefaultPcePath;
...@@ -150,8 +152,14 @@ public class PcePathWebResource extends AbstractWebResource { ...@@ -150,8 +152,14 @@ public class PcePathWebResource extends AbstractWebResource {
150 // Add cost 152 // Add cost
151 listConstrnt.add(path.costConstraint()); 153 listConstrnt.add(path.costConstraint());
152 154
155 + List<ExplicitPathInfo> explicitPathInfoList = null;
156 + if (explicitPathInfoList != null) {
157 + explicitPathInfoList = ImmutableList.copyOf(path.explicitPathInfo());
158 + }
159 +
153 Boolean issuccess = nullIsNotFound(get(PceService.class) 160 Boolean issuccess = nullIsNotFound(get(PceService.class)
154 - .setupPath(srcDevice, dstDevice, path.name(), listConstrnt, lspType), 161 + .setupPath(srcDevice, dstDevice, path.name(), listConstrnt,
162 + lspType, explicitPathInfoList),
155 PCE_SETUP_PATH_FAILED); 163 PCE_SETUP_PATH_FAILED);
156 return Response.status(OK).entity(issuccess.toString()).build(); 164 return Response.status(OK).entity(issuccess.toString()).build();
157 } catch (IOException e) { 165 } catch (IOException e) {
......
...@@ -64,6 +64,7 @@ import org.onosproject.net.DeviceId; ...@@ -64,6 +64,7 @@ import org.onosproject.net.DeviceId;
64 import org.onosproject.net.Link; 64 import org.onosproject.net.Link;
65 import org.onosproject.pce.pceservice.api.PceService; 65 import org.onosproject.pce.pceservice.api.PceService;
66 import org.onosproject.pce.pceservice.PcepAnnotationKeys; 66 import org.onosproject.pce.pceservice.PcepAnnotationKeys;
67 +import org.onosproject.pce.pcestore.api.PceStore;
67 import org.onosproject.net.Path; 68 import org.onosproject.net.Path;
68 import org.onosproject.net.PortNumber; 69 import org.onosproject.net.PortNumber;
69 import org.onosproject.net.provider.ProviderId; 70 import org.onosproject.net.provider.ProviderId;
...@@ -73,6 +74,7 @@ import org.onosproject.net.provider.ProviderId; ...@@ -73,6 +74,7 @@ import org.onosproject.net.provider.ProviderId;
73 */ 74 */
74 public class PcePathResourceTest extends PceResourceTest { 75 public class PcePathResourceTest extends PceResourceTest {
75 private final PceService pceService = createMock(PceService.class); 76 private final PceService pceService = createMock(PceService.class);
77 + private final PceStore pceStore = createMock(PceStore.class);
76 private final TunnelService tunnelService = createMock(TunnelService.class); 78 private final TunnelService tunnelService = createMock(TunnelService.class);
77 private final TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423)); 79 private final TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423));
78 private final TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421)); 80 private final TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421));
...@@ -102,6 +104,7 @@ public class PcePathResourceTest extends PceResourceTest { ...@@ -102,6 +104,7 @@ public class PcePathResourceTest extends PceResourceTest {
102 MockPceCodecContext context = new MockPceCodecContext(); 104 MockPceCodecContext context = new MockPceCodecContext();
103 ServiceDirectory testDirectory = new TestServiceDirectory().add(PceService.class, pceService) 105 ServiceDirectory testDirectory = new TestServiceDirectory().add(PceService.class, pceService)
104 .add(TunnelService.class, tunnelService) 106 .add(TunnelService.class, tunnelService)
107 + .add(PceStore.class, pceStore)
105 .add(CodecService.class, context.codecManager()); 108 .add(CodecService.class, context.codecManager());
106 BaseResource.setServiceDirectory(testDirectory); 109 BaseResource.setServiceDirectory(testDirectory);
107 110
...@@ -233,7 +236,7 @@ public class PcePathResourceTest extends PceResourceTest { ...@@ -233,7 +236,7 @@ public class PcePathResourceTest extends PceResourceTest {
233 */ 236 */
234 @Test 237 @Test
235 public void testPost() { 238 public void testPost() {
236 - expect(pceService.setupPath(anyObject(), anyObject(), anyObject(), anyObject(), anyObject())) 239 + expect(pceService.setupPath(anyObject(), anyObject(), anyObject(), anyObject(), anyObject(), anyObject()))
237 .andReturn(true) 240 .andReturn(true)
238 .anyTimes(); 241 .anyTimes();
239 replay(pceService); 242 replay(pceService);
......
...@@ -7,5 +7,10 @@ ...@@ -7,5 +7,10 @@
7 "constraint": 7 "constraint":
8 { "cost":2, 8 { "cost":2,
9 "bandwidth":200.0 9 "bandwidth":200.0
10 - } 10 + },
11 + "explicitPathInfo" :
12 + {"type":1,
13 + "subtype":0,
14 + "value":"11.0.0.2"
15 + }
11 } 16 }
......
1 {"path": {"source":"11.0.0.1", 1 {"path": {"source":"11.0.0.1",
2 "destination":"11.0.0.2", 2 "destination":"11.0.0.2",
3 - "pathType":"2", 3 + "pathType":"0",
4 - "name":"pcc2", 4 + "name":"rsvp11",
5 - "description":"path-create",
6 "constraint": 5 "constraint":
7 - {"cost":2, 6 + {"cost":1,
8 - "bandwidth":200.0 7 + "bandwidth":300
8 + },
9 + "explicitPathInfo" :
10 + {"type":1,
11 + "subtype":0,
12 + "value":"11.0.0.2"
9 } 13 }
10 } 14 }
11 } 15 }
......
...@@ -507,7 +507,9 @@ public class PceWebTopovMessageHandler extends UiMessageHandler { ...@@ -507,7 +507,9 @@ public class PceWebTopovMessageHandler extends UiMessageHandler {
507 break; 507 break;
508 } 508 }
509 509
510 - path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal); 510 + //TODO: need to get explicit paths [temporarily using null as the value]
511 + path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal,
512 + null);
511 if (!path) { 513 if (!path) {
512 log.error("setup path is failed"); 514 log.error("setup path is failed");
513 return; 515 return;
......