2 * Copyright (c) 2021 Orange. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.bgpcep.pcep.server.provider;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.base.MoreObjects;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.MoreExecutors;
18 import java.nio.ByteBuffer;
19 import java.util.Collections;
20 import org.opendaylight.graph.ConnectedEdge;
21 import org.opendaylight.graph.ConnectedGraph;
22 import org.opendaylight.mdsal.binding.api.WriteTransaction;
23 import org.opendaylight.mdsal.common.api.CommitInfo;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.AddressFamily;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ComputationStatus;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.path.descriptions.PathDescription;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments2Builder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments3Builder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.LspBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathComputationClient1;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathStatus;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.PathType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLsp;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.ConfiguredLspBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.IntendedPath;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev210720.pcc.configured.lsp.configured.lsp.intended.path.Constraints;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.BandwidthBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4CaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv6CaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.ipv4._case.Ipv4Builder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.ipv6._case.Ipv6Builder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObjBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.MetricBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.path.setup.type.tlv.PathSetupTypeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspInputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspOutput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.NetworkTopologyPcepService;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.Node1;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspInputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.add.lsp.args.ArgumentsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.pcep.client.attributes.PathComputationClient;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
70 import org.opendaylight.yangtools.yang.binding.CodeHelpers;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.opendaylight.yangtools.yang.common.RpcResult;
73 import org.opendaylight.yangtools.yang.common.Uint8;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
77 public class ManagedTePath {
79 private ConfiguredLsp cfgLsp = null;
80 private ConfiguredLsp prevLsp = null;
81 private final ManagedTeNode teNode;
82 private boolean sent = false;
83 private PathType type = PathType.Pcc;
84 private final InstanceIdentifier<Topology> pcepTopology;
85 private final InstanceIdentifier<PathComputationClient1> pccIdentifier;
87 private static final Logger LOG = LoggerFactory.getLogger(ManagedTePath.class);
89 public ManagedTePath(ManagedTeNode teNode, InstanceIdentifier<Topology> topology) {
90 this.teNode = requireNonNull(teNode);
91 this.pcepTopology = requireNonNull(topology);
92 this.pccIdentifier = pcepTopology.child(Node.class, new NodeKey(teNode.getId())).augmentation(Node1.class)
93 .child(PathComputationClient.class).augmentation(PathComputationClient1.class);
96 public ManagedTePath(ManagedTeNode teNode, final ConfiguredLsp lsp, InstanceIdentifier<Topology> topology) {
97 this.cfgLsp = requireNonNull(lsp);
98 this.teNode = requireNonNull(teNode);
99 this.pcepTopology = requireNonNull(topology);
100 this.pccIdentifier = pcepTopology.child(Node.class, new NodeKey(teNode.getId())).augmentation(Node1.class)
101 .child(PathComputationClient.class).augmentation(PathComputationClient1.class);
104 public ManagedTePath(ManagedTeNode teNode, final ManagedTePath mngPath) {
105 checkArgument(mngPath != null, "Managed TE Path is mandatory. Can't be null or empty!");
106 this.cfgLsp = mngPath.getLsp();
107 this.sent = mngPath.isSent();
108 this.type = mngPath.getType();
109 this.teNode = requireNonNull(teNode);
110 this.pcepTopology = mngPath.getTopology();
111 this.pccIdentifier = pcepTopology.child(Node.class, new NodeKey(teNode.getId())).augmentation(Node1.class)
112 .child(PathComputationClient.class).augmentation(PathComputationClient1.class);
115 public ConfiguredLsp getLsp() {
119 public ManagedTeNode getManagedTeNode() {
123 public PathType getType() {
127 public InstanceIdentifier<Topology> getTopology() {
131 public ManagedTePath setConfiguredLsp(final ConfiguredLsp lsp) {
132 this.prevLsp = this.cfgLsp;
137 public ManagedTePath setType(PathType type) {
143 * Mark this TE Path as synchronized and update the Data Store accordingly.
147 this.cfgLsp = new ConfiguredLspBuilder(cfgLsp).setPathStatus(PathStatus.Sync).build();
152 * Disabling this TE Path by marking it as Configured. Do not update the Data Store.
154 public void disabled() {
155 this.cfgLsp = new ConfiguredLspBuilder(cfgLsp).setPathStatus(PathStatus.Configured).build();
159 * Mark this TE Path as Failed.
161 public void failed() {
162 this.cfgLsp = new ConfiguredLspBuilder(cfgLsp).setPathStatus(PathStatus.Failed).build();
166 public boolean isSent() {
171 * Compare the current TE Path against the reported LSP to determine if there are in Sync, need Update or
172 * considered as in Failure if already updated.
174 * @param lsp LSP that corresponds to the reported LSP
176 * @return new LSP status
178 public PathStatus checkReportedPath(final ConfiguredLsp lsp) {
179 /* Check if this path has not been already verified */
180 if (cfgLsp.getPathStatus() == PathStatus.Sync) {
181 return PathStatus.Sync;
184 /* Check Source, Destination and routing method which must be the same */
185 final IntendedPath iPath = lsp.getIntendedPath();
186 final IntendedPath rPath = lsp.getIntendedPath();
187 PathStatus newStatus = sent ? PathStatus.Failed : PathStatus.Updated;
188 if (!iPath.getSource().equals(rPath.getSource()) || !iPath.getDestination().equals(rPath.getDestination())) {
189 return PathStatus.Failed;
192 /* Check constraints ... */
193 final Constraints icts = iPath.getConstraints();
194 final Constraints rcts = rPath.getConstraints();
195 if (!icts.getAddressFamily().equals(rcts.getAddressFamily())) {
198 if (icts.getBandwidth() != null && !icts.getBandwidth().equals(rcts.getBandwidth())) {
202 * ClassType, TE metric and Delay are not supported by all routers: need
203 * to check them only if there are all present
205 if (icts.getClassType() != null && rcts.getClassType() != null
206 && !icts.getClassType().equals(rcts.getClassType())) {
209 if (icts.getTeMetric() != null && rcts.getTeMetric() != null
210 && !icts.getTeMetric().equals(rcts.getTeMetric())) {
213 if (icts.getDelay() != null && rcts.getDelay() != null && !icts.getDelay().equals(rcts.getDelay())) {
217 /* ... and Path to determine if an update is required */
218 if (lsp.getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
219 return PathStatus.Failed;
221 if (!lsp.getComputedPath().getPathDescription().equals(lsp.getComputedPath().getPathDescription())) {
225 /* All is conform. LSP is in sync with expected result. */
226 return PathStatus.Sync;
229 public void addBandwidth(ConnectedGraph graph) {
230 /* Check that Connected Graph is valid */
234 /* Verify that we have a valid Computed Path and that the LSP is in SYNC */
235 if (cfgLsp.getComputedPath().getComputationStatus() != ComputationStatus.Completed
236 || cfgLsp.getPathStatus() != PathStatus.Sync) {
239 /* Verify that a Bandwidth has been requested and reserved */
240 if (cfgLsp.getIntendedPath().getConstraints().getBandwidth() == null) {
244 /* Loop the path description to add reserved bandwidth for this LSP */
245 final Long bw = cfgLsp.getIntendedPath().getConstraints().getBandwidth().getValue().longValue();
246 int cos = cfgLsp.getIntendedPath().getConstraints().getClassType() != null
247 ? cfgLsp.getIntendedPath().getConstraints().getClassType().intValue()
249 final AddressFamily af = cfgLsp.getIntendedPath().getConstraints().getAddressFamily();
250 for (PathDescription path : cfgLsp.getComputedPath().getPathDescription()) {
251 ConnectedEdge edge = null;
255 if (path.getIpv4() != null) {
256 edge = graph.getConnectedEdge(new IpAddress(path.getIpv4()));
257 } else if (path.getRemoteIpv4() != null) {
258 edge = graph.getConnectedEdge(new IpAddress(path.getRemoteIpv4()));
260 edge = graph.getConnectedEdge(edge.getEdge().getEdgeAttributes().getRemoteAddress());
266 if (path.getIpv6() != null) {
267 edge = graph.getConnectedEdge(new IpAddress(path.getIpv6()));
268 } else if (path.getRemoteIpv6() != null) {
269 edge = graph.getConnectedEdge(new IpAddress(path.getRemoteIpv6()));
271 /* Need to force using IPv6 address as Connected Edge is searched first on IPv4 address */
272 edge = graph.getConnectedEdge(new IpAddress(
273 edge.getEdge().getEdgeAttributes().getRemoteAddress().getIpv6Address()));
281 edge.addBandwidth(bw, cos);
286 public void delBandwidth(ConnectedGraph graph) {
287 /* Check that Connected Graph is valid */
291 /* Verify that we have a valid Computed Path and that the LSP is in SYNC */
292 if (cfgLsp.getComputedPath().getComputationStatus() != ComputationStatus.Completed
293 || cfgLsp.getPathStatus() != PathStatus.Sync) {
296 /* Verify that a Bandwidth has been requested and reserved */
297 if (cfgLsp.getIntendedPath().getConstraints().getBandwidth() == null) {
301 /* Loop the path description to delete reserved bandwidth for this LSP */
302 final Long bw = cfgLsp.getIntendedPath().getConstraints().getBandwidth().getValue().longValue();
303 int cos = cfgLsp.getIntendedPath().getConstraints().getClassType() != null
304 ? cfgLsp.getIntendedPath().getConstraints().getClassType().intValue()
306 final AddressFamily af = cfgLsp.getIntendedPath().getConstraints().getAddressFamily();
307 for (PathDescription path : cfgLsp.getComputedPath().getPathDescription()) {
308 ConnectedEdge edge = null;
312 edge = graph.getConnectedEdge(new IpAddress(path.getIpv4()));
316 edge = graph.getConnectedEdge(new IpAddress(path.getIpv6()));
322 edge.delBandwidth(bw, cos);
327 public void updateBandwidth(ConnectedGraph graph) {
328 /* Check that Connected Graph is valid */
332 /* First remove Bandwidth for the old path if any */
333 if (prevLsp != null && prevLsp.getIntendedPath().getConstraints().getBandwidth() != null) {
334 final Long bw = prevLsp.getIntendedPath().getConstraints().getBandwidth().getValue().longValue();
335 int cos = prevLsp.getIntendedPath().getConstraints().getClassType() != null
336 ? prevLsp.getIntendedPath().getConstraints().getClassType().intValue()
338 final AddressFamily af = prevLsp.getIntendedPath().getConstraints().getAddressFamily();
339 for (PathDescription path : prevLsp.getComputedPath().getPathDescription()) {
340 ConnectedEdge edge = null;
344 edge = graph.getConnectedEdge(new IpAddress(path.getIpv4()));
348 edge = graph.getConnectedEdge(new IpAddress(path.getIpv6()));
354 edge.delBandwidth(bw, cos);
358 /* Then add Bandwidth for the current path */
360 /* And memorize current LSP for latter update */
365 * Convert LSP as Add LSP Input class to enforce it into the PCC through a call to add-lsp RPCs.
367 * @return new Add LSP Input
369 private AddLspInput getAddLspInput() {
370 /* Create EndPoint Object */
371 final IntendedPath iPath = cfgLsp.getIntendedPath();
372 final EndpointsObjBuilder epb = new EndpointsObjBuilder()
374 .setProcessingRule(true);
375 if (iPath.getSource().getIpv4Address() != null) {
376 final Ipv4Builder ipBuilder = new Ipv4Builder()
377 .setDestinationIpv4Address(new Ipv4AddressNoZone(iPath.getDestination().getIpv4Address()))
378 .setSourceIpv4Address(new Ipv4AddressNoZone(iPath.getSource().getIpv4Address()));
379 epb.setAddressFamily((new Ipv4CaseBuilder().setIpv4(ipBuilder.build()).build()));
380 } else if (cfgLsp.getIntendedPath().getSource().getIpv6Address() != null) {
381 final Ipv6Builder ipBuilder = new Ipv6Builder()
382 .setDestinationIpv6Address(new Ipv6AddressNoZone(iPath.getDestination().getIpv6Address()))
383 .setSourceIpv6Address(new Ipv6AddressNoZone(iPath.getSource().getIpv6Address()));
384 epb.setAddressFamily((new Ipv6CaseBuilder().setIpv6(ipBuilder.build()).build()));
390 /* Create Path Setup Type */
391 final PathSetupTypeBuilder pstBuilder = new PathSetupTypeBuilder();
392 switch (iPath.getConstraints().getAddressFamily()) {
395 pstBuilder.setPst(Uint8.ONE);
398 pstBuilder.setPst(Uint8.ZERO);
403 final LspBuilder lspBuilder = new LspBuilder()
404 .setAdministrative(true)
409 * Note that TE Metric and Delay are not set because, at least, Juniper Routers don't support them.
411 final ArgumentsBuilder args = new ArgumentsBuilder()
412 .setEndpointsObj(epb.build())
413 .setEro(MessagesUtil.getEro(cfgLsp.getComputedPath().getPathDescription()))
414 .addAugmentation(new Arguments2Builder()
415 .setLsp(lspBuilder.build())
416 .setPathSetupType(pstBuilder.build())
419 /* with Bandwidth and Standard Metric */
420 if (iPath.getConstraints().getBandwidth() != null) {
421 final int ftoi = Float.floatToIntBits(iPath.getConstraints().getBandwidth().getValue().floatValue());
422 final byte[] itob = { (byte) (0xFF & ftoi >> 24), (byte) (0xFF & ftoi >> 16), (byte) (0xFF & ftoi >> 8),
423 (byte) (0xFF & ftoi) };
424 args.setBandwidth(new BandwidthBuilder().setBandwidth(new Bandwidth(itob)).build());
426 if (iPath.getConstraints().getMetric() != null) {
427 final MetricBuilder metricBuilder = new MetricBuilder()
429 .setMetricType(Uint8.ONE)
430 .setValue(new Float32(
431 ByteBuffer.allocate(4).putFloat(iPath.getConstraints().getMetric().floatValue()).array()));
432 args.setMetrics(Collections.singletonList(new MetricsBuilder().setMetric(metricBuilder.build()).build()));
436 * NOTE: Seems that ClassType is not supported by some routers. Skip it for the moment.
438 /* With Class Type if defined
439 if (iPath.getConstraints().getClassType() != null) {
441 new ClassTypeBuilder()
442 .setClassType(new ClassType(iPath.getConstraints().getClassType()))
444 .setProcessingRule(true)
449 /* Finally, build addLSP input */
450 return new AddLspInputBuilder()
451 .setNode(teNode.getId())
452 .setName(cfgLsp.getName())
453 .setArguments(args.build())
454 .setNetworkTopologyRef(new NetworkTopologyRef(pcepTopology))
460 * Call add-lsp RPC to enforce the LSP into the PCC. This action will trigger a PcInitiate message to the PCC.
462 * @param ntps Network Topology PCEP Service
464 * @return Add LSP Output to convey the RPC result
466 public ListenableFuture<RpcResult<AddLspOutput>> addPath(final NetworkTopologyPcepService ntps) {
467 /* Check if we could add this path */
468 if ((type != PathType.Initiated) || !teNode.isSync()) {
472 /* Check if we have a valid Path */
473 if (cfgLsp.getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
478 final ListenableFuture<RpcResult<AddLspOutput>> enforce = ntps.addLsp(getAddLspInput());
479 LOG.info("Call Add LSP to {} with {}", ntps, enforce);
480 Futures.addCallback(enforce, new FutureCallback<RpcResult<AddLspOutput>>() {
482 public void onSuccess(final RpcResult<AddLspOutput> result) {
483 if (result.isSuccessful()) {
484 LOG.debug("Enforce LSP success {}", result.getResult());
486 LOG.debug("Unable to enforce LSP {} on Node {}: Got error {}", cfgLsp.getName(), teNode.getId(),
493 public void onFailure(final Throwable throwable) {
494 LOG.warn("Failed enforce LSP {} on Node {}", cfgLsp.getName(), teNode.getId());
497 }, MoreExecutors.directExecutor());
503 * Convert LSP as Update LSP Input class to update it into the PCC through a call to update-lsp RPCs.
505 * @return new Update LSP Input
507 private UpdateLspInput getUpdateLspInput() {
508 /* Create Path Setup Type */
509 final IntendedPath iPath = cfgLsp.getIntendedPath();
510 final PathSetupTypeBuilder pstBuilder = new PathSetupTypeBuilder();
511 switch (iPath.getConstraints().getAddressFamily()) {
514 pstBuilder.setPst(Uint8.ONE);
517 pstBuilder.setPst(Uint8.ZERO);
522 final LspBuilder lspBuilder = new LspBuilder()
523 .setAdministrative(true)
526 /* Build Arguments */
527 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120
528 .update.lsp.args.ArgumentsBuilder args;
529 args = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120
530 .update.lsp.args.ArgumentsBuilder()
531 .addAugmentation(new Arguments3Builder()
532 .setLsp(lspBuilder.build())
533 .setPathSetupType(pstBuilder.build())
535 .setEro(MessagesUtil.getEro(cfgLsp.getComputedPath().getPathDescription()));
537 /* with Bandwidth if defined, but not other Metrics as some routers don't support them */
538 if (iPath.getConstraints().getBandwidth() != null) {
539 final int ftoi = Float.floatToIntBits(iPath.getConstraints().getBandwidth().getValue().floatValue());
540 final byte[] itob = { (byte) (0xFF & ftoi >> 24), (byte) (0xFF & ftoi >> 16), (byte) (0xFF & ftoi >> 8),
541 (byte) (0xFF & ftoi) };
542 args.setBandwidth(new BandwidthBuilder().setBandwidth(new Bandwidth(itob)).build());
546 * NOTE: Seems that ClassType is not supported by some routers. Skip it for the moment.
548 /* With Class Type if defined
549 if (iPath.getConstraints().getClassType() != null) {
551 new ClassTypeBuilder()
552 .setClassType(new ClassType(iPath.getConstraints().getClassType()))
554 .setProcessingRule(true)
559 /* Finally, build updateLSP input */
560 return new UpdateLspInputBuilder()
561 .setNode(teNode.getId())
562 .setName(cfgLsp.getName())
563 .setArguments(args.build())
564 .setNetworkTopologyRef(new NetworkTopologyRef(pcepTopology))
569 * Call update-lsp RPC to enforce the LSP into the PCC. This action will trigger a PcUpdate message to the PCC.
571 * @param ntps Network Topology PCEP Service
573 * @return Update LSP Output to convey the RPC result
575 public ListenableFuture<RpcResult<UpdateLspOutput>> updatePath(final NetworkTopologyPcepService ntps) {
577 /* Check if we could update this path */
578 if ((type != PathType.Initiated && type != PathType.Delegated) || !teNode.isSync()) {
582 /* Check if we have a valid ERO */
583 if (cfgLsp.getComputedPath().getComputationStatus() != ComputationStatus.Completed) {
588 final NodeId id = teNode.getId();
589 final ListenableFuture<RpcResult<UpdateLspOutput>> enforce = ntps.updateLsp(getUpdateLspInput());
590 LOG.info("Call Update LSP to {} with {}", ntps, enforce);
591 Futures.addCallback(enforce, new FutureCallback<RpcResult<UpdateLspOutput>>() {
593 public void onSuccess(final RpcResult<UpdateLspOutput> result) {
594 if (result.isSuccessful()) {
595 LOG.debug("Update LSP success {}", result.getResult());
597 LOG.debug("Unable to update LSP {} on Node {}: Got error {}", cfgLsp.getName(), id,
604 public void onFailure(final Throwable throwable) {
605 LOG.warn("Failed update LSP {} on Node {}", cfgLsp.getName(), id);
608 }, MoreExecutors.directExecutor());
614 * Call remove-lsp RPC to remove the LSP from the PCC. This action will trigger a PcInitiate message to the PCC
617 * @param ntps Network Topology PCEP Service
619 * @return Remove LSP Output to convey the RPC result
621 public ListenableFuture<RpcResult<RemoveLspOutput>> removePath(final NetworkTopologyPcepService ntps) {
623 /* Check if we could remove this path */
624 if ((type != PathType.Initiated) || !teNode.isSync() || cfgLsp.getPathStatus() != PathStatus.Sync) {
629 final NodeId id = teNode.getId();
630 final RemoveLspInput rli = new RemoveLspInputBuilder()
632 .setName(cfgLsp.getName())
633 .setNetworkTopologyRef(new NetworkTopologyRef(pcepTopology))
635 final ListenableFuture<RpcResult<RemoveLspOutput>> enforce = ntps.removeLsp(rli);
636 LOG.info("Call Remove LSP to {} with {}", ntps, enforce);
637 Futures.addCallback(enforce, new FutureCallback<RpcResult<RemoveLspOutput>>() {
639 public void onSuccess(final RpcResult<RemoveLspOutput> result) {
640 if (result.isSuccessful()) {
641 LOG.debug("Delete LSP success {}", result.getResult());
643 LOG.debug("Unable to delete LSP {} on Node {}: Got error {}", cfgLsp.getName(), id,
650 public void onFailure(final Throwable throwable) {
651 LOG.warn("Failed delete LSP {} on Node {}", cfgLsp.getName(), id);
654 }, MoreExecutors.directExecutor());
660 * Add LSP components to the Operational Data Store.
662 public synchronized void addToDataStore() {
663 /* Check if we could add this path */
664 if (!teNode.isSync()) {
668 final WriteTransaction trans = teNode.getTransaction();
669 trans.put(LogicalDatastoreType.OPERATIONAL, pccIdentifier.child(ConfiguredLsp.class, cfgLsp.key()), cfgLsp);
670 trans.commit().addCallback(new FutureCallback<CommitInfo>() {
672 public void onSuccess(final CommitInfo result) {
673 LOG.debug("Configured LSP {} has been published in operational datastore ", cfgLsp.getName());
677 public void onFailure(final Throwable throwable) {
678 LOG.error("Cannot write Configured LSP {} to the operational datastore (transaction: {})",
679 cfgLsp.getName(), trans.getIdentifier());
681 }, MoreExecutors.directExecutor());
685 * Update LSP components to the Data Store.
687 public synchronized void updateToDataStore() {
688 /* Check if we could update this path */
689 if (!teNode.isSync()) {
693 final WriteTransaction trans = teNode.getTransaction();
694 trans.merge(LogicalDatastoreType.OPERATIONAL, pccIdentifier.child(ConfiguredLsp.class, cfgLsp.key()), cfgLsp);
695 trans.commit().addCallback(new FutureCallback<CommitInfo>() {
697 public void onSuccess(final CommitInfo result) {
698 LOG.debug("Configured LSP {} has been updated in operational datastore ", cfgLsp.getName());
702 public void onFailure(final Throwable throwable) {
703 LOG.error("Cannot update Configured LSP {} to the operational datastore (transaction: {})",
704 cfgLsp.getName(), trans.getIdentifier());
706 }, MoreExecutors.directExecutor());
710 * Remove LSP components to the Data Store.
712 public synchronized void removeFromDataStore() {
713 /* Check if we could remove this path */
714 if (!teNode.isSync()) {
718 final WriteTransaction trans = teNode.getTransaction();
719 trans.delete(LogicalDatastoreType.OPERATIONAL, pccIdentifier.child(ConfiguredLsp.class, cfgLsp.key()));
720 trans.commit().addCallback(new FutureCallback<CommitInfo>() {
722 public void onSuccess(final CommitInfo result) {
723 LOG.debug("Configured LSP {} has been deleted in operational datastore ", cfgLsp.getName());
727 public void onFailure(final Throwable throwable) {
728 LOG.error("Cannot delete Configured LSP {} from the operational datastore (transaction: {})",
729 cfgLsp.getName(), trans.getIdentifier());
731 }, MoreExecutors.directExecutor());
735 public String toString() {
736 final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper("ManagedTePath");
737 CodeHelpers.appendValue(helper, "ConfiguredLsp", cfgLsp);
738 CodeHelpers.appendValue(helper, "PathType", type);
739 CodeHelpers.appendValue(helper, "Sent", sent);
740 return helper.toString();