BUG-48: next phase of implementation 44/2344/2
authorRobert Varga <rovarga@cisco.com>
Wed, 30 Oct 2013 09:58:40 +0000 (10:58 +0100)
committerRobert Varga <rovarga@cisco.com>
Mon, 4 Nov 2013 07:02:16 +0000 (08:02 +0100)
Trim down tunnel programming instructions
Introduce PCEP APIs
Introduce PCEP provider
Add tunnel SPI helper
Remove dependency on Inventory

Change-Id: I459f70780b90a80371b91f49802015ea2c252458
Signed-off-by: Robert Varga <rovarga@cisco.com>
38 files changed:
pcep/api/src/main/yang/pcep-types.yang
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/Util.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/PCEPEndPointsObjectParser.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPObjectParserTest.java
pcep/pom.xml
pcep/topology-api/.project [moved from topology/pcep-api/.project with 100% similarity]
pcep/topology-api/pom.xml [moved from topology/pcep-api/pom.xml with 87% similarity]
pcep/topology-api/src/main/yang/network-topology-pcep.yang [new file with mode: 0644]
pcep/topology-provider/.project [moved from topology/provider-pcep/.project with 100% similarity]
pcep/topology-provider/pom.xml [moved from topology/tunnel-provider-pcep/pom.xml with 72% similarity]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java [moved from topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/BundleActivator.java with 94% similarity]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java [moved from topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/TopologyExporter.java with 75% similarity]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java [new file with mode: 0644]
pcep/tunnel-api/.project [moved from topology/tunnel-pcep-api/.project with 93% similarity]
pcep/tunnel-api/pom.xml [new file with mode: 0644]
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang [new file with mode: 0644]
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang [moved from topology/tunnel-pcep-api/src/main/yang/topology-tunnel-pcep.yang with 100% similarity]
pcep/tunnel-provider/.project [moved from topology/tunnel-provider-pcep/.project with 100% similarity]
pcep/tunnel-provider/pom.xml [moved from topology/provider-pcep/pom.xml with 82% similarity]
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java [moved from topology/tunnel-provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/tunnel/provider/pcep/BundleActivator.java with 93% similarity]
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java [moved from topology/tunnel-provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/tunnel/provider/pcep/NodeChangedListener.java with 93% similarity]
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java [new file with mode: 0644]
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelTopologyExporter.java [moved from topology/tunnel-provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/tunnel/provider/pcep/TunnelTopologyExporter.java with 95% similarity]
programming/api/src/main/yang/programming.yang
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/Instruction.java
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/ProgrammingServiceImpl.java
programming/pom.xml
programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionExecutor.java
programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionScheduler.java [moved from programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionExecutorRegistry.java with 56% similarity]
programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/SuccessfulRpcResult.java [moved from programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/SuccessfulRpcResult.java with 81% similarity]
programming/topology-api/pom.xml [moved from topology/tunnel-pcep-api/pom.xml with 91% similarity]
programming/topology-api/src/main/yang/network-topology-programming.yang [new file with mode: 0644]
programming/tunnel-api/pom.xml
programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang
topology/pcep-api/src/main/yang/inventory-pcep.yang [deleted file]
topology/pcep-api/src/main/yang/network-topology-pcep.yang [deleted file]
topology/pom.xml
topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/ServerSessionManager.java [deleted file]

index 0dfaa6fe4fa36e90a9e89bda939f64e885bd3299..2c006a97b00dfd8dbb069406e64623b0f9bc35aa 100644 (file)
@@ -489,13 +489,10 @@ module pcep-types {
                }
        }
 
