Merge "Add model of graceful-restart capability"
authorDana Kutenicsova <dkutenic@cisco.com>
Sat, 9 Nov 2013 15:46:11 +0000 (15:46 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 9 Nov 2013 15:46:11 +0000 (15:46 +0000)
concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java
pcep/api/src/main/yang/pcep-types.yang
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java
programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang
rsvp/api/src/main/yang/rsvp.yang

index dfa552b126cdb2662a4d240ccd62531026c4f376..6fced21e9dae2ce2d8ce9e2be6d2d737f9b02cbe 100644 (file)
@@ -18,7 +18,6 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth;
index 6326985a4f93c0d099217a35cf47970e7e95f57f..43112e3da349ae5d77683c7dc0bbe9291f4a6650 100644 (file)
@@ -662,23 +662,7 @@ module pcep-types {
 
                container lspa {
                        uses object;
-
-                       leaf hold-priority {
-                               type uint8;
-                               mandatory true;
-                       }
-
-                       leaf setup-priority {
-                               type uint8;
-                               mandatory true;
-                       }
-
-                       leaf local-protection-desired {
-                               type boolean;
-                               default false;
-                       }
-
-                       uses rsvp:attribute-filters;
+                       uses rsvp:tunnel-attributes;
                }
        }
 
index 7a51170d8e5df730a3b9966dc7539d5f1a4ca7b6..9e38ec9a8cfda601c57c6362acb4ec611c841352 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
-import com.google.common.base.Preconditions;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
@@ -30,8 +29,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.InetSocketAddress;
-import java.util.concurrent.ExecutionException;
+import com.google.common.base.Preconditions;
 
 public final class BundleActivator extends AbstractBindingAwareProvider {
        private static final Logger LOG = LoggerFactory.getLogger(BundleActivator.class);
@@ -46,7 +44,7 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                final Open prefs = spf.getSessionProposal(address, 0);
                final PCEPDispatcher dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl
                                .getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(
-                               new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup());
+                                               new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup());
 
                final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder().node(Topology.class).toInstance();
 
index eb2de0203a54505002a5ab211123f87fa8d82119..67b6c24837c7da96c9f5ec3b9ffee63555a14426 100644 (file)
@@ -6,6 +6,7 @@ module topology-tunnel-pcep-programming {
        import pcep-types { prefix pcep; revision-date 2013-10-05; }
         import topology-tunnel-programming { prefix ttp; revision-date 2013-09-30; }
        import topology-tunnel-p2p { prefix p2p; revision-date 2013-08-19; }
+       import topology-tunnel-pcep { prefix ptp; }
 
         organization "Cisco Systems, Inc.";
         contact "Robert Varga <rovarga@cisco.com>";
@@ -32,6 +33,7 @@ module topology-tunnel-pcep-programming {
                        uses ttp:create-p2p-tunnel-input;
 
                        uses p2p:tunnel-p2p-path-cfg-attributes;
+                       uses ptp:tunnel-pcep-link-cfg-attributes;
                }
                output {
                        uses ttp:create-p2p-tunnel-output;
@@ -52,6 +54,7 @@ module topology-tunnel-pcep-programming {
                        uses ttp:base-tunnel-input;
 
                        uses p2p:tunnel-p2p-path-cfg-attributes;
+                       uses ptp:tunnel-pcep-link-cfg-attributes;
                }
 
                output {
index e17563e6e78979dd3ce0848b67b4419f74ff22a9..4e2f54cd81dbdbd90a11692310875757681a6ea7 100644 (file)
@@ -4,8 +4,8 @@ module topology-tunnel-pcep {
        namespace "urn:opendaylight:params:xml:ns:yang:topology:tunnel:pcep";
        prefix "pceptun";
 
-       import ieee754 { prefix ieee754; revision-date 2013-08-19; }
        import network-topology { prefix nt; revision-date 2013-10-21; }
+    import nps-concepts { prefix nps-c; }
        import pcep-types { prefix pcep; revision-date 2013-10-05; }
        import rsvp { prefix rsvp; revision-date 2013-08-20; }
        import topology-tunnel { prefix tt; revision-date 2013-08-19; }
@@ -34,6 +34,31 @@ module topology-tunnel-pcep {
                reference "https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-05#section-7.3";
        }
 
+       grouping topology-tunnel-pcep-type {
+               container topology-tunnel-pcep {
+                       presence "indicates a PCEP tunnel-aware topology";
+               }
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:topology-types" {
+               uses topology-tunnel-pcep-type;
+       }
+
+    grouping tunnel-pcep-supporting-node-attributes {
+        container path-computation-client {
+            leaf controlling {
+                type boolean;
+                default false;
+            }
+        }
+    }
+
+       augment "/nt:network-topology/nt:topology/nt:node/nt:supporting-node" {
+        when "../../../nt:topology-types/topology-tunnel-pcep";
+
+        uses tunnel-pcep-supporting-node-attributes;
+    }
+
        grouping tunnel-pcep-type {
                container pcep-tunnel {
                        presence "indicates a link is a PCEP tunnel";
@@ -44,22 +69,30 @@ module topology-tunnel-pcep {
                uses tunnel-pcep-type;
        }
 
-       grouping tunnel-pcep-link-attributes {
+       grouping tunnel-pcep-link-cfg-attributes {
                leaf administrative-status {
                        type administrative-status;
                }
 
-               leaf operational-status {
-                       type pcep:operational-status;
-                       config false;
-               }
-
                leaf class-type {
                        type pcep:class-type;
                }
 
                leaf bandwidth {
-                       type ieee754:float32;
+                       type nps-c:bandwidth;
+               }
+
+        leaf symbolic-path-name {
+            type pcep:symbolic-path-name;
+        }
+
+        uses rsvp:tunnel-attributes;
+       }
+
+       grouping tunnel-pcep-link-oper-attributes {
+               leaf operational-status {
+                       type pcep:operational-status;
+                       config false;
                }
        }
 
@@ -76,7 +109,8 @@ module topology-tunnel-pcep {
 
        augment "/nt:network-topology/nt:topology/nt:link" {
                when "../../tunnel-types/pcep-tunnel";
-               uses tunnel-pcep-link-attributes;
+               uses tunnel-pcep-link-cfg-attributes;
+               uses tunnel-pcep-link-oper-attributes;
        }
 
        augment "/nt:network-topology/nt:topology/tt:paths" {
index 754925de33f8bbb48ed32f427ebccbc92e20a877..8bea183e83d09354df8d01e99fefede559ddeeb6 100644 (file)
@@ -22,6 +22,6 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                tte.addTargetTopology(null);
 
                final InstructionScheduler scheduler = null;
-               final TunnelProgramming tp = new TunnelProgramming(scheduler, session.getRpcService(NetworkTopologyPcepService.class));
+               final TunnelProgramming tp = new TunnelProgramming(scheduler, dps, session.getRpcService(NetworkTopologyPcepService.class));
        }
 }
index a81fcb0b4a9508d197d1cf36857c2f4c459df53c..8d939a28286c92dce007cb2a1c5106f88f058c84 100644 (file)
@@ -16,8 +16,13 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.SymbolicPathName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsps;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -77,4 +82,10 @@ final class NodeChangedListener implements DataChangeListener {
                        LOG.error("Failed to propagate a topology change, target topology became inconsistent", e);
                }
        }
-}
\ No newline at end of file
+
+       public static InstanceIdentifier<Link> linkIdentifier(final InstanceIdentifier<Topology> topology,
+                       final NodeId node, final SymbolicPathName name) {
+               return InstanceIdentifier.builder(topology).
+                               node(Link.class, new LinkKey(new LinkId(node.getValue() + "/lsp/" + name))).toInstance();
+       }
+}
index 963d91ff3e01791f4b3100f52c86616564a54d05..0bea03fda35d0c3ed90326171a67194a5cbdcfcc 100644 (file)
@@ -8,10 +8,27 @@
 package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.opendaylight.bgpcep.pcep.topology.spi.AbstractTopologyProgrammingExecutor;
 import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.BandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.classtype.object.ClassTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.EndpointsObjBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobjects;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.LspaBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.FailureBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.failure.Failure;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInputBuilder;
@@ -22,6 +39,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.add.lsp.args.ArgumentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.programming.rev131102.TopologyInstructionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.p2p.rev130819.tunnel.p2p.path.cfg.attributes.ExplicitHops;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutputBuilder;
@@ -32,7 +52,30 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.AdministrativeStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.ExplicitHops1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.Link1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.SupportingNode1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.BaseTunnelInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.TpReference;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.TerminationPointType;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.Ip;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
@@ -40,35 +83,179 @@ import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
 final class TunnelProgramming implements TopologyTunnelPcepProgrammingService {
-       private final NetworkTopologyPcepService pcepTopology;
+       private static final Logger LOG = LoggerFactory.getLogger(TunnelProgramming.class);
+       private final NetworkTopologyPcepService topologyService;
+       private final DataProviderService dataProvider;
        private final InstructionScheduler scheduler;
 
-       TunnelProgramming(final InstructionScheduler scheduler, final NetworkTopologyPcepService pcepTopology) {
+       TunnelProgramming(final InstructionScheduler scheduler, final DataProviderService dataProvider,
+                       final NetworkTopologyPcepService topologyService) {
                this.scheduler = Preconditions.checkNotNull(scheduler);
-               this.pcepTopology = Preconditions.checkNotNull(pcepTopology);
+               this.dataProvider = Preconditions.checkNotNull(dataProvider);
+               this.topologyService = Preconditions.checkNotNull(topologyService);
        }
 
-       @Override
-       public ListenableFuture<RpcResult<PcepCreateP2pTunnelOutput>> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) {
-               Preconditions.checkNotNull(input.getLinkId());
-               Preconditions.checkNotNull(input.getSourceTp());
-               Preconditions.checkNotNull(input.getDestinationTp());
+       private static final class TpReader {
+               private final DataModificationTransaction t;
+               private final InstanceIdentifier<Node> nii;
+               private final InstanceIdentifier<TerminationPoint> tii;
+
+               TpReader(final DataModificationTransaction t, final InstanceIdentifier<Topology> topo, final TpReference ref) {
+                       this.t = Preconditions.checkNotNull(t);
+
+                       nii = InstanceIdentifier.builder(topo).node(Node.class, new NodeKey(ref.getNode())).toInstance();
+                       tii = InstanceIdentifier.builder(nii).node(TerminationPoint.class, new TerminationPointKey(ref.getTp())).toInstance();
+               }
+
+               private Node getNode() {
+                       return (Node) t.readOperationalData(nii);
+               }
+
+               private TerminationPoint getTp() {
+                       return (TerminationPoint) t.readOperationalData(tii);
+               }
+       }
+
+       private AddressFamily buildAddressFamily(final TerminationPoint sp, final TerminationPoint dp) {
+               // We need the IGP augmentation -- it has IP addresses
+               final TerminationPoint1 sp1 = Preconditions.checkNotNull(sp.getAugmentation(TerminationPoint1.class));
+               final TerminationPoint1 dp1 = Preconditions.checkNotNull(dp.getAugmentation(TerminationPoint1.class));
+
+               // Get the types
+               final TerminationPointType spt = sp1.getIgpTerminationPointAttributes().getTerminationPointType();
+               final TerminationPointType dpt = dp1.getIgpTerminationPointAttributes().getTerminationPointType();
+
+               // The types have to match
+               Preconditions.checkArgument(spt.getImplementedInterface().equals(dpt.getImplementedInterface()));
+
+               // And they have to actually be Ip
+               final Ip sips = (Ip) spt;
+               final Ip dips = (Ip) dpt;
+
+               /*
+                * Now a bit of magic. We need to find 'like' addresses, e.g. both
+                * IPv4 or both IPv6. We are in IPv6-enabled world now, so let's
+                * prefer that.
+                */
+               AddressFamily ret = findIpv6(sips.getIpAddress(), dips.getIpAddress());
+               if (ret == null) {
+                       ret = findIpv4(sips.getIpAddress(), dips.getIpAddress());
+               }
+
+               // We need to have a ret now
+               Preconditions.checkArgument(ret != null, "Failed to find like Endpoint addresses");
+
+               return ret;
+       }
+
+       private AddressFamily findIpv4(final List<IpAddress> srcs, final List<IpAddress> dsts) {
+               for (final IpAddress sc : srcs) {
+                       if (sc.getIpv4Address() != null) {
+                               for (final IpAddress dc : dsts) {
+                                       if (dc.getIpv4Address() != null) {
+                                               return new Ipv4Builder().
+                                                               setSourceIpv4Address(sc.getIpv4Address()).
+                                                               setDestinationIpv4Address(dc.getIpv4Address()).build();
+                                       }
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       private AddressFamily findIpv6(final List<IpAddress> srcs, final List<IpAddress> dsts) {
+               for (final IpAddress sc : srcs) {
+                       if (sc.getIpv6Address() != null) {
+                               for (final IpAddress dc : dsts) {
+                                       if (dc.getIpv6Address() != null) {
+                                               return new Ipv6Builder().
+                                                               setSourceIpv6Address(sc.getIpv6Address()).
+                                                               setDestinationIpv6Address(dc.getIpv6Address()).build();
+                                       }
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       private NodeId supportingNode(final DataModificationTransaction t, final Node node) {
+               for (SupportingNode n : node.getSupportingNode()) {
+                       final SupportingNode1 n1 = n.getAugmentation(SupportingNode1.class);
+                       if (n1 != null && n1.getPathComputationClient().isControlling()) {
+                               return n.getKey().getNodeRef();
+                       }
+               }
+
+               return null;
+       }
+
+       private Ero buildEro(final List<ExplicitHops> explicitHops) {
+               final EroBuilder b = new EroBuilder();
 
-               final AddLspInputBuilder ab = new AddLspInputBuilder();
-               ab.fieldsFrom(input);
+               if (!explicitHops.isEmpty()) {
+                       final List<Subobjects> subobjs = new ArrayList<>(explicitHops.size());
+                       for (ExplicitHops h : explicitHops) {
 
+                               final ExplicitHops1 h1 = h.getAugmentation(ExplicitHops1.class);
+                               if (h1 != null) {
+                                       final SubobjectsBuilder sb = new SubobjectsBuilder();
+                                       sb.fieldsFrom(h1);
+                                       sb.setLoose(h.isLoose());
+                                       subobjs.add(sb.build());
+                               } else {
+                                       LOG.debug("Ignoring unhandled explicit hop {}", h);
+                               }
+                       }
+                       b.setSubobjects(subobjs);
+               }
+               return b.build();
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepCreateP2pTunnelOutput>> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) {
                final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
                        protected ListenableFuture<OperationResult> executeImpl() {
-                               final ListenableFuture<RpcResult<AddLspOutput>> s =
-                                               (ListenableFuture<RpcResult<AddLspOutput>>) pcepTopology.addLsp(ab.build());
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
 
-                               return Futures.transform(s, new Function<RpcResult<AddLspOutput>, OperationResult>() {
-                                       @Override
-                                       public OperationResult apply(final RpcResult<AddLspOutput> input) {
-                                               return input.getResult();
-                                       }
-                               });
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+
+                               final TpReader dr = new TpReader(t, tii, input.getDestination());
+                               final TpReader sr = new TpReader(t, tii, input.getSource());
+
+                               final Node sn = Preconditions.checkNotNull(sr.getNode());
+                               final TerminationPoint sp = Preconditions.checkNotNull(sr.getTp());
+                               final TerminationPoint dp = Preconditions.checkNotNull(dr.getTp());
+
+                               final AddLspInputBuilder ab = new AddLspInputBuilder();
+                               ab.setNode(Preconditions.checkNotNull(supportingNode(t, sn)));
+                               ab.setName(Preconditions.checkNotNull(input.getSymbolicPathName()));
+
+                               // The link has to be non-existent
+                               final InstanceIdentifier<Link> lii = NodeChangedListener.linkIdentifier(tii, ab.getNode(), ab.getName());
+                               Preconditions.checkState(t.readOperationalData(lii) == null);
+
+                               final ArgumentsBuilder args = new ArgumentsBuilder();
+                               args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active);
+                               args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
+                               args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                               args.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(buildAddressFamily(sp, dp)).build());
+                               args.setEro(buildEro(input.getExplicitHops()));
+                               args.setLspa(new LspaBuilder(input).build());
+
+                               ab.setArguments(args.build());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<AddLspOutput>>) topologyService.addLsp(ab.build()),
+                                               new Function<RpcResult<AddLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<AddLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
                        }
                };
 
@@ -82,25 +269,54 @@ final class TunnelProgramming implements TopologyTunnelPcepProgrammingService {
                return Futures.immediateFuture(res);
        }
 
-       @Override
-       public ListenableFuture<RpcResult<PcepDestroyTunnelOutput>> pcepDestroyTunnel(final PcepDestroyTunnelInput input) {
-               Preconditions.checkNotNull(input.getLinkId());
+       // FIXME: topology programming utility class
+       private InstanceIdentifier<Topology> topologyIdentifier(final TopologyInstructionInput input) {
+               return InstanceIdentifier.builder().
+                               node(NetworkTopology.class).node(Topology.class, new TopologyKey(input.getTopologyId())).toInstance();
+       }
+
+       // FIXME: tunnel programming utility class
+       private InstanceIdentifier<Link> linkIdentifier(final InstanceIdentifier<Topology> topology, final BaseTunnelInput input) {
+               return InstanceIdentifier.builder(topology).
+                               node(Link.class, new LinkKey(Preconditions.checkNotNull(input.getLinkId()))).toInstance();
+       }
 
-               final RemoveLspInputBuilder ab = new RemoveLspInputBuilder();
-               ab.fieldsFrom(input);
+       private Node sourceNode(final DataModificationTransaction t, final InstanceIdentifier<Topology> topology, final Link link) {
+               final InstanceIdentifier<Node> nii = InstanceIdentifier.builder(topology).
+                               node(Node.class, new NodeKey(link.getSource().getSourceNode())).toInstance();
+               return (Node) t.readOperationalData(nii);
+       }
 
+       @Override
+       public ListenableFuture<RpcResult<PcepDestroyTunnelOutput>> pcepDestroyTunnel(final PcepDestroyTunnelInput input) {
                final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
                        protected ListenableFuture<OperationResult> executeImpl() {
-                               final ListenableFuture<RpcResult<RemoveLspOutput>> s =
-                                               (ListenableFuture<RpcResult<RemoveLspOutput>>) pcepTopology.removeLsp(ab.build());
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
+                               final InstanceIdentifier<Link> lii = linkIdentifier(tii, input);
 
-                               return Futures.transform(s, new Function<RpcResult<RemoveLspOutput>, OperationResult>() {
-                                       @Override
-                                       public OperationResult apply(final RpcResult<RemoveLspOutput> input) {
-                                               return input.getResult();
-                                       }
-                               });
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+                               // The link has to exist
+                               final Link link = (Link) t.readOperationalData(lii);
+                               Preconditions.checkState(link != null);
+
+                               // The source node has to exist
+                               final Node node = sourceNode(t, tii, link);
+                               Preconditions.checkState(node != null);
+
+                               final RemoveLspInputBuilder ab = new RemoveLspInputBuilder();
+                               ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName());
+                               ab.setNode(node.getSupportingNode().get(0).getKey().getNodeRef());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<RemoveLspOutput>>) topologyService.removeLsp(ab.build()),
+                                               new Function<RpcResult<RemoveLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<RemoveLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
                        }
                };
 
@@ -116,23 +332,45 @@ final class TunnelProgramming implements TopologyTunnelPcepProgrammingService {
 
        @Override
        public ListenableFuture<RpcResult<PcepUpdateTunnelOutput>> pcepUpdateTunnel(final PcepUpdateTunnelInput input) {
-               Preconditions.checkNotNull(input.getLinkId());
-
-               final UpdateLspInputBuilder ab = new UpdateLspInputBuilder();
-               ab.fieldsFrom(input);
-
                final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
                        protected ListenableFuture<OperationResult> executeImpl() {
-                               final ListenableFuture<RpcResult<UpdateLspOutput>> s =
-                                               (ListenableFuture<RpcResult<UpdateLspOutput>>) pcepTopology.updateLsp(ab.build());
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
+                               final InstanceIdentifier<Link> lii = linkIdentifier(tii, input);
 
-                               return Futures.transform(s, new Function<RpcResult<UpdateLspOutput>, OperationResult>() {
-                                       @Override
-                                       public OperationResult apply(final RpcResult<UpdateLspOutput> input) {
-                                               return input.getResult();
-                                       }
-                               });
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+                               // The link has to exist
+                               final Link link = (Link) t.readOperationalData(lii);
+                               Preconditions.checkState(link != null);
+
+                               // The source node has to exist
+                               final Node node = sourceNode(t, tii, link);
+                               Preconditions.checkState(node != null);
+
+                               final UpdateLspInputBuilder ab = new UpdateLspInputBuilder();
+                               ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName());
+                               ab.setNode(Preconditions.checkNotNull(supportingNode(t, node)));
+
+                               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder args =
+                                               new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder();
+
+                               args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active);
+                               args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
+                               args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                               args.setEro(buildEro(input.getExplicitHops()));
+                               args.setLspa(new LspaBuilder(input).build());
+
+                               ab.setArguments(args.build());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<UpdateLspOutput>>) topologyService.updateLsp(ab.build()),
+                                               new Function<RpcResult<UpdateLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<UpdateLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
                        }
                };
 
index fbbe2e991e8f92a7f67e23a2f2f66b0661e702ab..471e01d9c5afd1f7f7d34df290fcdaa2ac099a09 100644 (file)
@@ -41,11 +41,16 @@ module topology-tunnel-programming {
        }
 
        grouping create-tunnel-input {
-               uses base-tunnel-input;
+               uses tp:topology-instruction-input;
        }
 
        grouping create-tunnel-output {
                uses base-tunnel-output;
+
+               leaf link-id {
+                       type nt:link-id;
+                       mandatory true;
+               }
        }
 
        grouping destroy-tunnel-input {
@@ -56,29 +61,30 @@ module topology-tunnel-programming {
                uses base-tunnel-output;
        }
 
-       grouping p2p-tunnel-input {
-               uses base-tunnel-input;
-
-               leaf source-tp {
-                       type nt:tp-ref;
+       grouping tp-reference {
+               leaf node {
+                       type nt:node-ref;
                        mandatory true;
                }
-               leaf destination-tp {
+               leaf tp {
                        type nt:tp-ref;
                        mandatory true;
                }
        }
 
-       grouping p2p-tunnel-output {
-               uses base-tunnel-output;
-       }
-
        grouping create-p2p-tunnel-input {
-               uses p2p-tunnel-input;
+               uses create-tunnel-input;
+
+               container destination {
+                       uses tp-reference;
+               }
+               container source {
+                       uses tp-reference;
+               }
        }
 
        grouping create-p2p-tunnel-output {
-               uses p2p-tunnel-output;
+               uses create-tunnel-output;
        }
 }
 
index 556ac16e47b33873212676639f67f3ce4671339d..a6a61931e79612b6d928fa9dd4e77b4815b5b9a7 100644 (file)
@@ -47,6 +47,25 @@ module rsvp {
                }
        }
 
+       grouping tunnel-attributes {
+               leaf hold-priority {
+                       type uint8;
+                       mandatory true;
+               }
+
+               leaf setup-priority {
+                       type uint8;
+                       mandatory true;
+               }
+
+               leaf local-protection-desired {
+                       type boolean;
+                       default false;
+               }
+
+               uses attribute-filters;
+       }
+
        typedef lsp-id {
                type uint32;
                reference "https://tools.ietf.org/html/rfc3209#section-4.6.2.1";