-       grouping endpoints-object {
-               description "END-POINTS Object";
-               reference "https://tools.ietf.org/html/rfc5440#section-7.6";
-
-               uses object;
-
+       grouping endpoints {
                choice address-family {
+                       mandatory true;
+
                        case ipv4 {
                                leaf source-ipv4-address {
                                        type inet:ipv4-address;
@@ -521,6 +518,14 @@ module pcep-types {
                }
        }
 
+       grouping endpoints-object {
+               description "END-POINTS Object";
+               reference "https://tools.ietf.org/html/rfc5440#section-7.6";
+
+               uses object;
+               uses endpoints;
+       }
+
        grouping bandwidth-object {
                description "BANDWIDTH Object";
                reference "https://tools.ietf.org/html/rfc5440#section-7.7";
index 546006f3063b145ca1c58d61de7f8160c9e6c941..5eb4fd0a1cc65ff86acc72e5d7326e7e88cba0fe 100644 (file)
@@ -21,8 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OpenObject;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv4;
+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.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.ErrorType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.Errors;
index d2808e2838c23bbbaf101a648a4d1ccbce775096..ddc0e632fef7a72509317565f138ebeff45d6e4a 100644 (file)
@@ -18,11 +18,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.ObjectHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv6;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv6Builder;
+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.Ipv4;
+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.Ipv6;
+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.pcinitiate.message.pcinitiate.message.requests.EndpointsBuilder;
 
 /**
index 6a24ec4de8bc0b05a3475c85dbb36dc1f6bfbf30..3dab168f8a28dafb8b5fe8802136771a9a219090 100644 (file)
@@ -60,8 +60,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.RequestId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.SrpIdNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.close.message.c.close.message.CCloseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.address.family.Ipv6Builder;
+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.exclude.route.object.Subobjects;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.exclude.route.object.SubobjectsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.ClassTypeBuilder;
index 8fd3c665bac8cf899c81cb67b8f058c01970f90e..f58cee1d714e30356beec68328313bfbcafd2934 100644 (file)
@@ -21,5 +21,9 @@
                <module>impl</module>
                <module>spi</module>
         <module>testtool</module>
+        <module>topology-api</module>
+        <module>topology-provider</module>
+        <module>tunnel-api</module>
+        <module>tunnel-provider</module>
     </modules>
 </project>
similarity index 87%
rename from topology/pcep-api/pom.xml
rename to pcep/topology-api/pom.xml
index 9eceb856abf825d197e6698ca5cb133bd5160bf0..c1c3d986bf913085e13c9157b9d09f1356a06aeb 100644 (file)
@@ -5,13 +5,13 @@
 
        <parent>
                <groupId>org.opendaylight.bgpcep</groupId>
-               <artifactId>topology-parent</artifactId>
+               <artifactId>pcep-parent</artifactId>
                <version>0.3.0-SNAPSHOT</version>
        </parent>
 
        <modelVersion>4.0.0</modelVersion>
-       <artifactId>topology-pcep-api</artifactId>
-       <description>Topology PCEP API</description>
+       <artifactId>pcep-topology-api</artifactId>
+       <description>PCEP Topology API</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
        <prerequisites>
                        <artifactId>topology-api</artifactId>
             <version>${project.version}</version>
                </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>programming-topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-binding</artifactId>
             <artifactId>yang-common</artifactId>
             <version>${yangtools.version}</version>
         </dependency>
-
-        <dependency>
-            <groupId>org.opendaylight.controller.model</groupId>
-            <artifactId>model-inventory</artifactId>
-            <version>1.0-SNAPSHOT</version>
-        </dependency>
        </dependencies>
 
        <build>
@@ -92,8 +91,7 @@
                    <instructions>
                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
                        <Export-Package>
-                           org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024,
-                           org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024,
+                           org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.*,
                        </Export-Package>
                    </instructions>
                </configuration>
        <distributionManagement>
                <site>
                        <id>${project.artifactId}</id>
-                       <name>TOPOLOGY-PCEP-API Module site</name>
+                       <name>PCEP-TOPOLOGY-API Module site</name>
                        <url>${basedir}/target/site/${project.artifactId}</url>
                </site>
        </distributionManagement>
diff --git a/pcep/topology-api/src/main/yang/network-topology-pcep.yang b/pcep/topology-api/src/main/yang/network-topology-pcep.yang
new file mode 100644 (file)
index 0000000..2893f7a
--- /dev/null
@@ -0,0 +1,159 @@
+module network-topology-pcep {
+       // vi: set et smarttab sw=4 tabstop=4:
+       yang-version 1;
+       namespace "urn:opendaylight:params:xml:ns:yang:topology:pcep";
+       prefix "pn";
+
+       import network-topology { prefix nt; revision-date 2013-10-21; }
+       import network-topology-programming { prefix ntp; revision-date 2013-11-02; }
+       import pcep-types { prefix pcep; revision-date 2013-10-05; }
+
+       organization "Cisco Systems, Inc.";
+       contact "Robert Varga <rovarga@cisco.com>";
+
+       description
+               "This module contains the PCEP extensions to base topology model. It
+        exposes the LSPs for which a particular node is the head end.
+
+               Copyright (c)2013 Cisco Systems, Inc. All rights reserved.";
+
+       revision "2013-10-24" {
+               description
+                       "Initial revision.";
+               reference "";
+       }
+
+       typedef pcc-sync-state {
+               type enumeration {
+                       enum initial-resync {
+                               description
+                                       "Initial state resynchronization is being performed.";
+                       }
+                       enum synchronized {
+                               description
+                                       "State synchronization has been achieved.";
+                       }
+               }
+       }
+
+       grouping topology-pcep-type {
+               container topology-pcep {
+                       presence "indicates a PCEP-aware topology";
+               }
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:topology-types" {
+               uses topology-pcep-type;
+       }
+
+       grouping pcep-client-attributes {
+        description "Data present in a node which is a PCEP client (PCC).";
+
+               container path-computation-client {
+                       description
+                "PCC-related run-time information. This container is only
+                present when the node is connected through PCEP in a PCC
+                role.";
+            config false;
+
+                       container stateful-tlv {
+                               uses pcep:stateful-capability-tlv;
+                       }
+
+                       leaf state-sync {
+                               when "../stateful-tlv";
+                               type pcc-sync-state;
+                       }
+
+            list reported-lsps {
+                leaf name {
+                    type pcep:symbolic-path-name;
+                }
+                key name;
+
+                // FIXME: hide protocol-specific?
+                uses pcep:lsp-object;
+            }
+
+            list requested-lsps {
+                leaf name {
+                    type pcep:symbolic-path-name;
+                }
+                key name;
+
+                // FIXME: hide protocol-specific?
+                uses pcep:lsp-object;
+            }
+        }
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:node" {
+        when "../../nt:topology-types/topology-pcep";
+
+               uses pcep-client-attributes;
+       }
+
+    rpc add-lsp {
+        input {
+            uses ntp:topology-instruction-input;
+
+            leaf node {
+                type nt:node-ref;
+                mandatory true;
+            }
+
+            leaf name {
+                type pcep:symbolic-path-name;
+                mandatory true;
+            }
+
+            // FIXME: hide protocol-specific?
+            uses pcep:lsp-object;
+        }
+        output {
+            uses ntp:topology-instruction-output;
+        }
+    }
+
+    rpc remove-lsp {
+        input {
+            uses ntp:topology-instruction-input;
+
+            leaf node {
+                type nt:node-ref;
+                mandatory true;
+            }
+
+            leaf name {
+                type pcep:symbolic-path-name;
+                mandatory true;
+            }
+        }
+        output {
+            uses ntp:topology-instruction-output;
+        }
+    }
+
+    rpc update-lsp {
+        input {
+            uses ntp:topology-instruction-input;
+
+            leaf node {
+                type nt:node-ref;
+                mandatory true;
+            }
+
+            leaf name {
+                type pcep:symbolic-path-name;
+                mandatory true;
+            }
+
+            // FIXME: hide protocol-specific?
+            uses pcep:lsp-object;
+        }
+        output {
+            uses ntp:topology-instruction-output;
+        }
+    }
+}
+
similarity index 72%
rename from topology/tunnel-provider-pcep/pom.xml
rename to pcep/topology-provider/pom.xml
index 93b069645e513de452e398fa07d9a1f3f48faf58..3dc215b61bd92dd21f1265d61a7ba37d2e72d83d 100644 (file)
@@ -5,12 +5,12 @@
 
        <parent>
                <groupId>org.opendaylight.bgpcep</groupId>
-               <artifactId>topology-parent</artifactId>
+               <artifactId>pcep-parent</artifactId>
                <version>0.3.0-SNAPSHOT</version>
        </parent>
 
        <modelVersion>4.0.0</modelVersion>
-       <artifactId>topology-tunnel-provider-pcep</artifactId>
+       <artifactId>pcep-topology-provider</artifactId>
        <description>PCEP Topology Provider</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
        </prerequisites>
 
        <dependencies>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>topology-api</artifactId>
                </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>topology-pcep-api</artifactId>
+                       <artifactId>programming-api</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>topology-tunnel-api</artifactId>
+                       <artifactId>programming-spi</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>topology-tunnel-pcep-api</artifactId>
+                       <artifactId>pcep-topology-api</artifactId>
             <version>${project.version}</version>
                </dependency>
         <dependency>
             <version>${project.version}</version>
                        <scope>test</scope>
         </dependency>
+
+        <!-- FIXME: integrate with config to get rid of this -->
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-impl</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-spi</artifactId>
+            <version>${project.version}</version>
+               </dependency>
        </dependencies>
 
        <build>
@@ -68,9 +85,9 @@
                    <instructions>
                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
                        <Private-Package>
-                           org.opendaylight.bgpcep.topology.tunnel.provider.pcep
+                           org.opendaylight.bgpcep.pcep.topology.provider
                        </Private-Package>
-                       <Bundle-Activator>org.opendaylight.bgpcep.topology.tunnel.provider.pcep.BundleActivator</Bundle-Activator>
+                       <Bundle-Activator>org.opendaylight.bgpcep.pcep.topology.provider.BundleActivator</Bundle-Activator>
                    </instructions>
                </configuration>
            </plugin>
@@ -80,7 +97,7 @@
        <distributionManagement>
                <site>
                        <id>${project.artifactId}</id>
-                       <name>TOPOLOGY-PROVIDER-PCEP Module site</name>
+                       <name>PCEP-TOPOLOGY-PROVIDER Module site</name>
                        <url>${basedir}/target/site/${project.artifactId}</url>
                </site>
        </distributionManagement>
similarity index 94%
rename from topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/BundleActivator.java
rename to pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java
index 93e1e95d22e6fb8b271c2df5723942ba62caad21..9835f6cd86d0cda5f0cfbdbb58c20ff8229c1cc9 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.bgpcep.topology.provider.pcep;
+package org.opendaylight.bgpcep.pcep.topology.provider;
 
 import io.netty.channel.ChannelFuture;
 import io.netty.util.HashedWheelTimer;
@@ -45,7 +45,7 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                                new DefaultPCEPSessionNegotiatorFactory(new HashedWheelTimer(), prefs, 5));
                final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder().node(Topology.class).toInstance();
 
-               final TopologyExporter exp = new TopologyExporter(dispatcher, dps, topology);
+               final PCEPTopologyProvider exp = new PCEPTopologyProvider(dispatcher, null, dps, topology);
                final ChannelFuture s = exp.startServer(address);
                try {
                        s.get();
similarity index 75%
rename from topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/TopologyExporter.java
rename to pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
index d03c1262d3c772af224f242b4cd24bbbf40c03d2..527ce41cf5b76d783c7d8dd250ac297cd5b46743 100644 (file)
@@ -5,35 +5,37 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.bgpcep.topology.provider.pcep;
+package org.opendaylight.bgpcep.pcep.topology.provider;
 
 import io.netty.channel.ChannelFuture;
 
 import java.net.InetSocketAddress;
 
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.protocol.pcep.PCEPDispatcher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 import com.google.common.base.Preconditions;
 
-public final class TopologyExporter {
-       private static final InstanceIdentifier<Nodes> inventory = new InstanceIdentifier<Nodes>(Nodes.class);
+public final class PCEPTopologyProvider {
        private final PCEPDispatcher dispatcher;
        private final DataProviderService dataProvider;
        private final InstanceIdentifier<Topology> topology;
+       private final InstructionScheduler scheduler;
 
-       public TopologyExporter(final PCEPDispatcher dispatcher,
+       public PCEPTopologyProvider(final PCEPDispatcher dispatcher,
+                       final InstructionScheduler scheduler,
                        final DataProviderService dataService,
                        final InstanceIdentifier<Topology> topology) {
                this.dispatcher = Preconditions.checkNotNull(dispatcher);
                this.dataProvider = Preconditions.checkNotNull(dataService);
                this.topology = Preconditions.checkNotNull(topology);
+               this.scheduler = Preconditions.checkNotNull(scheduler);
        }
 
        public ChannelFuture startServer(final InetSocketAddress address) {
-               return dispatcher.createServer(address, new ServerSessionManager(dataProvider, inventory, topology));
+               return dispatcher.createServer(address, new ServerSessionManager(scheduler, dataProvider, topology));
        }
 }
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
new file mode 100644 (file)
index 0000000..f780d05
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.pcep.topology.provider;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
+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.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.protocol.framework.SessionListenerFactory;
+import org.opendaylight.protocol.pcep.PCEPSession;
+import org.opendaylight.protocol.pcep.PCEPSessionListener;
+import org.opendaylight.protocol.pcep.PCEPTerminationReason;
+import org.opendaylight.protocol.pcep.TerminationReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcrptMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.reports.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.stateful.capability.tlv.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.symbolic.path.name.tlv.SymbolicPathName;
+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.AddLspInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.PccSyncState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspInput;
+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.RemoveLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInput;
+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.UpdateLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClientBuilder;
+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.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLspsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.StatefulTlvBuilder;
+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.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+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.Preconditions;
+
+/**
+ *
+ */
+final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener>, NetworkTopologyPcepService {
+       private static String createNodeId(final InetAddress addr) {
+               return "pcc://" + addr.getHostAddress();
+       }
+
+       private final class SessionListener implements PCEPSessionListener {
+               private final Map<PlspId, SymbolicPathName> lsps = new HashMap<>();
+               private PathComputationClientBuilder pccBuilder;
+               private boolean synced = false;
+
+               private boolean ownsTopology = false;
+               private InstanceIdentifier<Node> topologyNodeId;
+               private InstanceIdentifier<Node1> topologyAugmentId;
+               private Node1Builder topologyAugmentBuilder;
+
+               final Node topologyNode(final DataModificationTransaction trans, final InetAddress address) {
+                       final String pccId = createNodeId(address);
+
+                       // FIXME: after 0.6 yangtools, this cast should not be needed
+                       final Topology topo = (Topology)trans.readOperationalData(topology);
+
+                       for (final Node n : topo.getNode()) {
+                               LOG.debug("Matching topology node {} to id {}", n, pccId);
+                               if (n.getNodeId().getValue().equals(pccId)) {
+                                       return n;
+                               }
+                       }
+
+                       /*
+                        * We failed to find a matching node. Let's create a dynamic one
+                        * and note that we are the owner (so we clean it up afterwards).
+                        */
+                       final NodeId id = new NodeId(pccId);
+                       final NodeKey nk = new NodeKey(id);
+                       final InstanceIdentifier<Node> nti = InstanceIdentifier.builder(topology).node(Node.class, nk).toInstance();
+
+                       final Node ret = new NodeBuilder().setKey(nk).setNodeId(id).build();
+
+                       trans.putRuntimeData(nti, ret);
+                       this.ownsTopology = true;
+                       this.topologyNodeId = nti;
+                       return ret;
+               }
+
+               @Override
+               public void onSessionUp(final PCEPSession session) {
+                       /*
+                        * The session went up. Look up the router in Inventory model,
+                        * create it if it is not there (marking that fact for later
+                        * deletion), and mark it as synchronizing. Also create it in
+                        * the topology model, with empty LSP list.
+                        */
+                       final InetAddress peerAddress = session.getRemoteAddress();
+                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
+
+                       final Node topoNode = topologyNode(trans, peerAddress);
+                       LOG.debug("Peer {} resolved to topology node {}", peerAddress, topoNode);
+
+                       // Our augmentation in the topology node
+                       pccBuilder = new PathComputationClientBuilder();
+
+                       final Tlvs tlvs = session.getRemoteTlvs();
+                       final Stateful stateful = tlvs.getStateful();
+                       if (stateful != null) {
+                               // FIXME: rework once groupings can be used in builders
+                               this.pccBuilder.setStatefulTlv(new StatefulTlvBuilder().setStateful(stateful).build());
+                               this.pccBuilder.setStateSync(PccSyncState.InitialResync);
+                       }
+
+                       topologyAugmentBuilder = new Node1Builder().setPathComputationClient(pccBuilder.build());
+                       topologyAugmentId = InstanceIdentifier.builder(topologyNodeId).node(Node1.class).toInstance();
+                       trans.putRuntimeData(topologyAugmentId, topologyAugmentBuilder.build());
+
+                       // All set, commit the modifications
+                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
+
+                       /*
+                        * FIXME: once this Future is listenable, attach to it so we can
+                        *        do cleanup if the commit fails. For now we force a commit.
+                        */
+                       try {
+                               s.get();
+                       } catch (InterruptedException | ExecutionException e) {
+                               LOG.error("Failed to update internal state for session {}, terminating it", session, e);
+                               session.close(TerminationReason.Unknown);
+                       }
+
+                       LOG.info("Session with {} attached to topology node {}", session.getRemoteAddress(), topoNode.getNodeId());
+               }
+
+               private void tearDown(final PCEPSession session) {
+                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
+
+                       // The session went down. Undo all the Topology changes we have done.
+                       trans.removeRuntimeData(topologyAugmentId);
+                       if (ownsTopology) {
+                               trans.removeRuntimeData(topologyNodeId);
+                       }
+
+                       /*
+                        * FIXME: once this Future is listenable, attach to it so we can
+                        *        do cleanup if the commit fails. For now we force a commit.
+                        */
+                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
+                       try {
+                               s.get();
+                       } catch (InterruptedException | ExecutionException e) {
+                               LOG.error("Failed to cleanup internal state for session {}", session, e);
+                       }
+               }
+
+               @Override
+               public void onSessionDown(final PCEPSession session, final Exception e) {
+                       LOG.warn("Session {} went down unexpectedly", e);
+                       tearDown(session);
+               }
+
+               @Override
+               public void onSessionTerminated(final PCEPSession session, final PCEPTerminationReason reason) {
+                       LOG.info("Session {} terminated by peer with reason {}", session, reason);
+                       tearDown(session);
+               }
+
+               private InstanceIdentifier<ReportedLsps> lspIdentifier(final SymbolicPathName name) {
+                       return InstanceIdentifier.builder(topologyAugmentId).
+                                       node(ReportedLsps.class, new ReportedLspsKey(name.getPathName())).toInstance();
+               }
+
+               @Override
+               public void onMessage(final PCEPSession session, final Message message) {
+                       if (!(message instanceof PcrptMessage)) {
+                               LOG.info("Unhandled message {} on session {}", message, session);
+                               session.sendMessage(unhandledMessageError);
+                       }
+
+                       final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
+
+                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
+
+                       for (final Reports r : rpt.getReports()) {
+                               final Lsp lsp = r.getLsp();
+
+                               if (lsp.isSync() && !this.synced) {
+                                       // Update synchronization flag
+                                       synced = true;
+                                       topologyAugmentBuilder.setPathComputationClient(pccBuilder.setStateSync(PccSyncState.Synchronized).build());
+                                       trans.putRuntimeData(topologyAugmentId, topologyAugmentBuilder.build());
+                                       LOG.debug("Session {} achieved synchronized state", session);
+                               }
+
+                               final PlspId id = lsp.getPlspId();
+                               if (lsp.isRemove()) {
+                                       final SymbolicPathName name = this.lsps.remove(id);
+                                       if (name != null) {
+                                               trans.removeRuntimeData(lspIdentifier(name));
+                                       }
+
+                                       LOG.debug("LSP {} removed", lsp);
+                               } else {
+                                       if (!this.lsps.containsKey(id)) {
+                                               LOG.debug("PLSPID {} not known yet, looking for a symbolic name", id);
+
+                                               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.object.Tlvs tlvs = r.getLsp().getTlvs();
+                                               final SymbolicPathName name = tlvs.getSymbolicPathName();
+                                               if (name == null) {
+                                                       LOG.error("PLSPID {} seen for the first time, not reporting the LSP");
+                                                       // TODO: what should we do here?
+                                                       continue;
+                                               }
+                                       }
+
+                                       final SymbolicPathName name = this.lsps.get(id);
+                                       trans.putRuntimeData(lspIdentifier(name), lsp);
+
+                                       LOG.debug("LSP {} updated");
+                               }
+                       }
+
+                       /*
+                        * FIXME: once this Future is listenable, attach to it so we can
+                        *        do cleanup if the commit fails. For now we force a commit.
+                        */
+                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
+                       try {
+                               s.get();
+                       } catch (InterruptedException | ExecutionException e) {
+                               LOG.error("Failed to update internal state for session {}, closing it", session, e);
+                               session.close(TerminationReason.Unknown);
+                       }
+               }
+       }
+
+       private static final Logger LOG = LoggerFactory.getLogger(ServerSessionManager.class);
+       private static final Pcerr unhandledMessageError = new PcerrBuilder().setPcerrMessage(
+                       new PcerrMessageBuilder().setErrorType(null).build()).build();
+       private static final EventExecutor exec = GlobalEventExecutor.INSTANCE;
+       private final InstanceIdentifier<Topology> topology;
+       private final DataProviderService dataProvider;
+       private final InstructionScheduler scheduler;
+
+       public ServerSessionManager(final InstructionScheduler scheduler,
+                       final DataProviderService dataProvider, final InstanceIdentifier<Topology> topology) {
+               this.dataProvider = Preconditions.checkNotNull(dataProvider);
+               this.topology = Preconditions.checkNotNull(topology);
+               this.scheduler = Preconditions.checkNotNull(scheduler);
+       }
+
+       @Override
+       public PCEPSessionListener getSessionListener() {
+               return new SessionListener();
+       }
+
+       private synchronized io.netty.util.concurrent.Future<ExecutionResult<?>> realAddLsp(final AddLspInput input) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       private synchronized io.netty.util.concurrent.Future<ExecutionResult<?>> realRemoveLsp(final RemoveLspInput input) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       private synchronized io.netty.util.concurrent.Future<ExecutionResult<?>> realUpdateLsp(final UpdateLspInput input) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Future<RpcResult<AddLspOutput>> addLsp(final AddLspInput input) {
+               final InstructionExecutor e = new InstructionExecutor() {
+                       @Override
+                       public io.netty.util.concurrent.Future<ExecutionResult<?>> execute() {
+                               return realAddLsp(input);
+                       }
+               };
+
+               final Failure f = scheduler.submitInstruction(input, e);
+               final AddLspOutputBuilder b = new AddLspOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<AddLspOutput> res = SuccessfulRpcResult.create(b.build());
+               return exec.newSucceededFuture(res);
+       }
+
+       @Override
+       public Future<RpcResult<RemoveLspOutput>> removeLsp(final RemoveLspInput input) {
+               final InstructionExecutor e = new InstructionExecutor() {
+                       @Override
+                       public io.netty.util.concurrent.Future<ExecutionResult<?>> execute() {
+                               return realRemoveLsp(input);
+                       }
+               };
+
+               final Failure f = scheduler.submitInstruction(input, e);
+               final RemoveLspOutputBuilder b = new RemoveLspOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<RemoveLspOutput> res = SuccessfulRpcResult.create(b.build());
+               return exec.newSucceededFuture(res);
+       }
+
+       @Override
+       public Future<RpcResult<UpdateLspOutput>> updateLsp(final UpdateLspInput input) {
+               final InstructionExecutor e = new InstructionExecutor() {
+                       @Override
+                       public io.netty.util.concurrent.Future<ExecutionResult<?>> execute() {
+                               return realUpdateLsp(input);
+                       }
+               };
+
+               final Failure f = scheduler.submitInstruction(input, e);
+               final UpdateLspOutputBuilder b = new UpdateLspOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<UpdateLspOutput> res = SuccessfulRpcResult.create(b.build());
+               return exec.newSucceededFuture(res);
+       }
+}
similarity index 93%
rename from topology/tunnel-pcep-api/.project
rename to pcep/tunnel-api/.project
index 990d616992389a39170dcc8d363da6898a99a3ef..01b39d16fc3381cd973d3b671ab45563f97fa501 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-       <name>topology-tunnel-pcep</name>
+       <name>programming-tunnel-pcep-api</name>
        <comment></comment>
        <projects>
        </projects>
diff --git a/pcep/tunnel-api/pom.xml b/pcep/tunnel-api/pom.xml
new file mode 100644 (file)
index 0000000..69e72e7
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+       <parent>
+               <groupId>org.opendaylight.bgpcep</groupId>
+               <artifactId>pcep-parent</artifactId>
+               <version>0.3.0-SNAPSHOT</version>
+       </parent>
+
+       <modelVersion>4.0.0</modelVersion>
+       <artifactId>pcep-tunnel-api</artifactId>
+       <description>Tunnel API for PCEP</description>
+       <packaging>bundle</packaging>
+       <name>${project.artifactId}</name>
+       <prerequisites>
+               <maven>3.0.4</maven>
+       </prerequisites>
+
+       <dependencies>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>programming-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>programming-tunnel-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>topology-tunnel-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-binding</artifactId>
+            <version>${yang.binding.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+            <version>${yangtools.version}</version>
+        </dependency>
+       </dependencies>
+
+       <build>
+        <plugins>
+           <plugin>
+               <groupId>org.opendaylight.yangtools</groupId>
+               <artifactId>yang-maven-plugin</artifactId>
+               <version>${yangtools.version}</version>
+               <executions>
+                   <execution>
+                       <goals>
+                           <goal>generate-sources</goal>
+                       </goals>
+                       <configuration>
+                           <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+                           <codeGenerators>
+                               <generator>
+                                   <codeGeneratorClass>
+                                       org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                   </codeGeneratorClass>
+                                   <outputBaseDir>
+                                       target/generated-sources/sal
+                                   </outputBaseDir>
+                               </generator>
+                           </codeGenerators>
+                           <inspectDependencies>true</inspectDependencies>
+                       </configuration>
+                   </execution>
+               </executions>
+               <dependencies>
+                   <dependency>
+                       <groupId>org.opendaylight.yangtools</groupId>
+                       <artifactId>maven-sal-api-gen-plugin</artifactId>
+                       <version>${yang.binding.version}</version>
+                       <type>jar</type>
+                   </dependency>
+               </dependencies>
+           </plugin>
+           <plugin>
+               <groupId>org.apache.felix</groupId>
+               <artifactId>maven-bundle-plugin</artifactId>
+               <version>${maven.bundle.version}</version>
+               <extensions>true</extensions>
+               <configuration>
+                   <instructions>
+                       <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                       <Export-Package>
+                           org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.*,
+                       </Export-Package>
+                   </instructions>
+               </configuration>
+           </plugin>
+               </plugins>
+       </build>
+
+       <distributionManagement>
+               <site>
+                       <id>${project.artifactId}</id>
+                       <name>PROGRAMMING-TUNNEL-PCEP-API Module site</name>
+                       <url>${basedir}/target/site/${project.artifactId}</url>
+               </site>
+       </distributionManagement>
+
+</project>
diff --git a/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang b/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang
new file mode 100644 (file)
index 0000000..9918060
--- /dev/null
@@ -0,0 +1,94 @@
+module topology-tunnel-pcep-programming {
+        yang-version 1;
+        namespace "urn:opendaylight:params:xml:ns:yang:topology:tunnel:pcep:programming";
+        prefix "ttpp";
+
+        import network-topology { prefix nt; revision-date 2013-10-21; }
+       import pcep-types { prefix pcep; revision-date 2013-10-05; }
+        import programming { prefix pgm; revision-date 2013-09-30; }
+        import topology-tunnel { prefix tt; revision-date 2013-08-19; }
+        import topology-tunnel-programming { prefix ttp; revision-date 2013-09-30; }
+
+        organization "Cisco Systems, Inc.";
+        contact "Robert Varga <rovarga@cisco.com>";
+
+        description
+                "This module contains the programming extensions for tunnel
+                topologies.
+
+                Copyright (c)2013 Cisco Systems, Inc. All rights reserved.
+
+                This program and the accompanying materials are made available
+                under the terms of the Eclipse Public License v1.0 which
+                accompanies this distribution, and is available at
+                http://www.eclipse.org/legal/epl-v10.html";
+
+        revision "2013-10-30" {
+                description
+                        "Initial revision.";
+                reference "";
+        }
+
+       rpc pcep-create-tunnel {
+               input {
+                       uses ttp:create-tunnel-input;
+
+                       leaf symbolic-path-name {
+                               type pcep:symbolic-path-name;
+                               mandatory true;
+                       }
+
+                       container endpoints {
+                               uses pcep:endpoints;
+                       }
+
+                       leaf signaling-type {
+                               // FIXME: dedicated type in PCEP
+                               type uint8;
+                               default 0;
+                       }
+
+                       leaf administrative {
+                               type boolean;
+                               default true;
+                       }
+
+                       // FIXME: ERO
+                       // FIXME: attribute-list
+               }
+               output {
+                       uses ttp:create-tunnel-output;
+               }
+       }
+
+       rpc pcep-destroy-tunnel {
+               input {
+                       uses ttp:destroy-tunnel-input;
+               }
+               output {
+                       uses ttp:destroy-tunnel-output;
+               }
+       }
+
+       rpc pcep-update-tunnel {
+               input {
+                       container update-tunnel {
+                                leaf topology-id {
+                                        type nt:topology-id;
+                                        mandatory true;
+                                }
+                                leaf link-id {
+                                        type nt:link-id;
+                                        mandatory true;
+                                }
+
+                               // FIXME: all that PCUpd jazz
+                       }
+               }
+
+               output {
+                       uses pgm:submit-instruction-output;
+               }
+       }
+}
+
similarity index 82%
rename from topology/provider-pcep/pom.xml
rename to pcep/tunnel-provider/pom.xml
index 4c414c644f773a76c9e7cd43b64fd4f98af7c4ce..409ca13d618b69d7124358312e0a9ec32706a92a 100644 (file)
@@ -5,13 +5,13 @@
 
        <parent>
                <groupId>org.opendaylight.bgpcep</groupId>
-               <artifactId>topology-parent</artifactId>
+               <artifactId>pcep-parent</artifactId>
                <version>0.3.0-SNAPSHOT</version>
        </parent>
 
        <modelVersion>4.0.0</modelVersion>
-       <artifactId>topology-provider-pcep</artifactId>
-       <description>PCEP Topology Provider</description>
+       <artifactId>pcep-tunnel-provider</artifactId>
+       <description>PCEP Tunnel Topology Provider</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
        <prerequisites>
@@ -21,7 +21,7 @@
        <dependencies>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>pcep-api</artifactId>
+                       <artifactId>programming-spi</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
                </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>topology-pcep-api</artifactId>
+                       <artifactId>topology-tunnel-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-tunnel-api</artifactId>
             <version>${project.version}</version>
                </dependency>
         <dependency>
             <version>${project.version}</version>
                        <scope>test</scope>
         </dependency>
-
-        <!-- FIXME: integrate with config to get rid of this -->
-               <dependency>
-                       <groupId>${project.groupId}</groupId>
-                       <artifactId>pcep-impl</artifactId>
-            <version>${project.version}</version>
-               </dependency>
-               <dependency>
-                       <groupId>${project.groupId}</groupId>
-                       <artifactId>pcep-spi</artifactId>
-            <version>${project.version}</version>
-               </dependency>
        </dependencies>
 
        <build>
@@ -75,9 +73,9 @@
                    <instructions>
                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
                        <Private-Package>
-                           org.opendaylight.bgpcep.topology.provider.pcep
+                           org.opendaylight.bgpcep.pcep.tunnel.provider
                        </Private-Package>
-                       <Bundle-Activator>org.opendaylight.bgpcep.topology.provider.pcep.BundleActivator</Bundle-Activator>
+                       <Bundle-Activator>org.opendaylight.bgpcep.pcep.tunnel.provider.BundleActivator</Bundle-Activator>
                    </instructions>
                </configuration>
            </plugin>
@@ -87,7 +85,7 @@
        <distributionManagement>
                <site>
                        <id>${project.artifactId}</id>
-                       <name>TOPOLOGY-PROVIDER-PCEP Module site</name>
+                       <name>PCEP-TUNNEL-PROVIDER Module site</name>
                        <url>${basedir}/target/site/${project.artifactId}</url>
                </site>
        </distributionManagement>
similarity index 93%
rename from topology/tunnel-provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/tunnel/provider/pcep/BundleActivator.java
rename to pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java
index 2a4a6fdc36e6dcf0aca023eb8da769f4f7bc5fa0..361a641038cf4603013a0180df4d7281bd02c4e1 100644 (file)
@@ -1,4 +1,4 @@
-package org.opendaylight.bgpcep.topology.tunnel.provider.pcep;
+package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.bgpcep.topology.tunnel.provider.pcep;
+package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
 import java.util.Map.Entry;
 import java.util.concurrent.ExecutionException;
@@ -16,7 +16,7 @@ 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.topology.pcep.rev131024.pcep.client.attributes.pcc.Lsps;
+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.network.topology.Topology;
 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;
@@ -40,7 +40,7 @@ final class NodeChangedListener implements DataChangeListener {
        private void remove(final DataModificationTransaction trans, final InstanceIdentifier<?> id) {
                if (Node.class.equals(id.getTargetType())) {
                        // FIXME: implement this
-               } else if (Lsps.class.equals(id.getTargetType())) {
+               } else if (ReportedLsps.class.equals(id.getTargetType())) {
                        // FIXME: implement this
                } else {
                        LOG.debug("Ignoring changed instance {}", id);
diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java
new file mode 100644 (file)
index 0000000..d8928e1
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.pcep.tunnel.provider;
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.topology.pcep.type.TopologyPcep;
+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.TopologyId;
+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.TopologyTypes;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public final class PCEPTunnelInstructionExecutor {
+       private static final Logger LOG = LoggerFactory.getLogger(PCEPTunnelInstructionExecutor.class);
+       private final InstanceIdentifier<Topology> underlay;
+       private final InstanceIdentifier<Topology> target;
+       private final DataProviderService dps;
+
+       private PCEPTunnelInstructionExecutor(final DataProviderService dps, final InstanceIdentifier<Topology> underlay,
+                       final InstanceIdentifier<Topology> target, final TopologyId topologyId) {
+               this.dps = Preconditions.checkNotNull(dps);
+               this.underlay = Preconditions.checkNotNull(underlay);
+               this.target = Preconditions.checkNotNull(target);
+       }
+
+       public static PCEPTunnelInstructionExecutor create(final DataProviderService dps, final InstanceIdentifier<Topology> underlay,
+                       final TopologyId targetId) {
+               Preconditions.checkNotNull(dps);
+               Preconditions.checkNotNull(targetId);
+
+               // Topology pointer
+               final InstanceIdentifier<Topology> target = InstanceIdentifier.builder().node(NetworkTopology.class).
+                               node(Topology.class, new TopologyKey(targetId)).toInstance();
+
+               // Now check if there is a container identifying the topology as PCEP-aware
+               final InstanceIdentifier<TopologyPcep> i = InstanceIdentifier.builder(target).node(TopologyTypes.class).node(TopologyPcep.class).toInstance();
+               final DataObject ttt = dps.readOperationalData(i);
+               Preconditions.checkArgument(ttt != null, "Specified topology does not list topology-pcep as its type");
+
+               return new PCEPTunnelInstructionExecutor(dps, underlay, target, targetId);
+       }
+}
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.bgpcep.topology.tunnel.provider.pcep;
+package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
index 21fca87d074dda3515f26f35f52d123dfc7c6be9..f57f386dc464bb8e955cf2677140870ad9ef60d0 100644 (file)
@@ -231,55 +231,36 @@ module programming {
                base submit-failure;
        }
 
-       identity instruction-type {
-               description
-                       "Base intruction type. This identity should be
-                       extended for each individual instruction defined.";
-       }
-
-       rpc submit-instruction {
-               input {
-                       leaf id {
-                               type instruction-id;
-                               mandatory true;
-                       }
-
-                       leaf type {
-                               type identityref {
-                                       base instruction-type;
-                               }
-                               mandatory true;
-                       }
-
-                       leaf deadline {
-                               type nanotime;
-                               mandatory true;
-                       }
-
-                       leaf-list preconditions {
-                               type instruction-id;
-                       }
+       grouping submit-instruction-input {
+               leaf id {
+                       type instruction-id;
+                       mandatory true;
+               }
 
-                       choice arguments {
+               leaf deadline {
+                       type nanotime;
+                       mandatory true;
+               }
 
-                       }
+               leaf-list preconditions {
+                       type instruction-id;
                }
+       }
 
-               output {
-                       choice result {
-                               case failure {
-                                       container failure {
-                                               leaf type {
-                                                       type identityref {
-                                                               base submit-failure;
-                                                       }
-                                                       mandatory true;
+       grouping submit-instruction-output {
+               choice result {
+                       case failure {
+                               container failure {
+                                       leaf type {
+                                               type identityref {
+                                                       base submit-failure;
                                                }
+                                               mandatory true;
+                                       }
 
-                                               leaf-list failed-preconditions {
-                                                       when "../type = dead-on-arrival";
-                                                       type instruction-id;
-                                               }
+                                       leaf-list failed-preconditions {
+                                               when "../type = dead-on-arrival";
+                                               type instruction-id;
                                        }
                                }
                        }
index c72bd0a89150bb2bb8b8691335775e79760dfab7..00cca8c539f6b2d9081bce0920e992d86bd6c999 100644 (file)
@@ -8,36 +8,45 @@
 package org.opendaylight.bgpcep.programming.impl;
 
 import io.netty.util.Timeout;
+import io.netty.util.concurrent.Future;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
+import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.SubmitInstructionInput;
 
 import com.google.common.base.Preconditions;
 
 final class Instruction {
        private final List<Instruction> dependants = new ArrayList<>();
+       private final InstructionExecutor executor;
        private final List<Instruction> dependencies;
-       private final SubmitInstructionInput input;
+       private final InstructionId id;
        private volatile InstructionStatus status = InstructionStatus.Queued;
        private Timeout timeout;
 
-       Instruction(final SubmitInstructionInput input, final List<Instruction> dependencies, final Timeout timeout) {
-               this.input = Preconditions.checkNotNull(input);
+       Instruction(final InstructionId id, final InstructionExecutor executor, final List<Instruction> dependencies, final Timeout timeout) {
+               this.id = Preconditions.checkNotNull(id);
+               this.executor = Preconditions.checkNotNull(executor);
                this.dependencies = Preconditions.checkNotNull(dependencies);
                this.timeout = Preconditions.checkNotNull(timeout);
        }
 
-       SubmitInstructionInput getInput() {
-               return input;
+       InstructionId getId() {
+               return id;
        }
 
        InstructionStatus getStatus() {
                return status;
        }
 
+       Future<ExecutionResult<?>> execute() {
+               return executor.execute();
+       }
+
        void setStatus(final InstructionStatus status) {
                this.status = status;
        }
index 6d75bfc8b53180a5f3fecb049a3e6c673ee06940..bbcf9bb20d60bfc93c04faaeccc6ecfc2140b527 100644 (file)
@@ -16,10 +16,8 @@ import io.netty.util.concurrent.FutureListener;
 import java.math.BigInteger;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Deque;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -32,7 +30,8 @@ import javax.annotation.concurrent.GuardedBy;
 
 import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
 import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
-import org.opendaylight.bgpcep.programming.spi.InstructionExecutorRegistry;
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
+import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.CancelInstructionInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.CancelInstructionOutput;
@@ -42,11 +41,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programm
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionStatusChangedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.ProgrammingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.SubmitInstructionInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.SubmitInstructionOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.SubmitInstructionOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.UncancellableInstruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.UnknownInstruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.UnknownPreconditionId;
@@ -54,17 +50,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programm
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.status.changed.DetailsBuilder;
 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.programming.rev130930.submit.instruction.output.result.failure.FailureBuilder;
-import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
 
-final class ProgrammingServiceImpl implements InstructionExecutorRegistry, ProgrammingService {
+final class ProgrammingServiceImpl implements InstructionScheduler, ProgrammingService {
        private static final Logger LOG = LoggerFactory.getLogger(ProgrammingServiceImpl.class);
        private static final BigInteger MILLION = BigInteger.valueOf(1000000);
 
@@ -73,12 +66,6 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
        @GuardedBy("this")
        private final Deque<Instruction> readyQueue = new ArrayDeque<>();
 
-       @GuardedBy("this")
-       private final Deque<Instruction> deferredQueue = new ArrayDeque<>();
-
-       @GuardedBy("this")
-       private final Multimap<Class<? extends InstructionType>, InstructionExecutor> executors = ArrayListMultimap.create();
-
        private final NotificationProviderService notifs;
        private final ExecutorService executor;
        private final Timer timer;
@@ -86,7 +73,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
        private ExecutorService exec;
 
        ProgrammingServiceImpl(final NotificationProviderService notifs, final ExecutorService executor,
-                       final Timer timer, final InstructionExecutorRegistry registry) {
+                       final Timer timer, final InstructionScheduler registry) {
                this.notifs = Preconditions.checkNotNull(notifs);
                this.executor = Preconditions.checkNotNull(executor);
                this.timer = Preconditions.checkNotNull(timer);
@@ -102,63 +89,6 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                });
        }
 
-       @Override
-       public java.util.concurrent.Future<RpcResult<SubmitInstructionOutput>> submitInstruction(final SubmitInstructionInput input) {
-               return executor.submit(new Callable<RpcResult<SubmitInstructionOutput>>() {
-                       @Override
-                       public RpcResult<SubmitInstructionOutput> call() {
-                               return realSubmitInstruction(input);
-                       }
-               });
-       }
-
-       @Override
-       public synchronized Registration<InstructionExecutor> registerInstructionExecutor(final Class<? extends InstructionType> type, final InstructionExecutor executor) {
-               Preconditions.checkNotNull(type);
-               Preconditions.checkNotNull(executor);
-
-               executors.put(type, executor);
-
-               /*
-                * Walk the deferred instructions back to front, check if they have
-                * the same type as the executor we have just registered. If they do,
-                * we move them to the head of readyQueue. This approach should retain
-                * submission order of the instructions.
-                */
-               final Iterator<Instruction> it = deferredQueue.descendingIterator();
-               while (it.hasNext()) {
-                       final Instruction i = it.next();
-                       if (type.equals(i.getInput().getType())) {
-                               it.remove();
-                               readyQueue.addFirst(i);
-                       }
-               }
-
-               notify();
-
-               final Object lock = this;
-               return new Registration<InstructionExecutor>() {
-                       @Override
-                       public void close() throws Exception {
-                               synchronized (lock) {
-                                       executors.remove(type, executor);
-                               }
-                       }
-
-                       @Override
-                       public InstructionExecutor getInstance() {
-                               return executor;
-                       }
-               };
-       }
-
-       private static final RpcResult<SubmitInstructionOutput> failedSubmit(final Failure f) {
-               return SuccessfulRpcResult.create(
-                               new SubmitInstructionOutputBuilder().setResult(
-                                               new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.FailureBuilder()
-                                               .setFailure(f).build()).build());
-       }
-
        private synchronized RpcResult<CancelInstructionOutput> realCancelInstruction(final CancelInstructionInput input)  {
                final Instruction i = insns.get(input.getId());
                if (i == null) {
@@ -186,11 +116,12 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                return SuccessfulRpcResult.create(new CancelInstructionOutputBuilder().build());
        }
 
-       private synchronized RpcResult<SubmitInstructionOutput> realSubmitInstruction(final SubmitInstructionInput input) {
+       @Override
+       public Failure submitInstruction(final SubmitInstructionInput input, final InstructionExecutor executor) {
                final InstructionId id = input.getId();
                if (insns.get(id) != null) {
                        LOG.info("Instruction ID {} already present", id);
-                       return failedSubmit(new FailureBuilder().setType(DuplicateInstructionId.class).build());
+                       return new FailureBuilder().setType(DuplicateInstructionId.class).build();
                }
 
                // First things first: check the deadline
@@ -199,7 +130,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
 
                if (left.compareTo(BigInteger.ZERO) <= 0) {
                        LOG.debug("Instruction {} deadline has already passed by {}ns", id, left);
-                       return failedSubmit(new FailureBuilder().setType(DeadOnArrival.class).build());
+                       return new FailureBuilder().setType(DeadOnArrival.class).build();
                }
 
                // Resolve dependencies
@@ -208,7 +139,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                        final Instruction i = insns.get(pid);
                        if (i == null) {
                                LOG.info("Instruction {} depends on {}, which is not a known instruction", id, pid);
-                               return failedSubmit(new FailureBuilder().setType(UnknownPreconditionId.class).build());
+                               return new FailureBuilder().setType(UnknownPreconditionId.class).build();
                        }
 
                        dependencies.add(i);
@@ -221,7 +152,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                        case Cancelled:
                        case Failed:
                        case Unknown:
-                               unmet.add(d.getInput().getId());
+                               unmet.add(d.getId());
                                break;
                        case Executing:
                        case Queued:
@@ -236,7 +167,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                 *  and fail the operation.
                 */
                if (!unmet.isEmpty()) {
-                       return failedSubmit(new FailureBuilder().setType(DeadOnArrival.class).setFailedPreconditions(unmet).build());
+                       return new FailureBuilder().setType(DeadOnArrival.class).setFailedPreconditions(unmet).build();
                }
 
                /*
@@ -254,7 +185,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                }, left.longValue(), TimeUnit.NANOSECONDS);
 
                // Put it into the instruction list
-               final Instruction i = new Instruction(input, dependencies, t);
+               final Instruction i = new Instruction(input.getId(), executor, dependencies, t);
                insns.put(id, i);
 
                // Attach it into its dependencies
@@ -268,14 +199,14 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                 * This task should be ingress-weighed, so we reinsert it into the
                 * same execution service.
                 */
-               executor.submit(new Runnable() {
+               this.executor.submit(new Runnable() {
                        @Override
                        public void run() {
                                tryScheduleInstruction(i);
                        }
                });
 
-               return SuccessfulRpcResult.create(new SubmitInstructionOutputBuilder().build());
+               return null;
        }
 
        @GuardedBy("this")
@@ -283,11 +214,11 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                // Set the status
                v.setStatus(status);
 
-               LOG.debug("Instruction {} transitioned to status {}", v.getInput().getId(), status);
+               LOG.debug("Instruction {} transitioned to status {}", v.getId(), status);
 
                // Send out a notification
                notifs.publish(new InstructionStatusChangedBuilder().
-                               setId(v.getInput().getId()).setStatus(status).setDetails(details).build());
+                               setId(v.getId()).setStatus(status).setDetails(details).build());
        }
 
        @GuardedBy("this")
@@ -301,7 +232,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
 
        @GuardedBy("this")
        private void cancelDependants(final Instruction v) {
-               final Details details = new DetailsBuilder().setUnmetDependencies(ImmutableList.of(v.getInput().getId())).build();
+               final Details details = new DetailsBuilder().setUnmetDependencies(ImmutableList.of(v.getId())).build();
                for (final Instruction d : v.getDependants()) {
                        switch (d.getStatus()) {
                        case Cancelled:
@@ -320,7 +251,6 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
        }
 
        private synchronized void cancelInstruction(final Instruction i, final Details details) {
-               deferredQueue.remove(i);
                readyQueue.remove(i);
                cancelSingle(i, details);
                cancelDependants(i);
@@ -353,14 +283,14 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                        final List<InstructionId> ids = new ArrayList<>();
                        for (final Instruction d : i.getDependencies()) {
                                if (d.getStatus() != InstructionStatus.Successful) {
-                                       ids.add(d.getInput().getId());
+                                       ids.add(d.getId());
                                }
                        }
 
                        cancelInstruction(i, new DetailsBuilder().setUnmetDependencies(ids).build());
                        break;
                case Scheduled:
-                       LOG.debug("Instruction {} timed out while Scheduled, cancelling it", i.getInput().getId());
+                       LOG.debug("Instruction {} timed out while Scheduled, cancelling it", i.getId());
                        // FIXME: we should provide details why it timed out while scheduled
                        cancelInstruction(i, null);
                        break;
@@ -386,7 +316,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                        case Cancelled:
                        case Failed:
                        case Unknown:
-                               unmet.add(d.getInput().getId());
+                               unmet.add(d.getId());
                                break;
                        case Executing:
                        case Queued:
@@ -400,14 +330,14 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                }
 
                if (!unmet.isEmpty()) {
-                       LOG.debug("Instruction {} was Queued, while some dependencies were resolved unsuccessfully, cancelling it", i.getInput().getId());
+                       LOG.debug("Instruction {} was Queued, while some dependencies were resolved unsuccessfully, cancelling it", i.getId());
                        cancelSingle(i, new DetailsBuilder().setUnmetDependencies(unmet).build());
                        cancelDependants(i);
                        return;
                }
 
                if (ready) {
-                       LOG.debug("Instruction {} is ready for execution", i.getInput().getId());
+                       LOG.debug("Instruction {} is ready for execution", i.getId());
                        transitionInstruction(i, InstructionStatus.Scheduled, null);
 
                        readyQueue.add(i);
@@ -416,7 +346,7 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
        }
 
        private synchronized void executionFailed(final Instruction i, final Throwable cause) {
-               LOG.error("Instruction {} failed to execute", i.getInput().getId(), cause);
+               LOG.error("Instruction {} failed to execute", i.getId(), cause);
                transitionInstruction(i, InstructionStatus.Failed, null);
                cancelDependants(i);
        }
@@ -441,30 +371,9 @@ final class ProgrammingServiceImpl implements InstructionExecutorRegistry, Progr
                                final Instruction i = readyQueue.poll();
 
                                Preconditions.checkState(i.getStatus().equals(InstructionStatus.Scheduled));
-                               final SubmitInstructionInput input = i.getInput();
-
-                               /*
-                                *  Walk all the registered executors for a particular type and
-                                *  offer them the chance to execute the instruction. The first
-                                *  one to accept it wins.
-                                */
-                               Future<ExecutionResult<?>> f = null;
-                               final Collection<InstructionExecutor> el = executors.get(input.getType());
-
-                               for (final InstructionExecutor e : el) {
-                                       f = e.offerInstruction(input.getArguments());
-                                       if (f != null) {
-                                               break;
-                                       }
-                               }
-
-                               // We did not find an executor -- defer the instruction
-                               if (f == null) {
-                                       deferredQueue.add(i);
-                                       continue;
-                               }
 
                                transitionInstruction(i, InstructionStatus.Executing, null);
+                               final Future<ExecutionResult<?>> f = i.execute();
                                f.addListener(new FutureListener<ExecutionResult<?>>() {
                                        @Override
                                        public void operationComplete(final Future<ExecutionResult<?>> future) {
index 2358267230925cc017bef36c308f62f7feb40191..e3a4b3822336ecc8dea434f1750766a1cbb5154e 100644 (file)
@@ -20,6 +20,7 @@
         <module>api</module>
         <module>impl</module>
         <module>spi</module>
+        <module>topology-api</module>
                <module>tunnel-api</module>
     </modules>
 </project>
index bf86cac92e7ef5d509c238eca152bf3327894d60..9c27ca8af600cb410d9525a09a4da40f13dd596a 100644 (file)
@@ -9,8 +9,6 @@ package org.opendaylight.bgpcep.programming.spi;
 
 import io.netty.util.concurrent.Future;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.input.Arguments;
-
 public interface InstructionExecutor {
-       Future<ExecutionResult<?>> offerInstruction(Arguments arguments);
+       Future<ExecutionResult<?>> execute();
 }
similarity index 56%
rename from programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionExecutorRegistry.java
rename to programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionScheduler.java
index 0eea0cb939a05fb1d1cc6155fe158a46a49c3e20..e7af7a048d207e744c5b98c267774cc9f1d73e2a 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.bgpcep.programming.spi;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionType;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.SubmitInstructionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.failure.Failure;
 
-public interface InstructionExecutorRegistry {
-       Registration<InstructionExecutor> registerInstructionExecutor(Class<? extends InstructionType> type, InstructionExecutor executor);
+public interface InstructionScheduler {
+       Failure submitInstruction(SubmitInstructionInput input, InstructionExecutor executor);
 }
+
similarity index 81%
rename from programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/SuccessfulRpcResult.java
rename to programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/SuccessfulRpcResult.java
index d0d1f15a7a7ec2a5a67f9acedeb98c3a0aa8634b..aaaf9105438d482f5093926e9dac1a628817a31c 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.bgpcep.programming.impl;
+package org.opendaylight.bgpcep.programming.spi;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -13,14 +13,14 @@ import java.util.Collections;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
-final class SuccessfulRpcResult<T> implements RpcResult<T> {
+public final class SuccessfulRpcResult<T> implements RpcResult<T> {
        private final T value;
 
        private SuccessfulRpcResult(final T value) {
                this.value = value;
        }
 
-       static <T> SuccessfulRpcResult<T> create(final T value) {
+       public static <T> SuccessfulRpcResult<T> create(final T value) {
                return new SuccessfulRpcResult<T>(value);
        }
 
similarity index 91%
rename from topology/tunnel-pcep-api/pom.xml
rename to programming/topology-api/pom.xml
index 1ea57a525329f39b08d88febba4d2308ef78c953..a85800af63ce67ccc1316a366c89d0707799f876 100644 (file)
@@ -5,13 +5,13 @@
 
        <parent>
                <groupId>org.opendaylight.bgpcep</groupId>
-               <artifactId>topology-parent</artifactId>
+               <artifactId>programming-parent</artifactId>
                <version>0.3.0-SNAPSHOT</version>
        </parent>
 
        <modelVersion>4.0.0</modelVersion>
-       <artifactId>topology-tunnel-pcep-api</artifactId>
-       <description>Topology Tunnel PCEP binding</description>
+       <artifactId>programming-topology-api</artifactId>
+       <description>Topology Programming API</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
        <prerequisites>
        <dependencies>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>pcep-api</artifactId>
+                       <artifactId>programming-api</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>topology-tunnel-api</artifactId>
+                       <artifactId>topology-api</artifactId>
             <version>${project.version}</version>
                </dependency>
         <dependency>
@@ -86,7 +86,7 @@
                    <instructions>
                        <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
                        <Export-Package>
-                           org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.*,
+                           org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.*,
                        </Export-Package>
                    </instructions>
                </configuration>
@@ -97,7 +97,7 @@
        <distributionManagement>
                <site>
                        <id>${project.artifactId}</id>
-                       <name>TOPOLOGY-TUNNEL-PCEP Module site</name>
+                       <name>PROGRAMMING-TOPOLOGY-API Module site</name>
                        <url>${basedir}/target/site/${project.artifactId}</url>
                </site>
        </distributionManagement>
diff --git a/programming/topology-api/src/main/yang/network-topology-programming.yang b/programming/topology-api/src/main/yang/network-topology-programming.yang
new file mode 100644 (file)
index 0000000..8330547
--- /dev/null
@@ -0,0 +1,42 @@
+module network-topology-programming {
+       yang-version 1;
+       namespace "urn:opendaylight:params:xml:ns:yang:topology:programming";
+       prefix "tp";
+
+       import network-topology { prefix nt; revision-date 2013-10-21; }
+       import programming { prefix pgm; revision-date 2013-09-30; }
+
+       organization "Cisco Systems, Inc.";
+       contact "Robert Varga <rovarga@cisco.com>";
+
+       description
+               "This module contains the programming extensions for tunnel
+               topologies.
+
+               Copyright (c)2013 Cisco Systems, Inc. All rights reserved.
+
+               This program and the accompanying materials are made available
+               under the terms of the Eclipse Public License v1.0 which
+               accompanies this distribution, and is available at
+               http://www.eclipse.org/legal/epl-v10.html";
+
+       revision "2013-11-02" {
+               description
+                       "Initial revision.";
+               reference "";
+       }
+
+       grouping topology-instruction-input {
+               uses pgm:submit-instruction-input;
+
+               leaf topology-id {
+                       type nt:topology-id;
+                       mandatory true;
+               }
+       }
+
+       grouping topology-instruction-output {
+               uses pgm:submit-instruction-output;
+       }
+}
+
index 2adf708749f761ce022764cadfd1e4733550a5c1..6e2001bc0851b362fac3a9683e3f029df600d714 100644 (file)
@@ -11,7 +11,7 @@
 
        <modelVersion>4.0.0</modelVersion>
        <artifactId>programming-tunnel-api</artifactId>
-       <description>Programming API</description>
+       <description>Tunnel Programming API</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
        <prerequisites>
@@ -21,7 +21,7 @@
        <dependencies>
                <dependency>
                        <groupId>${project.groupId}</groupId>
-                       <artifactId>programming-api</artifactId>
+                       <artifactId>programming-topology-api</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
index 8c9361b765ee07f69a31f41d1d9a8349b09d0b8c..d0d196b5e93490c1324949c5e5254aff41aab0a6 100644 (file)
@@ -4,8 +4,8 @@ module topology-tunnel-programming {
        prefix "ttp";
 
        import network-topology { prefix nt; revision-date 2013-10-21; }
+       import network-topology-programming { prefix tp; revision-date 2013-11-02; }
        import topology-tunnel { prefix tt; revision-date 2013-08-19; }
-       import programming { prefix pgm; revision-date 2013-09-30; }
 
        organization "Cisco Systems, Inc.";
        contact "Robert Varga <rovarga@cisco.com>";
@@ -27,114 +27,30 @@ module topology-tunnel-programming {
                reference "";
        }
 
-       identity attach-path-instruction {
-               base pgm:instruction-type;
-       }
-
-       identity create-path-instruction {
-               base pgm:instruction-type;
-       }
-
-       identity destroy-path-instruction {
-               base pgm:instruction-type;
-       }
-
-       identity detach-path-instruction {
-               base pgm:instruction-type;
-       }
-
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = attach-path-instruction";
-
-               case attach-path {
-                       container attach-path {
-                               leaf link-id {
-                                       type nt:link-id;
-                                       mandatory true;
-                               }
-                               leaf path-id {
-                                       type tt:path-id;
-                                       mandatory true;
-                               }
-                       }
-               }
-       }
-
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = create-path-instruction";
+       grouping create-tunnel-input {
+               uses tp:topology-instruction-input;
 
-               case create-path {
-                       container create-path {
-                               leaf path-id {
-                                       type tt:path-id;
-                                       mandatory true;
-                               }
-                       }
+               leaf link-id {
+                       type nt:link-id;
+                       mandatory true;
                }
        }
 
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = destroy-path-instruction";
-
-               case destroy-path {
-                       container destroy-path {
-                               leaf path-id {
-                                       type tt:path-id;
-                                       mandatory true;
-                               }
-                       }
-               }
-       }
-
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = detach-path-instruction";
-
-               case detach-path {
-                       container detach-path {
-                               leaf link-id {
-                                       type nt:link-id;
-                                       mandatory true;
-                               }
-                               leaf path-id {
-                                       type tt:path-id;
-                                       mandatory true;
-                               }
-                       }
-               }
+       grouping create-tunnel-output {
+               uses tp:topology-instruction-output;
        }
 
-       identity create-tunnel-instruction {
-               base pgm:instruction-type;
-       }
-
-       identity destroy-tunnel-instruction {
-               base pgm:instruction-type;
-       }
+       grouping destroy-tunnel-input {
+               uses tp:topology-instruction-input;
 
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = create-tunnel-instruction";
-
-               case create-tunnel {
-                       container create-tunnel {
-                               leaf link-id {
-                                       type nt:link-id;
-                                       mandatory true;
-                               }
-                       }
+               leaf link-id {
+                       type nt:link-id;
+                       mandatory true;
                }
        }
 
-       augment "/pgm:submit-instruction/pgm:input/pgm:arguments" {
-               when "../type = destroy-tunnel-instruction";
-
-               case destroy-tunnel {
-                       container destroy-tunnel {
-                               leaf link-id {
-                                       type nt:link-id;
-                                       mandatory true;
-                               }
-                       }
-               }
+       grouping destroy-tunnel-output {
+               uses tp:topology-instruction-output;
        }
 }
 
diff --git a/topology/pcep-api/src/main/yang/inventory-pcep.yang b/topology/pcep-api/src/main/yang/inventory-pcep.yang
deleted file mode 100644 (file)
index 36150e6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-module inventory-pcep {
-       // vi: set et smarttab sw=4 tabstop=4:
-       yang-version 1;
-       namespace "urn:opendaylight:inventory:pcep";
-       prefix "inv-pcep";
-
-       import network-topology { prefix nt; revision-date 2013-10-21; }
-       import opendaylight-inventory { prefix inv; revision-date 2013-08-19; }
-       import pcep-types { prefix pcep; revision-date 2013-10-05; }
-
-       organization "Cisco Systems, Inc.";
-       contact "Robert Varga <rovarga@cisco.com>";
-
-       description
-               "This module contains the PCEP extensions to base inventory
-               model.
-
-               Copyright (c)2013 Cisco Systems, Inc. All rights reserved.";
-
-       revision "2013-10-24" {
-               description
-                       "Initial revision.";
-               reference "";
-       }
-
-       typedef pcc-sync-state {
-               type enumeration {
-                       enum initial-resync {
-                               description
-                                       "Initial state resynchronization is being performed.";
-                       }
-                       enum synchronized {
-                               description
-                                       "State synchronization has been achieved.";
-                       }
-               }
-       }
-
-       augment "/inv:nodes/inv:node" {
-               container path-computation-client {
-                       description
-                "PCC-related run-time information. This container is only
-                present when the node is connected through PCEP in a PCC
-                role.";
-
-                       container stateful-tlv {
-                               uses pcep:stateful-capability-tlv;
-                       }
-
-                       leaf state-sync {
-                               when "../stateful-tlv";
-                               type pcc-sync-state;
-                       }
-
-            leaf topology-node {
-                type nt:node-ref;
-            }
-               }
-       }
-}
-
diff --git a/topology/pcep-api/src/main/yang/network-topology-pcep.yang b/topology/pcep-api/src/main/yang/network-topology-pcep.yang
deleted file mode 100644 (file)
index f870c72..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-module network-topology-pcep {
-       // vi: set et smarttab sw=4 tabstop=4:
-       yang-version 1;
-       namespace "urn:opendaylight:params:xml:ns:yang:topology:pcep";
-       prefix "pn";
-
-       import network-topology { prefix nt; revision-date 2013-10-21; }
-       import pcep-types { prefix pcep; revision-date 2013-10-05; }
-
-       organization "Cisco Systems, Inc.";
-       contact "Robert Varga <rovarga@cisco.com>";
-
-       description
-               "This module contains the PCEP extensions to base topology model. It
-        exposes the LSPs for which a particular node is the head end.
-
-               Copyright (c)2013 Cisco Systems, Inc. All rights reserved.";
-
-       revision "2013-10-24" {
-               description
-                       "Initial revision.";
-               reference "";
-       }
-
-       grouping pcep-client-attributes {
-        description "Data present in a node which is a PCEP client (PCC).";
-
-        container pcc {
-            config false;
-
-            list lsps {
-                leaf name {
-                    type pcep:symbolic-path-name;
-                }
-                key name;
-
-                // FIXME: hide protocol-specific?
-                uses pcep:lsp-object;
-            }
-        }
-       }
-
-       augment "/nt:network-topology/nt:topology/nt:node" {
-               uses pcep-client-attributes;
-       }
-}
-
index 5cf79ba43f5d4704b0f53c1218e0d0064803ea8c..e7c24d1c9c390c0fd0238e2959aeefb3980547d0 100644 (file)
        
        <modules>
         <module>api</module>
-        <module>pcep-api</module>
         <module>provider-bgp</module>
-        <module>provider-pcep</module>
                <module>tunnel-api</module>
-        <module>tunnel-pcep-api</module>
-        <module>tunnel-provider-pcep</module>
         <module>segment-routing</module>
     </modules>
 </project>
diff --git a/topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/ServerSessionManager.java b/topology/provider-pcep/src/main/java/org/opendaylight/bgpcep/topology/provider/pcep/ServerSessionManager.java
deleted file mode 100644 (file)
index 3a0f509..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.bgpcep.topology.provider.pcep;
-
-import java.net.InetAddress;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.pcep.PCEPSessionListener;
-import org.opendaylight.protocol.pcep.PCEPTerminationReason;
-import org.opendaylight.protocol.pcep.TerminationReason;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.PccSyncState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.nodes.node.PathComputationClientBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.nodes.node.path.computation.client.StatefulTlvBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcrptMessage;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PlspId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Tlvs;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.Reports;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.pcrpt.message.reports.Lsp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.stateful.capability.tlv.Stateful;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.symbolic.path.name.tlv.SymbolicPathName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PccBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.pcc.Lsps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.pcc.LspsKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-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.Preconditions;
-
-/**
- *
- */
-final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener> {
-       private static String createNodeId(final InetAddress addr) {
-               return "pcc://" + addr.getHostAddress();
-       }
-
-       private final class SessionListener implements PCEPSessionListener {
-               private org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node inventoryNode(
-                               final DataModificationTransaction trans, final InetAddress address) {
-                       final String pccId = createNodeId(address);
-
-                       // FIXME: after 0.6 yangtools, this cast should not be needed
-                       final Nodes nodes = (Nodes) trans.readOperationalData(ServerSessionManager.this.inventory);
-
-                       for (final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node n : nodes.getNode()) {
-                               LOG.debug("Matching inventory node {} to peer {}", n, address);
-                               if (n.getId().getValue().equals(pccId)) {
-                                       return n;
-                               }
-
-                               // FIXME: locate the node by its management IP address
-                       }
-
-                       /*
-                        * We failed to find a matching node. Let's create a dynamic one
-                        * to have a backer. Note that this node will be created in the
-                        * Runtime data space.
-                        */
-                       LOG.debug("Failed to find inventory node for peer {}, creating a new one at {}", address, pccId);
-
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId id = new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId(pccId);
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey nk = new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey(id);
-                       final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nii = InstanceIdentifier.builder(
-                                       ServerSessionManager.this.inventory).node(
-                                       org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, nk).toInstance();
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node ret = new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder().setId(
-                                       id).setKey(nk).build();
-
-                       trans.putRuntimeData(nii, ret);
-                       ServerSessionManager.this.ownsInventory = true;
-                       ServerSessionManager.this.inventoryNodeId = nii;
-                       return ret;
-               }
-
-               final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node topologyNode(
-                               final DataModificationTransaction trans,
-                               final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node invNode) {
-                       // FIXME: after 0.6 yangtools, this cast should not be needed
-                       final Topology topo = (Topology) trans.readOperationalData(ServerSessionManager.this.topology);
-
-                       for (final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node n : topo.getNode()) {
-                               LOG.debug("Matching topology node {} to inventory node {}", n, invNode);
-                               if (n.getNodeId().getValue().equals(invNode.getId().getValue())) {
-                                       return n;
-                               }
-                       }
-
-                       /*
-                        * We failed to find a matching node. Let's create a dynamic one
-                        * and note that we are the owner (so we clean it up afterwards).
-                        */
-                       final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId id = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(invNode.getId().getValue());
-                       final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey nk = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey(id);
-                       final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> nti = InstanceIdentifier.builder(
-                                       ServerSessionManager.this.topology).node(
-                                       org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class,
-                                       nk).toInstance();
-
-                       final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node ret = new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder().setKey(
-                                       nk).setNodeId(id).build();
-
-                       trans.putRuntimeData(nti, ret);
-                       ServerSessionManager.this.ownsTopology = true;
-                       ServerSessionManager.this.topologyNodeId = nti;
-                       return ret;
-               }
-
-               @Override
-               public void onSessionUp(final PCEPSession session) {
-                       /*
-                        * The session went up. Look up the router in Inventory model,
-                        * create it if it is not there (marking that fact for later
-                        * deletion), and mark it as synchronizing. Also create it in
-                        * the topology model, with empty LSP list.
-                        */
-                       final InetAddress peerAddress = session.getRemoteAddress();
-                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
-
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node invNode = inventoryNode(trans, peerAddress);
-                       LOG.debug("Peer {} resolved to inventory node {}", peerAddress, invNode);
-
-                       final org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node topoNode = topologyNode(
-                                       trans, invNode);
-                       LOG.debug("Peer {} resolved to topology node {}", peerAddress, topoNode);
-
-                       // Our augmentation in the topology node
-                       final PccBuilder pb = new PccBuilder();
-
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1 topoAugment = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1Builder().setPcc(
-                                       pb.build()).build();
-                       ServerSessionManager.this.topologyAugmentId = InstanceIdentifier.builder(ServerSessionManager.this.topologyNodeId).node(
-                                       org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1.class).toInstance();
-                       trans.putRuntimeData(ServerSessionManager.this.topologyAugmentId, topoAugment);
-
-                       // Our augmentation in the inventory node
-                       ServerSessionManager.this.pccBuilder = new PathComputationClientBuilder();
-
-                       final Tlvs tlvs = session.getRemoteTlvs();
-                       final Stateful stateful = tlvs.getStateful();
-                       if (stateful != null) {
-                               // FIXME: rework once groupings can be used in builders
-                               ServerSessionManager.this.pccBuilder.setStatefulTlv(new StatefulTlvBuilder().setStateful(stateful).build());
-                               ServerSessionManager.this.pccBuilder.setStateSync(PccSyncState.InitialResync);
-                       }
-
-                       ServerSessionManager.this.pccBuilder.setTopologyNode(topoNode.getNodeId());
-
-                       ServerSessionManager.this.inventoryAugmentBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.Node1Builder().setPathComputationClient(ServerSessionManager.this.pccBuilder.build());
-                       ServerSessionManager.this.inventoryAugmentId = InstanceIdentifier.builder(ServerSessionManager.this.inventoryNodeId).node(
-                                       org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.Node1.class).toInstance();
-                       trans.putRuntimeData(ServerSessionManager.this.inventoryAugmentId, ServerSessionManager.this.inventoryAugmentBuilder.build());
-
-                       // All set, commit the modifications
-                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
-
-                       /*
-                        * FIXME: once this Future is listenable, attach to it so we can
-                        *        do cleanup if the commit fails. For now we force a commit.
-                        */
-                       try {
-                               s.get();
-                       } catch (InterruptedException | ExecutionException e) {
-                               LOG.error("Failed to update internal state for session {}, terminating it", session, e);
-                               session.close(TerminationReason.Unknown);
-                       }
-
-                       LOG.info("Session with {} attached to inventory node {} and topology node {}", session.getRemoteAddress(), invNode.getId(),
-                                       topoNode.getNodeId());
-               }
-
-               private void tearDown(final PCEPSession session) {
-                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
-
-                       /*
-                        * The session went down. Undo all the Inventory and Topology
-                        * changes we have done.
-                        */
-                       trans.removeRuntimeData(ServerSessionManager.this.inventoryAugmentId);
-                       if (ServerSessionManager.this.ownsInventory) {
-                               trans.removeRuntimeData(ServerSessionManager.this.inventoryNodeId);
-                       }
-                       trans.removeRuntimeData(ServerSessionManager.this.topologyAugmentId);
-                       if (ServerSessionManager.this.ownsTopology) {
-                               trans.removeRuntimeData(ServerSessionManager.this.topologyNodeId);
-                       }
-
-                       /*
-                        * FIXME: once this Future is listenable, attach to it so we can
-                        *        do cleanup if the commit fails. For now we force a commit.
-                        */
-                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
-                       try {
-                               s.get();
-                       } catch (InterruptedException | ExecutionException e) {
-                               LOG.error("Failed to cleanup internal state for session {}", session, e);
-                       }
-               }
-
-               @Override
-               public void onSessionDown(final PCEPSession session, final Exception e) {
-                       LOG.warn("Session {} went down unexpectedly", e);
-                       tearDown(session);
-               }
-
-               @Override
-               public void onSessionTerminated(final PCEPSession session, final PCEPTerminationReason reason) {
-                       LOG.info("Session {} terminated by peer with reason {}", session, reason);
-                       tearDown(session);
-               }
-
-               private InstanceIdentifier<Lsps> lspIdentifier(final SymbolicPathName name) {
-                       return InstanceIdentifier.builder(ServerSessionManager.this.topologyAugmentId).node(Lsps.class, new LspsKey(name.getPathName())).toInstance();
-               }
-
-               @Override
-               public void onMessage(final PCEPSession session, final Message message) {
-                       if (!(message instanceof PcrptMessage)) {
-                               LOG.info("Unhandled message {} on session {}", message, session);
-                               session.sendMessage(unhandledMessageError);
-                       }
-
-                       final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
-
-                       final DataModificationTransaction trans = ServerSessionManager.this.dataProvider.beginTransaction();
-
-                       for (final Reports r : rpt.getReports()) {
-                               final Lsp lsp = r.getLsp();
-
-                               if (lsp.isSync() && !ServerSessionManager.this.synced) {
-                                       // Update synchronization flag
-                                       ServerSessionManager.this.synced = true;
-                                       ServerSessionManager.this.inventoryAugmentBuilder.setPathComputationClient(ServerSessionManager.this.pccBuilder.setStateSync(
-                                                       PccSyncState.Synchronized).build());
-                                       trans.putRuntimeData(ServerSessionManager.this.inventoryAugmentId,
-                                                       ServerSessionManager.this.inventoryAugmentBuilder.build());
-                                       LOG.debug("Session {} achieved synchronized state", session);
-                               }
-
-                               final PlspId id = lsp.getPlspId();
-                               if (lsp.isRemove()) {
-                                       final SymbolicPathName name = ServerSessionManager.this.lsps.remove(id);
-                                       if (name != null) {
-                                               trans.removeRuntimeData(lspIdentifier(name));
-                                       }
-
-                                       LOG.debug("LSP {} removed", lsp);
-                               } else {
-                                       if (!ServerSessionManager.this.lsps.containsKey(id)) {
-                                               LOG.debug("PLSPID {} not known yet, looking for a symbolic name", id);
-
-                                               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.object.Tlvs tlvs = r.getLsp().getTlvs();
-                                               final SymbolicPathName name = tlvs.getSymbolicPathName();
-                                               if (name == null) {
-                                                       LOG.error("PLSPID {} seen for the first time, not reporting the LSP");
-                                                       // TODO: what should we do here?
-                                                       continue;
-                                               }
-                                       }
-
-                                       final SymbolicPathName name = ServerSessionManager.this.lsps.get(id);
-                                       trans.putRuntimeData(lspIdentifier(name), lsp);
-
-                                       LOG.debug("LSP {} updated");
-                               }
-                       }
-
-                       /*
-                        * FIXME: once this Future is listenable, attach to it so we can
-                        *        do cleanup if the commit fails. For now we force a commit.
-                        */
-                       final Future<RpcResult<TransactionStatus>> s = trans.commit();
-                       try {
-                               s.get();
-                       } catch (InterruptedException | ExecutionException e) {
-                               LOG.error("Failed to update internal state for session {}, closing it", session, e);
-                               session.close(TerminationReason.Unknown);
-                       }
-               }
-       }
-
-       private static final Logger LOG = LoggerFactory.getLogger(ServerSessionManager.class);
-       private static final Pcerr unhandledMessageError = new PcerrBuilder().setPcerrMessage(
-                       new PcerrMessageBuilder().setErrorType(null).build()).build();
-       private final Map<PlspId, SymbolicPathName> lsps = new HashMap<>();
-       private final InstanceIdentifier<Nodes> inventory;
-       private final InstanceIdentifier<Topology> topology;
-       private final DataProviderService dataProvider;
-
-       private boolean ownsInventory = false;
-       private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> inventoryNodeId;
-       private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.Node1> inventoryAugmentId;
-       private org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.pcep.rev131024.Node1Builder inventoryAugmentBuilder;
-       private PathComputationClientBuilder pccBuilder;
-       private boolean synced = false;
-
-       private boolean ownsTopology = false;
-       private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> topologyNodeId;
-       private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1> topologyAugmentId;
-
-       public ServerSessionManager(final DataProviderService dataProvider, final InstanceIdentifier<Nodes> inventory,
-                       final InstanceIdentifier<Topology> topology) {
-               this.dataProvider = Preconditions.checkNotNull(dataProvider);
-               this.inventory = Preconditions.checkNotNull(inventory);
-               this.topology = Preconditions.checkNotNull(topology);
-       }
-
-       @Override
-       public PCEPSessionListener getSessionListener() {
-               return new SessionListener();
-       }
-}