Stubpce Update 61/64561/5
authorMartial COULIBALY <martial.coulibaly@gfi.fr>
Fri, 20 Oct 2017 09:04:26 +0000 (11:04 +0200)
committerguillaume.lambert <guillaume.lambert@orange.com>
Thu, 21 Dec 2017 15:58:39 +0000 (16:58 +0100)
(FakePCE implementation) This implementation is only for test purposes and allows
to load PCE topology from xml file.

This commit includes :
- Add java package 'org.opendaylight.transportpce.stubpce.topology'
which implements java classes for getting topology elements from xml
file and build path descriptions List.
- This file 'fakepce.xml' must be in src/main/resources to be loaded
in target/classes and must also follow 'SuperNode'
model (cf fakepce.xml).
- change 'leaf node-id' in case termination-point
in model yang transportpce-pathDescription by 'leaf tp-node-id'
to not interfere with 'leaf node-id' in case node.
- Add PathDescriptionList in stubpce yang model to stored
all possible paths in datastore.
- update servicehandler dependency
- move stubpce and stubrenderer to tests folder
- add dependency 'Version update to 1.6 of the service-path model'.

Change-Id: I29391cc098706c261d109f8f1860bbfd78012c69
Signed-off-by: Martial COULIBALY <martial.coulibaly@gfi.fr>
Signed-off-by: Olivier RENAIS <olivier.renais@orange.com>
(cherry picked from commit 730925ab6a616aef3cc2f5b8b190774fa5708407)

27 files changed:
api/src/main/yang/service_path/transportpce-pathDescription@2017-04-26.yang
api/src/main/yang/service_path/transportpce-service-path@2017-04-26.yang
tests/stubpce/pom.xml
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CompliancyCheck.java
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/SendingPceRPCs.java
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceImpl.java
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/impl/StubpceProvider.java
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java [new file with mode: 0644]
tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java [new file with mode: 0644]
tests/stubpce/src/main/resources/fakepce.xml [new file with mode: 0644]
tests/stubpce/src/main/resources/org/opendaylight/blueprint/Stubpce-blueprint.xml

index d9d4de0aa3ce9072a2444e59372d1ff094f022c6..dff1bd49ba6df7175c771f596a358ec0b3e8576b 100644 (file)
@@ -60,7 +60,7 @@ module transportpce-pathDescription {
           leaf tp-id {
               type string; //to be clarified with topology model
           }
-          leaf node-id {
+          leaf tp-node-id {
               type string; //to be clarified with topology model
           }
         }
index dd517b4b0298d2b46a23d6b6e2b8e11d312ddff4..41022a306f9caf3b76f50b1dc49c7e2799fad912 100644 (file)
@@ -140,6 +140,27 @@ module transportpce-servicepath {
       uses transportpce-common-service-path-types:service-path;
     }
   }
+
+  grouping stubpce-path-description {
+      leaf path-name {
+          type string;
+          description
+            "Identifier for the pathDescription to be created in
+             the ROADM network, e.g., CLFI, CLCI, etc.";
+          mandatory true;
+        }
+      uses transportpce-pathDescription:path-description;
+  }
+
+  container path-description-list {
+    description
+      "List of pathDescription. Can only be created, deleted, modified, etc. using special RPCs.";
+    list pathDescriptions {
+      key "path-name";
+      uses stubpce-path-description;
+    }
+  }
+
 notification service-path-rpc-result {
     description
       "This Notification indicates result of  service RPC";
index 48ae3cfa0c39020c240e1e77df60bed4ae85f21c..f4e5341b4464e33c53fa35459932e6d90c41d227 100644 (file)
@@ -26,6 +26,21 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   <version>0.2.0-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
+  <!-- Ajout Fakepce to add fakepce.xml to target/classes -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <additionalClasspathElements>
+            <additionalClasspathElement>src/main/resources</additionalClasspathElement>
+          </additionalClasspathElements>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
   <dependencies>
     <dependency>
       <groupId>${project.groupId}</groupId>
@@ -50,5 +65,36 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
+
+    <!-- Ajout Fakepce -->
+    <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-xml</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-jaxb-annotations</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>com.fasterxml.woodstox</groupId>
+        <artifactId>woodstox-core</artifactId>
+        <version>5.0.3</version>
+    </dependency>
+    <dependency>
+        <groupId>org.codehaus.woodstox</groupId>
+        <artifactId>stax2-api</artifactId>
+    </dependency>
   </dependencies>
 </project>
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/CheckCoherencyHardSoft.java
new file mode 100644 (file)
index 0000000..bae514f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *  Class to check coherency between hard and soft constraints.
+ *  @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ *
+ */
+public class CheckCoherencyHardSoft {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(CheckCoherencyHardSoft.class);
+    /** Hard Constraints. */
+    private HardConstraints hard;
+    /** Soft Constraints. */
+    private SoftConstraints soft;
+
+    public CheckCoherencyHardSoft(HardConstraints hard, SoftConstraints soft) {
+        this.hard = hard;
+        this.soft = soft;
+    }
+
+    /**
+     * function to check coherency between hard and soft constraints.
+     * @return  <code> true </code>  if coherent
+     *          <code> false </code> else
+     */
+    public boolean check() {
+        boolean result = false;
+        if (hard != null && soft != null) {
+            /**
+             * Check coherency with hard/soft constraints
+             * hard/soft include/exclude coherency
+             *
+             */
+        } else {
+            LOG.info("HardConstraints or/and  SoftConstraints is null !");
+            result = true;
+        }
+        return result;
+    }
+
+}
index 12d2b0dee6e86b9fc738779d65a108f67f72dd84..ccbc5ea244c0471cbe17fd3d983a9eb4dc964adf 100644 (file)
@@ -9,20 +9,21 @@
 
 package org.opendaylight.transportpce.stubpce;
 
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
 /**
  * Class to check RPCs Compliancy.
+ *
  * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
  *
  */
 public class CompliancyCheck {
-    /* Logging. */
+    /** Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(CompliancyCheck.class);
-    /* Response message from procedure. */
+    /** Response message from procedure. */
     private String message;
 
     private PathComputationRequestInput input;
@@ -31,7 +32,7 @@ public class CompliancyCheck {
         input = prcInput;
     }
 
-    /*
+    /**
      * Check if a String is not
      * null and not equal to ''.
      *
@@ -48,6 +49,14 @@ public class CompliancyCheck {
 
     }
 
+    /**
+     * check if service name
+     * or ServiceHandlerHeader
+     * is set in RPC request.
+     *
+     * @return true  if  settings is ok,
+     *          false if not
+     */
     public Boolean check() {
         Boolean result = true;
         if (input != null) {
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/LoggingFuturesCallBack.java
new file mode 100644 (file)
index 0000000..7738ceb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import com.google.common.util.concurrent.FutureCallback;
+import org.slf4j.Logger;
+
+/**
+ * Class to log future logging from datastore actions (write, modify, delete..).
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         bealf of Orange
+ */
+public class LoggingFuturesCallBack<V> implements FutureCallback<V> {
+
+    private Logger log;
+    private String message;
+
+    public LoggingFuturesCallBack(String message, Logger log) {
+        this.message = message;
+        this.log = log;
+    }
+
+    @Override
+    public void onFailure(Throwable ex) {
+        log.warn(message, ex);
+
+    }
+
+    @Override
+    public void onSuccess(V arg0) {
+        log.info("Success! {} ", arg0);
+
+    }
+
+}
\ No newline at end of file
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/MyEndpoint.java
new file mode 100644 (file)
index 0000000..87758df
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import java.util.Map;
+
+/**
+ * Enum class to identify ServiceAEnd and serviceZEnd.
+ *
+ * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
+ *
+ */
+enum MyEndpoint {
+    SERVICEAEND(1),
+    SERVICEZEND(2);
+
+    int value;
+    private static final Map<Integer, MyEndpoint> VALUE_MAP;
+
+    MyEndpoint(int value) {
+        this.value = value;
+    }
+
+    static {
+        final com.google.common.collect.ImmutableMap.Builder<java.lang.Integer, MyEndpoint> b =
+                com.google.common.collect.ImmutableMap.builder();
+        for (MyEndpoint enumItem : MyEndpoint.values()) {
+            b.put(enumItem.value, enumItem);
+        }
+
+        VALUE_MAP = b.build();
+    }
+
+    /**
+     * Get integer value.
+     *
+     * @return integer value.
+     */
+    public int getIntValue() {
+        return value;
+    }
+
+    /**
+     * Get Endpoint value.
+     *
+     * @param valueArg
+     *            Integer to identify Enum
+     * @return corresponding ServiceFormat item
+     */
+    public static MyEndpoint forValue(int valueArg) {
+        return VALUE_MAP.get(valueArg);
+    }
+}
index 0ad88a6e59f41e8b6360acf56c0345d3978eb01c..ad867bde6a4f3b6b27c24426a148dd69e2a195ee 100644 (file)
@@ -9,26 +9,52 @@
 
 package org.opendaylight.transportpce.stubpce;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.Resource;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.NodeBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.General;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Diversity;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.constraints.sp.co.routing.or.general.general.Exclude;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.HardConstraints;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev170426.routing.constraints.sp.SoftConstraints;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeaderBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceAEnd;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.path.ServiceZEnd;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,223 +63,793 @@ import org.slf4j.LoggerFactory;
  * PCE requests :
  * - path-computation-request
  * - cancel-resource-reserve.
- * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on behalf of Orange
  *
  */
 public class SendingPceRPCs {
-
-    /* Logging. */
+    /** Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(SendingPceRPCs.class);
-    /* define procedure success (or not ). */
     private Boolean success;
-    /* define type of request<br>
-     * <code>true</code> pathcomputation <br>
-     * <code>false</code> cancelresourcereserve .*/
-    private AToZDirection atozdirection;
-    private ZToADirection ztoadirection;
+    private PathComputationRequestInput input;
+    private CancelResourceReserveInput cancelInput;
     private PathDescriptionBuilder pathDescription;
-
+    private DataBroker db;
+    private String error;
+    private final ListeningExecutorService executor;
+    private List<ServicePaths> servicePathList;
 
     public SendingPceRPCs() {
         success = true;
-        atozdirection = null;
-        ztoadirection = null;
         setPathDescription(null);
+        setError("");
+        executor = null;
+        setServicePathList(new ArrayList<ServicePaths>());
+    }
+
+    public SendingPceRPCs(PathComputationRequestInput input,DataBroker databroker,ListeningExecutorService executor) {
+        success = true;
+        setPathDescription(null);
+        setInput(input);
+        setCancelInput(null);
+        setDb(databroker);
+        setError("");
+        servicePathList = readServicePathList();
+        this.executor = executor;
+    }
+
+    public SendingPceRPCs(CancelResourceReserveInput input,DataBroker databroker,ListeningExecutorService executor) {
+        success = true;
+        setPathDescription(null);
+        setInput(null);
+        setCancelInput(input);
+        setDb(databroker);
+        setError("");
+        servicePathList = readServicePathList();
+        this.executor = executor;
+    }
+
+    /**
+     * Compare AEnd and ZEnd resource Node to
+     * AEnd and ZEnd String.
+     *
+     * @param pathAend AEnd resource Node
+     * @param pathZend ZEnd resource Node
+     * @param inputAend AEnd String Node
+     * @param inputZend ZEnd String Node
+     * @return Boolean result true if equal, false if not
+     */
+    private Boolean comp(Resource pathAend, Resource pathZend, String inputAend, String inputZend) {
+        Boolean result = false;
+        if (pathAend != null && pathZend != null && inputAend != null && inputZend != null) {
+            if (pathAend instanceof Node && pathZend instanceof Node) {
+                Node aend = (Node) pathAend;
+                Node zend = (Node) pathZend;
+                if (aend.getNodeId().compareToIgnoreCase(inputAend) == 0) {
+                    if (zend.getNodeId().compareToIgnoreCase(inputZend) == 0) {
+                        result = true;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Compare two resource.
+     *
+     * @param res1 first resource
+     * @param res2 second resource
+     * @return Boolean result true if equal, false if not
+     */
+    private Boolean egalResource(Resource res1, Resource res2) {
+        LOG.info("comparing resource ...");
+        Boolean result = false;
+        LOG.info(res1.getClass().getName() + " - " + res2.getClass().getName());
+        if (res1.getClass().getName().compareToIgnoreCase(res2.getClass().getName()) == 0) {
+            if (res1 instanceof Node && res2 instanceof Node) {
+                Node node1 = (Node)res1;
+                Node node2 = (Node)res2;
+                if (node1.getNodeId().compareTo(node2.getNodeId()) == 0) {
+                    result = true;
+                }
+            }
+            if (res1 instanceof TerminationPoint && res2 instanceof TerminationPoint) {
+                TerminationPoint tp1 = (TerminationPoint)res1;
+                TerminationPoint tp2 = (TerminationPoint)res2;
+                if (tp1.getTpNodeId().compareTo(tp2.getTpNodeId()) == 0) {
+                    if (tp1.getTpId().compareTo(tp2.getTpId()) == 0) {
+                        result = true;
+                    }
+                }
+            }
+            if (res1 instanceof Link && res2 instanceof Link) {
+                Link link1 = (Link)res1;
+                Link link2 = (Link)res2;
+                if (link1.getLinkId().compareTo(link2.getLinkId()) == 0) {
+                    result = true;
+                }
+
+            }
+        }
+        return result;
+    }
+
+    /**
+     *  compare two AtoZDirection.
+     *
+     * @param atoz1 first AToZDirection
+     * @param atoz2 second AToZDirection
+     * @return Boolean result true if equal, false if not
+     */
+    private Boolean egalAtoZDirection(AToZDirection atoz1, AToZDirection atoz2) {
+        LOG.info("comparing AtoZDirection ...");
+        Boolean result = true;
+        if (atoz1.getAToZ().size() == atoz2.getAToZ().size()) {
+            int index = 0;
+            int size = atoz1.getAToZ().size();
+            LOG.info("size : " + size);
+            String id1 = null;
+            String id2 = null;
+            while (index < size) {
+                id1 = atoz1.getAToZ().get(index).getId();
+                LOG.info("id : " + id1);
+                Resource res1 = atoz1.getAToZ().get(index).getResource().getResource();
+                LOG.info("res1 : " + res1.toString());
+                Resource res2 = null;
+                if (id1 != null) {
+                    Boolean trouve = false;
+                    for (int loop = 0;loop < size;loop++) {
+                        id2 = atoz2.getAToZ().get(loop).getId();
+                        if (id2 != null && id2.compareTo(id1) == 0) {
+                            res2 = atoz2.getAToZ().get(loop).getResource().getResource();
+                            LOG.info("res2 : " + res2.toString());
+                            trouve = true;
+                            break;
+                        }
+                    }
+                    if (trouve) {
+                        if (!egalResource(res1, res2)) {
+                            result = false;
+                            break;
+                        }
+                    }
+                } else {
+                    result = false;
+                    break;
+                }
+                index++;
+            }
+        } else {
+            LOG.info("AToZDirection size is not equal !");
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     *  compare two ZtoZDirection.
+     *
+     * @param ztoa1 first ZToZDirection
+     * @param ztoa2 second ZToZDirection
+     * @return Boolean result true if equal, false if not
+     */
+    private Boolean egalZtoADirection(ZToADirection ztoa1, ZToADirection ztoa2) {
+        LOG.info("comparing ZtoADirection ...");
+        Boolean result = true;
+        if (ztoa1.getZToA().size() == ztoa2.getZToA().size()) {
+            int index = 0;
+            int size = ztoa1.getZToA().size();
+            LOG.info("size : " + size);
+            String id1 = null;
+            String id2 = null;
+            while (index < size) {
+                id1 = ztoa1.getZToA().get(index).getId();
+                LOG.info("id : " + id1);
+                Resource res1 = ztoa1.getZToA().get(index).getResource().getResource();
+                LOG.info("res1 : " + res1.toString());
+                Resource res2 = null;
+                if (id1 != null) {
+                    Boolean trouve = false;
+                    for (int loop = 0;loop < size;loop++) {
+                        id2 = ztoa2.getZToA().get(loop).getId();
+                        if (id2 != null && id2.compareTo(id1) == 0) {
+                            res2 = ztoa2.getZToA().get(loop).getResource().getResource();
+                            LOG.info("res2 : " + res2.toString());
+                            trouve = true;
+                            break;
+                        }
+                    }
+                    if (trouve) {
+                        if (!egalResource(res1, res2)) {
+                            result = false;
+                            break;
+                        }
+                    }
+                } else {
+                    result = false;
+                    break;
+                }
+                index++;
+            }
+        } else {
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     * Test if resources Nodes
+     * not include in PathDescriptions.
+     *
+     * @param path PathDescriptions
+     * @param nodes Nodes List
+     * @return Boolean result true if found, false if not
+     */
+    private Boolean excludeNode(PathDescriptions path, List<String> nodes) {
+        LOG.info("Testing exclude Nodes ...");
+        Boolean result = false;
+        if (path != null && !nodes.isEmpty()) {
+            List<AToZ> list = path.getAToZDirection().getAToZ();
+            if (!list.isEmpty()) {
+                int index = 0;
+                boolean found = false;
+                while (index < list.size() && !found) {
+                    Resource res = list.get(index).getResource().getResource();
+                    if (res != null && res instanceof Node) {
+                        Node node = (Node) res;
+                        for (String exclude : nodes) {
+                            if (exclude.compareToIgnoreCase(node.getNodeId()) == 0) {
+                                LOG.info("Node not excluded !");
+                                found = true;
+                                break;
+                            }
+                        }
+                    }
+                    index++;
+                }
+                if (!found) {
+                    result = true;
+                }
+            }
+        } else {
+            LOG.info("exclude parameters not corrrect !");
+        }
+        return result;
+    }
+
+    /**
+     * check if existing services not
+     * in pathDescriptions.
+     *
+     *
+     * @param existingService existing service list
+     * @param path PathDescriptions
+     * @param choice 0:Nodes, 1:Clli, 2:Srlg
+     * @return Boolean result true if found, false if not
+     */
+    private Boolean diversityService(List<String> existingService, PathDescriptions path, int choice) {
+        LOG.info("Testing diversity ...");
+        Boolean result = false;
+        if (path != null && choice >= 0 && !existingService.isEmpty()) {
+            int index = 0;
+            while (index < existingService.size()) {
+                String tmp = existingService.get(index);
+                if (tmp != null) {
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service
+                        .types.rev170426.service.path.PathDescription pathDesc = null;
+                    if (servicePathList != null && !servicePathList.isEmpty()) {
+                        for (ServicePaths service : servicePathList) {
+                            if (service.getServicePathName().compareTo(tmp) == 0) {
+                                LOG.info("Existing Service '" + tmp + "' found in ServicePathList ...");
+                                pathDesc = service.getPathDescription();
+                            }
+                        }
+                    }
+                    if (pathDesc != null) {
+                        switch (choice) {
+                            case 0: //Nodes
+                                LOG.info("Checking Node existing-service-applicability ...");
+                                if (!egalAtoZDirection(path.getAToZDirection(), pathDesc.getAToZDirection())) {
+                                    result = true;
+                                    break;
+                                }
+                                break;
+                            case 1: //Clli
+                                LOG.info("Checking clli existing-service-applicability ...");
+                                break;
+
+                            case 2: //Srlg
+                                LOG.info("Checking srlg existing-service-applicability ...");
+
+                                break;
+                            default:
+                                break;
+                        }
+                    } else {
+                        LOG.info("Existing Service '" + tmp + "' not found in ServicePathList !");
+                        result = true;
+                    }
+                    if (!result) {
+                        break;
+                    }
+                }
+                index++;
+            }
+        } else {
+            LOG.info("Diversity parameters not coherent !");
+        }
+        return result;
+    }
+
+    /**
+     * test if pathDescription
+     * already exists in ServicePathList.
+     *
+     * @param path PathDescriptions
+     * @return <code>Boolean</code> result
+     */
+    private Boolean testPathDescription(PathDescriptions path) {
+        LOG.info("Testing pathDescription ...");
+        Boolean result = false;
+        if (path != null) {
+            LOG.info("retrieving path from servicePath List ...");
+            try {
+                if (!servicePathList.isEmpty()) {
+                    LOG.info("ServicePathList not empty, contains " + servicePathList.size() + " paths.");
+                    for (ServicePaths service : servicePathList) {
+                        org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service
+                            .types.rev170426.service.path.PathDescription tmp = service.getPathDescription();
+                        if (tmp != null) {
+                            if (path.getAToZDirection() != null && tmp.getAToZDirection() != null
+                                    && egalAtoZDirection(path.getAToZDirection(), tmp.getAToZDirection())) {
+                                if (path.getZToADirection() != null && tmp.getZToADirection() != null
+                                        && egalZtoADirection(path.getZToADirection(), tmp.getZToADirection())) {
+                                    result = true;
+                                    LOG.info("Path already present in servicePath List");
+                                    break;
+                                } else {
+                                    LOG.info("ZtoADirection not equal or one of ZtoADirection is null!");
+                                    break;
+                                }
+                            } else {
+                                LOG.info("AtoZDirection not equal !");
+                                break;
+                            }
+
+                        }
+                    }
+                } else {
+                    LOG.info("ServicePathList is empty");
+                }
+            } catch (NullPointerException e) {
+                LOG.error("ServicePathList is empty");
+            }
+        } else {
+            LOG.info("PathDescriptions is null !");
+            result = true;
+        }
+        LOG.info("testPathDescription result : " + result);
+        return result;
+    }
+
+    /**
+     * function to retrieve Paths based on
+     * AEnd and ZEnd.
+     *
+     * @param aendNodeId Aend Node Id
+     * @param zendNodeId Zend Node Id
+     * @return result PathDescriptions List
+     */
+    private List<PathDescriptions> retrievePath(String aendNodeId, String zendNodeId) {
+        List<PathDescriptions> result = new ArrayList<PathDescriptions>();
+        List<PathDescriptions> paths = readPathDescriptionList();
+        if (!paths.isEmpty() && aendNodeId != null && zendNodeId != null) {
+            LOG.info("retrieving paths from pathDescription List for " + aendNodeId + " / " + zendNodeId);
+            for (PathDescriptions tmp : paths) {
+                Resource pathAend = null;
+                Resource pathZend = null;
+                String id = null;
+                if (tmp != null) {
+                    LOG.info("Getting Aend & ZEnd from path '" + tmp.getPathName() + "'...");
+                    int index = 0;
+                    int size = tmp.getAToZDirection().getAToZ().size();
+                    while (index < size) {
+                        id = tmp.getAToZDirection().getAToZ().get(index).getId();
+                        if (id.compareToIgnoreCase("1") == 0) {
+                            Resource resource = tmp.getAToZDirection().getAToZ().get(index).getResource()
+                                    .getResource();
+                            LOG.info(resource.getClass().toString() + " : " + resource.toString());
+                            pathAend = resource;
+                            break;
+                        }
+                        index++;
+                    }
+                    index = 0;
+                    while (index < size) {
+                        id = tmp.getZToADirection().getZToA().get(index).getId();
+                        if (id.compareToIgnoreCase("1") == 0) {
+                            Resource resource = tmp.getZToADirection().getZToA().get(index).getResource()
+                                    .getResource();
+                            LOG.info(resource.toString());
+                            pathZend = resource;
+                            break;
+                        }
+                        index++;
+                    }
+                    if (pathAend != null && pathZend != null) {
+                        LOG.info("pathAend : " + pathAend + " - pathZend: " + pathZend);
+                        LOG.info("aendNodeId : " + aendNodeId + " - zendNodeId : " + zendNodeId);
+                        if (comp(pathAend, pathZend, aendNodeId, zendNodeId)) {
+                            LOG.info("PathDescription found !");
+                            result.add(tmp);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * found Pathdescriptions with
+     * name containing an expression.
+     *
+     * @param pathdescr PathDescriptions List
+     * @param contain String expression
+     * @return PathDescriptionsOrdered List
+     */
+    private SortedSet<PathDescriptionsOrdered> foundpath(List<PathDescriptions> pathdescr, String contain) {
+        SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
+        ListIterator<PathDescriptions> it = pathdescr.listIterator();
+        int odr = 0;
+        while (it.hasNext()) {
+            PathDescriptions path = it.next();
+            String name = path.getPathName();
+            LOG.info("path  : " + name);
+            if (name != null && name.contains(contain)) {
+                LOG.info("    path gets : " + name);
+                String [] split = name.split("_");
+                if (split.length == 3) {
+                    odr = Integer.parseInt(split[2]);
+                    result.add(new PathDescriptionsOrdered(path, odr));
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * order PathDescriptions List
+     * with first, ordered direct links
+     * and secondly ordered indirect
+     * links.
+     *
+     * @param pathdescr PathDescriptions List
+     * @return PathDescriptions List ordered
+     */
+    private List<PathDescriptions> orderPathdescriptionsList(List<PathDescriptions> pathdescr) {
+        SortedSet<PathDescriptionsOrdered> direct = new TreeSet<PathDescriptionsOrdered>();
+        SortedSet<PathDescriptionsOrdered> indirect = new TreeSet<PathDescriptionsOrdered>();
+        List<PathDescriptions> result = new ArrayList<PathDescriptions>();
+        int size = pathdescr.size();
+        if (size > 0) {
+            LOG.info("getting direct path first ...");
+            direct = foundpath(pathdescr, "_direct_");
+            LOG.info("getting indirect path first ...");
+            indirect = foundpath(pathdescr, "_indirect_");
+        }
+        if (direct.size() > 0) {
+            Iterator<PathDescriptionsOrdered> itset = direct.iterator();
+            while (itset.hasNext()) {
+                result.add(itset.next().getPathDescriptions());
+            }
+            if (indirect.size() > 0) {
+                Iterator<PathDescriptionsOrdered> itset2 = indirect.iterator();
+                while (itset2.hasNext()) {
+                    result.add(itset2.next().getPathDescriptions());
+                }
+            }
+
+        } else if (indirect.size() > 0) {
+            Iterator<PathDescriptionsOrdered> itset2 = indirect.iterator();
+            while (itset2.hasNext()) {
+                result.add(itset2.next().getPathDescriptions());
+            }
+        }
+        if (result.size() == pathdescr.size()) {
+            return result;
+        } else {
+            return null;
+        }
+    }
+
+    public ListenableFuture<Boolean> cancelResourceReserve() {
+        LOG.info("In cancelResourceReserve request ...");
+        setSuccess(false);
+        return executor.submit(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                Boolean output = false;
+                if (cancelInput != null) {
+                    Boolean found = false;
+                    String name = cancelInput.getServiceName();
+                    if (name != null && !servicePathList.isEmpty()) {
+                        for (ServicePaths service : servicePathList) {
+                            if (name.compareTo(service.getServicePathName()) == 0) {
+                                LOG.info("ServicePaths found in ServicePathList !!!");
+                                found = true;
+                                break;
+                            }
+                        }
+                        if (found) {
+                            LOG.info("removing servicePaths from datastore ...");
+                            if (writeOrDeleteServicePathList(name,1)) {
+                                LOG.info("Service deleted !");
+                                setSuccess(true);
+                                output = true;
+                            } else {
+                                LOG.info("service deletion failed !");
+                            }
+                        }
+                    } else {
+                        LOG.info("serviceName is null or servicePathList is empty !");
+                    }
+                } else {
+                    LOG.info("cancelresourcereserveinput parameter not valid !");
+                }
+                return output;
+            }
+        });
+    }
+
+    public ListenableFuture<Boolean> pathComputation() {
+        LOG.info("In pathComputation request ...");
+        setSuccess(false);
+        return executor.submit(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                Boolean output = false;
+                List<PathDescriptions> pathsList = new ArrayList<PathDescriptions>();
+                PathDescriptions path = null;
+                int index ;
+                Boolean constraints = false;
+                if (input != null) {
+                    HardConstraints inputHard = input.getHardConstraints();
+                    SoftConstraints inputSoft = input.getSoftConstraints();
+                    if (inputHard != null || inputSoft != null) {
+                        constraints = true;
+                    }
+                    path = null;
+                    pathsList =  retrievePath(input.getServiceAEnd().getNodeId(), input.getServiceZEnd()
+                            .getNodeId());
+                    index = 0;
+                    output = false;
+                    /** get pathList ordered. */
+                    pathsList = orderPathdescriptionsList(pathsList);
+                    if (!pathsList.isEmpty()) {
+                        LOG.info(pathsList.size() + " Paths get from Pathdescription List");
+                        index = 0;
+                        output = false;
+                        while (index < pathsList.size()) {
+                            path = pathsList.get(index);
+                            LOG.info("path n°" + index + " gets : '" + path.getPathName() + "'!");
+                            if (constraints) {
+                                LOG.info("Calculating path with constraints ...");
+                                if (inputHard.getCoRoutingOrGeneral() instanceof General) {
+                                    General general = (General)inputHard.getCoRoutingOrGeneral();
+                                    if (general != null) {
+                                        Diversity diversity = general.getDiversity();
+                                        if (diversity != null) {
+                                            LOG.info("Getting diversity ...");
+                                            List<String> existingService = diversity.getExistingService();
+                                            if (existingService.size() > 0) {
+                                                LOG.info("Getting existing service applicability ...");
+                                                int choice = -1;
+                                                if (choice < 0
+                                                        && diversity.getExistingServiceApplicability().isNode()) {
+                                                    LOG.info("existing-service-applicability : Node");
+                                                    choice = 0;
+                                                }
+                                                if (choice < 0
+                                                        && diversity.getExistingServiceApplicability().isClli()) {
+                                                    LOG.info("existing-service-applicability : Clli");
+                                                    choice = 1;
+                                                }
+                                                if (choice < 0
+                                                        && diversity.getExistingServiceApplicability().isSrlg()) {
+                                                    LOG.info("existing-service-applicability : Srlg");
+                                                    choice = 2;
+                                                }
+                                                if (!diversityService(existingService, path, choice)) {
+                                                    error = "existing service applicability not satisfied";
+                                                    LOG.info(error);
+                                                    path = null;
+                                                }
+                                            }
+                                        }
+                                        Exclude exclude = general.getExclude();
+                                        if (exclude != null) {
+                                            LOG.info("Getting exclude ...");
+                                            if (!excludeNode(path, exclude.getNodeId())) {
+                                                error = "Exclude node constraints not satisfied !";
+                                                LOG.info(error);
+                                                path = null;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            if (!testPathDescription(path)) {
+                                LOG.info("Process finish !");
+                                output = true;
+                                break;
+                            }
+                            index++;
+                        }
+                    } else {
+                        LOG.info("failed to retrieve path from PathDescription List !");
+                    }
+                } else {
+                    LOG.info("pathComputationRequestInput parameter not valid !");
+                }
+                if (path != null) {
+                    LOG.info("Path ok !");
+                    pathDescription = new PathDescriptionBuilder()
+                            .setAToZDirection(path.getAToZDirection())
+                            .setZToADirection(path.getZToADirection());
+                    if (input.isResourceReserve()) {
+                        LOG.info("reserving pce resource ...");
+                        setPathDescription(pathDescription);
+                        if (writeOrDeleteServicePathList(input.getServiceName(), 0)) {
+                            LOG.info("write ServicePaths to datastore");
+                            setSuccess(true);
+                        } else {
+                            LOG.error("writing ServicePaths to datastore failed ! ");
+                        }
+                    } else {
+                        LOG.info("no pce resource reserve !");
+                        setSuccess(true);
+                    }
+                }
+                return output;
+            }
+        });
     }
 
-    public void cancelResourceReserve() {
-        LOG.info("Wait for 10s til beginning the PCE cancelResourceReserve request");
+
+    /**
+     * get all ServicePaths in ServicePathlist.
+     *
+     * @return <code>ServicePaths List</code>
+     */
+    private List<ServicePaths> readServicePathList() {
+        LOG.info("Reading ServicePathList ...");
+        List<ServicePaths> result = null;
+        ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
+        InstanceIdentifier<ServicePathList> iid = InstanceIdentifier.create(ServicePathList.class);
+        Future<Optional<ServicePathList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
+        Optional<ServicePathList> optional = Optional.absent();
         try {
-            Thread.sleep(10000); //sleep for 10s
-        } catch (InterruptedException e) {
-            LOG.error(e.toString());
+            optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS);
+        } catch (ExecutionException e) {
+            LOG.error("Reading service failed:", e);
+        }
+        if (optional.isPresent()) {
+            LOG.info("ServicePath List present !");
+            result = optional.get().getServicePaths();
         }
-        LOG.info("cancelResourceReserve ...");
+        return result;
     }
 
-    public void pathComputation() {
-        LOG.info("Wait for 10s til beginning the PCE pathComputation request");
+
+    private List<PathDescriptions> readPathDescriptionList() {
+        LOG.info("Reading PathDescriptionsList ...");
+        List<PathDescriptions> result = null;
+        ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
+        InstanceIdentifier<PathDescriptionList> iid = InstanceIdentifier.create(PathDescriptionList.class);
+        Future<Optional<PathDescriptionList>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
+        Optional<PathDescriptionList> optional = Optional.absent();
         try {
-            Thread.sleep(10000); //sleep for 10s
-        } catch (InterruptedException e) {
-            LOG.error(e.toString());
+            optional = Futures.getChecked(future, ExecutionException.class, 60, TimeUnit.SECONDS);
+        } catch (ExecutionException e) {
+            LOG.error("Reading service failed:", e);
+        }
+        if (optional.isPresent()) {
+            LOG.info("ServicePath List present !");
+            result = optional.get().getPathDescriptions();
+        }
+        return result;
+
+    }
+
+    /**
+     * Write or Delete ServicePaths
+     * for ServicePathList.
+     *
+     * @param serviceName Service Name
+     * @param choice 0 : write or 1 : delete
+     * @return Boolean result true if deleted, false if not
+     */
+    private Boolean writeOrDeleteServicePathList(String serviceName, int choice) {
+        Boolean result = null;
+        if (serviceName != null && serviceName.compareTo(" ") != 0 && choice >= 0 && choice < 2) {
+            LOG.info("WriteOrDeleting '" + serviceName + "' ServicePaths");
+            WriteTransaction writeTx = db.newWriteOnlyTransaction();
+            result = true;
+            String action = null;
+            InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
+                    .child(ServicePaths.class,new ServicePathsKey(serviceName));
+            Future<Void> future = null;
+            switch (choice) {
+                case 0: /** Write. */
+                    LOG.info("Writing '" + serviceName + "' Service");
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service
+                        .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
+                        ._interface.service.types.rev170426.service.path.PathDescriptionBuilder();
+                    if (pathDescription != null) {
+                        if (pathDescription.getAToZDirection() != null) {
+                            path.setAToZDirection(pathDescription.getAToZDirection());
+                        }
+                        if (pathDescription.getZToADirection() != null) {
+                            path.setZToADirection(pathDescription.getZToADirection());
+                        }
+                        LOG.info("pathdescription gets");
+                    }
+                    ServiceAEnd aend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
+                            ._interface.service.types.rev170426.service.path.ServiceAEndBuilder(input.getServiceAEnd())
+                            .build();
+                    ServiceZEnd zend = new org.opendaylight.yang.gen.v1.http.org.transportpce.b.c
+                            ._interface.service.types.rev170426.service.path.ServiceZEndBuilder(input.getServiceZEnd())
+                            .build();
+                    ServicePaths service = new ServicePathsBuilder()
+                            .setServicePathName(serviceName)
+                            .setServiceHandlerHeader(new ServiceHandlerHeaderBuilder()
+                                    .setRequestId(input.getServiceHandlerHeader().getRequestId()).build())
+                            .setServiceAEnd(aend)
+                            .setServiceZEnd(zend)
+                            .setHardConstraints(input.getHardConstraints())
+                            .setSoftConstraints(input.getSoftConstraints())
+                            .setPathDescription(path.build())
+                            .build();
+                    LOG.info("Servicepath build");
+                    writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
+                    action = "write";
+                    //CheckedFuture<Void, OperationFailedException> future = transaction.submit();
+                    future = writeTx.submit();
+                    try {
+                        LOG.info("Sending '" + action + "' command to datastore !");
+                        Futures.getChecked(future, ExecutionException.class);
+                    } catch (ExecutionException e) {
+                        LOG.error("Failed to " + action + " service from Service List");
+                        result = false;
+                    }
+                    break;
+
+                case 1: /** Delete */
+                    LOG.info("Deleting '" + serviceName + "' Service");
+                    writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                    action = "delete";
+                    future = writeTx.submit();
+                    try {
+                        LOG.info("Sending '" + action + "' command to datastore !");
+                        Futures.getChecked(future, ExecutionException.class);
+                    } catch (ExecutionException e) {
+                        LOG.error("Failed to " + action + " service from Service List");
+                        result = false;
+                    }
+                    break;
+
+                default:
+                    LOG.info("No choice found");
+                    break;
+
+            }
+
+        } else {
+            LOG.info("Parameters not correct !");
         }
-        LOG.info("PathComputation ...");
-        buildAToZ();
-        buildZToA();
-
-        setPathDescription(new PathDescriptionBuilder()
-            .setAToZDirection(atozdirection)
-            .setZToADirection(ztoadirection));
-    }
-
-    public void buildAToZ() {
-        Link atoB = new LinkBuilder()
-            .setLinkId("AtoB")
-            .build();
-        Link btoZ = new LinkBuilder()
-            .setLinkId("BtoZ")
-            .build();
-
-        Node roadmA = new NodeBuilder()
-            .setNodeId("RoadmA")
-            .build();
-        Node roadmB = new NodeBuilder()
-            .setNodeId("RoadmB")
-            .build();
-        Node roadmZ = new NodeBuilder()
-            .setNodeId("RoadmZ")
-            .build();
-
-        /*A -> Z*/
-        /*RoadmA*/
-        AToZKey roadmAKey = new AToZKey("RoadmA");
-        Resource roadmAResource = new ResourceBuilder()
-            .setResource(roadmA)
-            .build();
-        AToZ atoz = new AToZBuilder()
-            .setId("RoadmA")
-            .setKey(roadmAKey)
-            .setResource(roadmAResource)
-            .build();
-        /*Link AtoB*/
-        AToZKey atoBKey = new AToZKey("AtoB");
-        Resource atozResource = new ResourceBuilder()
-            .setResource(atoB)
-            .build();
-        AToZ atob = new AToZBuilder()
-            .setId("AtoB")
-            .setKey(atoBKey)
-            .setResource(atozResource)
-            .build();
-        /*RoadmB*/
-        AToZKey roadmBKey = new AToZKey("RoadmB");
-        Resource roadmBResource = new ResourceBuilder()
-            .setResource(roadmB)
-            .build();
-        AToZ roadmb = new AToZBuilder()
-            .setId("RoadmB")
-            .setKey(roadmBKey)
-            .setResource(roadmBResource)
-            .build();
-        /*Link BtoZ*/
-        AToZKey btoZKey = new AToZKey("BtoZ");
-        Resource botzResource = new ResourceBuilder()
-            .setResource(btoZ)
-            .build();
-        AToZ btoz = new AToZBuilder()
-            .setId("BtoZ")
-            .setKey(btoZKey)
-            .setResource(botzResource)
-            .build();
-        /*RoadmZ*/
-        AToZKey roadmZKey = new AToZKey("RoadmZ");
-        Resource roadmZResource = new ResourceBuilder()
-            .setResource(roadmZ)
-            .build();
-        AToZ roadmz = new AToZBuilder()
-            .setId("RoadmZ")
-            .setKey(roadmZKey)
-            .setResource(roadmZResource)
-            .build();
-
-        List<AToZ> atozList = new ArrayList<AToZ>();
-        atozList.add(atoz);
-        atozList.add(atob);
-        atozList.add(roadmb);
-        atozList.add(btoz);
-        atozList.add(roadmz);
-
-        atozdirection = new AToZDirectionBuilder()
-            .setRate((long)100)
-            .setAToZWavelengthNumber((long)200)
-            .setAToZ(atozList)
-            .build();
-    }
-
-    public void buildZToA() {
-
-        Link btoA = new LinkBuilder()
-            .setLinkId("BtoA")
-            .build();
-        Link ztoB = new LinkBuilder()
-            .setLinkId("ZtoB")
-            .build();
-
-        Node roadmA = new NodeBuilder()
-            .setNodeId("RoadmA")
-            .build();
-        Node roadmB = new NodeBuilder()
-            .setNodeId("RoadmB")
-            .build();
-        Node roadmZ = new NodeBuilder()
-            .setNodeId("RoadmZ")
-            .build();
-
-        /*Z -> A*/
-        /*RoadmZ*/
-        ZToAKey roadmZKey = new ZToAKey("RoadmZ");
-        Resource roadmZResource = new ResourceBuilder()
-            .setResource(roadmZ)
-            .build();
-        ZToA ztoa = new ZToABuilder()
-            .setId("RoadmZ")
-            .setKey(roadmZKey)
-            .setResource(roadmZResource)
-            .build();
-        /*Link ZtoB*/
-        ZToAKey ztoBKey = new ZToAKey("ZtoB");
-        Resource ztoBResource = new ResourceBuilder()
-            .setResource(ztoB)
-            .build();
-        ZToA ztob = new ZToABuilder()
-            .setId("ZtoB")
-            .setKey(ztoBKey)
-            .setResource(ztoBResource)
-            .build();
-        /*RoadmB*/
-        ZToAKey roadmBKey = new ZToAKey("RoadmB");
-        Resource roadmBResource = new ResourceBuilder()
-            .setResource(roadmB)
-            .build();
-        ZToA roadmb = new ZToABuilder()
-            .setId("RoadmB")
-            .setKey(roadmBKey)
-            .setResource(roadmBResource)
-            .build();
-        /*Link BtoA*/
-        ZToAKey btoAKey = new ZToAKey("BtoA");
-        Resource btoAResource = new ResourceBuilder()
-            .setResource(btoA)
-            .build();
-        ZToA btoa = new ZToABuilder()
-            .setId("BtoA")
-            .setKey(btoAKey)
-            .setResource(btoAResource)
-            .build();
-        /* RoadmA*/
-        ZToAKey roadmAKey = new ZToAKey("RoadmA");
-        Resource roadmAResource = new ResourceBuilder()
-            .setResource(roadmA)
-            .build();
-        ZToA roadma = new ZToABuilder()
-            .setId("RoadmA")
-            .setKey(roadmAKey)
-            .setResource(roadmAResource)
-            .build();
-
-        List<ZToA> ztoaList = new ArrayList<ZToA>();
-        ztoaList.add(ztoa);
-        ztoaList.add(ztob);
-        ztoaList.add(roadmb);
-        ztoaList.add(btoa);
-        ztoaList.add(roadma);
-
-        ztoadirection = new ZToADirectionBuilder()
-            .setRate((long)100)
-            .setZToAWavelengthNumber((long)100)
-            .setZToA(ztoaList)
-            .build();
+        return result;
     }
 
     public PathDescriptionBuilder getPathDescription() {
@@ -272,4 +868,43 @@ public class SendingPceRPCs {
         this.success = success;
     }
 
+    public PathComputationRequestInput getInput() {
+        return input;
+    }
+
+    public void setInput(PathComputationRequestInput input) {
+        this.input = input;
+    }
+
+    public CancelResourceReserveInput getCancelInput() {
+        return cancelInput;
+    }
+
+    public void setCancelInput(CancelResourceReserveInput input) {
+        this.cancelInput = input;
+    }
+
+    public DataBroker getDb() {
+        return db;
+    }
+
+    public void setDb(DataBroker db) {
+        this.db = db;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public List<ServicePaths> getServicePathList() {
+        return servicePathList;
+    }
+
+    public void setServicePathList(List<ServicePaths> servicePathList) {
+        this.servicePathList = servicePathList;
+    }
 }
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceCompliancyCheck.java
new file mode 100644 (file)
index 0000000..7353d96
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ConnectionType;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.handler.header.ServiceHandlerHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for checking service sdnc-request-header compliancy.
+ *
+ * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
+ *
+ */
+public class StubpceCompliancyCheck {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(StubpceCompliancyCheck.class);
+    /** SdncRequestHeader. */
+    private ServiceHandlerHeader serviceHandlerHeader;
+    /** Service Name. */
+    private String serviceName;
+    /** Type of connection : service / infrastructure / roadm-line. */
+    private ConnectionType conType;
+    /** Response message from procedure. */
+    private String message;
+
+
+    public StubpceCompliancyCheck(String serviceName,ServiceHandlerHeader serviceHandlerHeader) {
+        this.serviceName = serviceName;
+        this.serviceHandlerHeader = serviceHandlerHeader;
+        this.setMessage("");
+    }
+
+    /**
+     * Check if a String is not null and not equal to void.
+     *
+     * @param value
+     *            String value
+     * @return true if String ok false if not
+     */
+    public Boolean checkString(String value) {
+        Boolean result = false;
+        if (value != null && value.compareTo("") != 0) {
+            result = true;
+        }
+        return result;
+
+    }
+
+    /**
+     * Check Compliancy of Service request.
+     *
+     * @param contype
+     *            Boolean to check connection Type
+     * @param servicehandler
+     *            Boolean to check sndcRequestHeader
+     *
+     * @return true if String ok false if not
+     */
+    public Boolean check(Boolean contype, Boolean servicehandler) {
+        Boolean result = true;
+        if (!checkString(serviceName)) {
+            result = false;
+            message = "Service Name is not set";
+            LOG.debug(message);
+        } else if (contype && conType == null) {
+            result = false;
+            message = "Service ConnectionType is not set";
+            LOG.debug(message);
+        }
+        if (servicehandler) {
+            if (serviceHandlerHeader != null) {
+                String requestId = serviceHandlerHeader.getRequestId();
+                if (!checkString(requestId)) {
+                    result = false;
+                    message = "Service serviceHandlerHeader 'request-id' is not set";
+                    LOG.debug(message);
+                }
+            } else {
+                result = false;
+                message = "Service serviceHandlerHeader is not set ";
+                LOG.debug(message);
+            }
+        }
+        return result;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/StubpceTxRxCheck.java
new file mode 100644 (file)
index 0000000..a301900
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.ServiceFormat;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.lgx.Lgx;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.service.port.Port;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServiceEndpointSp;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.RxDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service.endpoint.sp.TxDirection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for checking missing info on Tx/Rx for A/Z end.
+ *
+ * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class StubpceTxRxCheck {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(StubpceTxRxCheck.class);
+    /** ServiceEndpoint. */
+    private ServiceEndpointSp serviceEnd;
+    /** Response message from procedure. */
+    private String message;
+    /** type serviceEndpoint : serviceAEnd / serviceZEnd. */
+    private String service = null;
+
+    /**
+     * ServicehandlerTxRxCheck class constructor.
+     *
+     * @param endPoint
+     *            ServiceEndpoint
+     * @param value
+     *            Integer to define ServiceAEND/ZEND
+     */
+    public StubpceTxRxCheck(ServiceEndpointSp endPoint, int value) {
+        this.serviceEnd = endPoint;
+        this.setMessage("");
+        if (value > 0) {
+            service = MyEndpoint.forValue(value).name();
+        }
+    }
+
+    /**
+     * Check if a String is not null and not equal to ''.
+     *
+     * @param value
+     *            String value
+     * @return true if String ok false if not
+     */
+    public Boolean checkString(String value) {
+        Boolean result = false;
+        if (value != null && value.compareTo("") != 0) {
+            result = true;
+        }
+        return result;
+
+    }
+
+    /**
+     * check if Port info is compliant.
+     *
+     * @param port
+     *            port info
+     * @return true if String ok false if not
+     */
+    public Boolean checkPort(Port port) {
+        Boolean result = false;
+        if (port != null) {
+            String portDeviceName = port.getPortDeviceName();
+            String portType = port.getPortType();
+            String portName = port.getPortName();
+            String portRack = port.getPortRack();
+            String portShelf = port.getPortShelf();
+
+            if (checkString(portDeviceName) && checkString(portType) && checkString(portName) && checkString(portRack)
+                    && checkString(portShelf)) {
+                result = true;
+            }
+        }
+        return result;
+
+    }
+
+    /**
+     * Check if lgx info is compliant.
+     *
+     * @param lgx
+     *            lgx info
+     * @return true if String ok false if not
+     */
+    public Boolean checkLgx(Lgx lgx) {
+        Boolean result = false;
+        if (lgx != null) {
+            String lgxDeviceName = lgx.getLgxDeviceName();
+            String lgxPortName = lgx.getLgxPortName();
+            String lgxPortRack = lgx.getLgxPortRack();
+            String lgxPortShelf = lgx.getLgxPortShelf();
+            if (checkString(lgxDeviceName) && checkString(lgxPortName) && checkString(lgxPortRack)
+                    && checkString(lgxPortShelf)) {
+                result = true;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Check if Tx/Rx Direction complaincy info.
+     *
+     * @param txDirection
+     *            TxDirection
+     * @param rxDirection
+     *            RxDirection
+     *
+     * @return <code>true</code> if check is ok <code>false</code> else
+     */
+    public boolean checkTxOrRxInfo(TxDirection txDirection, RxDirection rxDirection) {
+        Boolean result = true;
+        if (txDirection != null) {
+            if (!checkPort(txDirection.getPort())) {
+                result = false;
+                message = "Service TxDirection Port is not correctly set";
+            } else if (rxDirection != null) {
+                if (!checkPort(rxDirection.getPort())) {
+                    result = false;
+                    message = "Service RxDirection Port is not correctly set";
+                }
+            } else {
+                result = false;
+                message = "Service RxDirection is not correctly set";
+            }
+        } else {
+            result = false;
+            message = "Service TxDirection is not correctly set";
+        }
+        return result;
+    }
+
+    /**
+     * Check Compliancy of Service TxRx info.
+     *
+     * @return true if String ok false if not
+     */
+    public Boolean check() {
+        Boolean result = true;
+        if (serviceEnd != null) {
+            Long serviceRate = serviceEnd.getServiceRate();
+            ServiceFormat serviceformat = serviceEnd.getServiceFormat();
+            String clli = serviceEnd.getClli();
+            if (serviceRate != null && serviceRate <= 0) {
+                result = false;
+                message = "Service " + service + " rate is not set";
+                LOG.info(message);
+            } else if (serviceformat == null) {
+                result = false;
+                message = "Service " + service + " format is not set";
+                LOG.info(message);
+            } else if (!checkString(clli)) {
+                result = false;
+                message = "Service" + service + " clli format is not set";
+                LOG.info(message);
+            } else {
+                if (!checkTxOrRxInfo(serviceEnd.getTxDirection(), serviceEnd.getRxDirection())) {
+                    result = false;
+                }
+            }
+        } else {
+            result = false;
+            message = service + " is not set";
+            LOG.info(message);
+        }
+        return result;
+
+    }
+
+    public static void main(String[] args) {
+
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/TpNodeTp.java
new file mode 100644 (file)
index 0000000..ebb2ac6
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+
+/**
+ * Class to create structure
+ * TerminationPoint
+ * Node
+ * TerminationPoint.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class TpNodeTp {
+    private TerminationPoint tpOut;
+    private TerminationPoint tpIn;
+    private Node node;
+    private List<Resource> resources;
+    private List<AToZ> atoz;
+    private List<ZToA> ztoa;
+    private List<String> ids;
+
+    /**
+     * TpNodeTp Constructor.
+     *
+     * @param in TerminationPoint input
+     * @param out TerminationPoint output
+     * @param node Node Id
+     */
+    public TpNodeTp(TerminationPoint in, TerminationPoint out, Node node) {
+        this.tpOut = out;
+        this.tpIn = in;
+        this.node = node;
+        resources = new ArrayList<Resource>();
+        atoz = new ArrayList<AToZ>();
+        ztoa = new ArrayList<ZToA>();
+        ids = new ArrayList<String>();
+
+    }
+
+    /**
+     * create resource List.
+     */
+    public void createListResource() {
+        ids.clear();
+        resources.clear();
+        atoz.clear();
+        ztoa.clear();
+
+        resources.add(new ResourceBuilder().setResource(tpIn).build());
+        ids.add(tpIn.getTpNodeId().concat("-").concat(tpIn.getTpId()));
+        resources.add(new ResourceBuilder().setResource(node).build());
+        ids.add(node.getNodeId());
+        resources.add(new ResourceBuilder().setResource(tpOut).build());
+        ids.add(tpOut.getTpNodeId().concat("-").concat(tpOut.getTpId()));
+    }
+
+    /**
+     * Create an hop in AtoZList.
+     * @param odr hop number
+     */
+    public void createAToZListHop(int odr) {
+        AToZ hop = null;
+        AToZKey atozKey = null;
+        createListResource();
+        for (Resource resource : resources) {
+            atozKey = new AToZKey(Integer.toString(odr));
+            resource = new ResourceBuilder().setResource(resource.getResource()).build();
+            hop = new AToZBuilder()
+                    .setKey(atozKey)
+                    .setResource(resource)
+                    .build();
+            atoz.add(hop);
+            odr++;
+        }
+    }
+
+    /**
+     * Create an hop in ZtoAList.
+     * @param odr hop number
+     */
+    public void createZToAListHop(int odr) {
+        ZToA hop = null;
+        ZToAKey ztoaKey = null;
+        createListResource();
+        for (Resource resource : resources) {
+            ztoaKey = new ZToAKey(Integer.toString(odr));
+            resource = new ResourceBuilder().setResource(resource.getResource()).build();
+            hop = new ZToABuilder()
+                    .setKey(ztoaKey)
+                    .setResource(resource)
+                    .build();
+            ztoa.add(hop);
+            odr++;
+        }
+    }
+
+    public TpNodeTp reverse() {
+        return new TpNodeTp(tpOut, tpIn, node);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder("[ ");
+        result.append("tpIn : " + tpIn.getTpId());
+        result.append(" - Node : " + node.getNodeId());
+        result.append(" - tpOut : " + tpOut.getTpId());
+        result.append(" ]");
+        return result.toString();
+
+    }
+
+    public List<AToZ> getAToZ() {
+        return atoz;
+    }
+
+    public List<ZToA> getZToA() {
+        return ztoa;
+    }
+
+    public Node getNode() {
+        return node;
+    }
+
+    public TerminationPoint getTpIn() {
+        return tpIn;
+    }
+
+    public TerminationPoint getTpOut() {
+        return tpOut;
+    }
+}
index 41ac6e991c47908879ae0fe893faef4c0d05adb7..89d3404f7d2a20b31fd44e87aed4b0a901d4555d 100644 (file)
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-
 package org.opendaylight.transportpce.stubpce.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
-import org.opendaylight.transportpce.stubpce.CompliancyCheck;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.transportpce.stubpce.CheckCoherencyHardSoft;
 import org.opendaylight.transportpce.stubpce.SendingPceRPCs;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveInput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.CancelResourceReserveOutputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestInput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutput;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.PathComputationRequestOutputBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResult;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.ServicePathRpcResultBuilder;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.service.path.rpc.result.PathDescription;
+import org.opendaylight.transportpce.stubpce.StubpceCompliancyCheck;
+import org.opendaylight.transportpce.stubpce.StubpceTxRxCheck;
+import org.opendaylight.transportpce.stubpce.topology.PathDescriptionsOrdered;
+import org.opendaylight.transportpce.stubpce.topology.SuperNodePath;
+import org.opendaylight.transportpce.stubpce.topology.Topology;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev161014.configuration.response.common.ConfigurationResponseCommonBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.ServiceList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.Services;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev161014.service.list.ServicesKey;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.RpcStatusEx;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.ServicePathNotificationTypes;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.response.parameters.sp.response.parameters.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.CancelResourceReserveOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathComputationRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.PathDescriptionListBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceDeleteOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestInput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServiceImplementationRequestOutput;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathList;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathListBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResult;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.ServicePathRpcResultBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.list.ServicePathsKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.service.path.rpc.result.PathDescription;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * Class to implement
- * StubpceService
- * StubpceListener.
- *
- * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
- *
+ * Class to implement StubpceService StubpceListener.
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
  */
 
-public class StubpceImpl implements StubpceService {
-
-    /* Logging. */
+public class StubpceImpl implements TransportpceServicepathService {
+    /** Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(StubpceImpl.class);
-
-    private CompliancyCheck compliancyCheck;
-    /* send notification. */
+    /** Permit to access database. */
+    private DataBroker db;
+    /** check service sdnc-request-header compliancy. */
+    private StubpceCompliancyCheck compliancyCheck;
+    /** check missing info on Tx/Rx for A/Z end. */
+    private StubpceTxRxCheck txrxCheck;
+    /** check coherency between hard and soft constraints. */
+    private CheckCoherencyHardSoft checkCoherencyHardSoft;
     private NotificationPublishService notificationPublishService;
     private ServicePathRpcResult notification;
+    private PathDescriptionBuilder pathDescriptionBuilder;
+    private SendingPceRPCs sendingPCE;
+    private final ListeningExecutorService executor = MoreExecutors
+            .listeningDecorator(Executors.newFixedThreadPool(10));
 
-    public StubpceImpl(NotificationPublishService notificationPublishService) {
+    public StubpceImpl(NotificationPublishService notificationPublishService, DataBroker databroker) {
         this.notificationPublishService = notificationPublishService;
+        this.db = databroker;
+        pathDescriptionBuilder = null;
+        if (initializePathDescriptionList(databroker)) {
+            fillPathDesciptionList();
+        }
+        initializeServicePathList(databroker);
+        /*if (initializeServicePathList(databroker)) {
+            fillServicePathList();
+        }*/
     }
 
     @Override
     public Future<RpcResult<CancelResourceReserveOutput>> cancelResourceReserve(CancelResourceReserveInput input) {
         LOG.info("RPC cancelResourceReserve  request received");
         String message = "";
+        String responseCode = "";
+        ConfigurationResponseCommonBuilder configurationResponseCommon = null;
+        String serviceName = input.getServiceName();
+        LOG.info("serviceName : " + serviceName);
+        if (serviceName != null) {
+            sendingPCE = new SendingPceRPCs(input,db,executor);
+            FutureCallback<Boolean> pceCallback = new FutureCallback<Boolean>() {
+                String message = "";
+                ServicePathRpcResult notification = null;
 
-        notification = new ServicePathRpcResultBuilder()
-            .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
-            .setServiceName(input.getServiceName())
-            .setStatus(RpcStatusEx.Pending)
-            .setStatusMessage("Service compliant, submitting cancelResourceReserve Request ...")
-            .build();
-        try {
-            notificationPublishService.putNotification(notification);
-        } catch (InterruptedException e) {
-            LOG.info("notification offer rejected : " + e);
-        }
+                @Override
+                public void onFailure(Throwable arg0) {
+                    LOG.error(arg0.toString());
+                    LOG.error("Cancel resource failed !");
+                    notification = new ServicePathRpcResultBuilder()
+                            .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
+                            .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
+                            .setStatusMessage("Cancel resource request failed  : " + arg0.getMessage()).build();
+                    try {
+                        notificationPublishService.putNotification(notification);
+                    } catch (InterruptedException e) {
+                        LOG.info("notification offer rejected : " + e);
+                    }
+                }
+
+                @Override
+                public void onSuccess(Boolean response) {
+                    LOG.info("response : " + response);
+                    if (response) {
+                        message = "Resource cancelled !";
+                        notification = new ServicePathRpcResultBuilder()
+                                .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
+                                .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
+                                .setStatusMessage(message)
+                                .build();
+                    } else {
+                        message = sendingPCE.getError();
+                        notification = new ServicePathRpcResultBuilder()
+                                .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
+                                .setServiceName("")
+                                .setStatus(RpcStatusEx.Failed).setStatusMessage(message)
+                                .build();
+                        message = "Cancel request failed !";
+                    }
+                    LOG.info(notification.toString());
+                    try {
+                        notificationPublishService.putNotification(notification);
+                    } catch (InterruptedException e) {
+                        LOG.info("notification offer rejected : " + e);
+                    }
+                    LOG.info(message);
+                }
+            };
+            ListenableFuture<Boolean> pce = sendingPCE.cancelResourceReserve();
+            Futures.addCallback(pce, pceCallback, executor);
+            LOG.info("Cancel Resource Request in progress ...");
+            configurationResponseCommon = new ConfigurationResponseCommonBuilder()
+                    .setAckFinalIndicator("No")
+                    .setRequestId(input.getServiceHandlerHeader().getRequestId())
+                    .setResponseMessage("Service compliant, Cancel resource request in progress...")
+                    .setResponseCode("200");
+
+            CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder()
+                    .setConfigurationResponseCommon(configurationResponseCommon.build());
 
-        SendingPceRPCs sendingPCE = new SendingPceRPCs();
-        sendingPCE.cancelResourceReserve();
-        if (sendingPCE.getSuccess()) {
-            message = "ResourceReserve cancelled ! ";
+            return RpcResultBuilder.success(output.build()).buildFuture();
         } else {
-            message = "Cancelling ResourceReserve failed ! ";
+            message = "serviceName / requestId is not correct !";
+            responseCode = "500";
+            notification = new ServicePathRpcResultBuilder()
+                    .setNotificationType(ServicePathNotificationTypes.CancelResourceReserve)
+                    .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
+                    .setStatusMessage(message).build();
+            try {
+                notificationPublishService.putNotification(notification);
+            } catch (InterruptedException e) {
+                LOG.info("notification offer rejected : " + e);
+            }
         }
-        LOG.info(message);
-        ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
-        configurationResponseCommon
-            .setAckFinalIndicator("Yes")
-            .setRequestId(input.getServiceHandlerHeader().getRequestId())
-            .setResponseCode("200")
-            .setResponseMessage("")
-            .setResponseMessage(message);
-        CancelResourceReserveOutputBuilder output  = new CancelResourceReserveOutputBuilder();
-        output
-            .setConfigurationResponseCommon(configurationResponseCommon.build());
+        configurationResponseCommon = new ConfigurationResponseCommonBuilder();
+        configurationResponseCommon.setAckFinalIndicator("Yes")
+        .setRequestId(input.getServiceHandlerHeader().getRequestId())
+        .setResponseMessage(message)
+        .setResponseCode(responseCode).build();
+        CancelResourceReserveOutputBuilder output = new CancelResourceReserveOutputBuilder();
+        output.setConfigurationResponseCommon(configurationResponseCommon.build());
         return RpcResultBuilder.success(output.build()).buildFuture();
     }
 
-
     @Override
     public Future<RpcResult<PathComputationRequestOutput>> pathComputationRequest(PathComputationRequestInput input) {
         LOG.info("RPC pathcomputation request received");
         String message = "";
-        PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder();
-        ConfigurationResponseCommonBuilder configurationResponseCommon = new ConfigurationResponseCommonBuilder();
+        String responseCode = "";
+        boolean coherencyHardSoft = false;
+        boolean commonId = true;
+        ConfigurationResponseCommonBuilder configurationResponseCommon = null;
+        compliancyCheck = new StubpceCompliancyCheck(input.getServiceName(), input.getServiceHandlerHeader());
+        if (compliancyCheck.check(false, true)) {
+            LOG.info("Service compliant !");
+            /**
+             * If compliant, service-request parameters are verified in order to
+             * check if there is no missing parameter that prevents calculating
+             * a path and implement a service.
+             */
+            LOG.info("checking Tx/Rx Info for AEnd ...");
+            txrxCheck = new StubpceTxRxCheck(input.getServiceAEnd(), 1);
+            if (txrxCheck.check()) {
+                LOG.info("Tx/Rx Info for AEnd checked !");
+                LOG.info("checking Tx/Rx Info for ZEnd ...");
+                txrxCheck = new StubpceTxRxCheck(input.getServiceZEnd(), 2);
+                if (txrxCheck.check()) {
+                    LOG.info("Tx/Rx Info for ZEnd checked !");
+                    /**
+                     * If OK, common-id is verified in order to see if there is
+                     * no routing policy provided. If yes, the routing
+                     * constraints of the policy are recovered and coherency
+                     * with hard/soft constraints provided in the input of the
+                     * RPC.
+                     */
+                    if (input.getHardConstraints() != null || input.getSoftConstraints() != null) {
+                        LOG.info("Constraints specified !");
+                        checkCoherencyHardSoft = new CheckCoherencyHardSoft(input.getHardConstraints(),
+                                input.getSoftConstraints());
+                        if (checkCoherencyHardSoft.check()) {
+                            LOG.info("hard/soft constraints coherent !");
+                            coherencyHardSoft = true;
+                        } else {
+                            LOG.info("hard/soft constraints are not coherent !");
+                            message = "hard/soft constraints are not coherent !";
+                            responseCode = "500";
+                        }
+                    } else {
+                        commonId = false;
+                    }
+                    if (!commonId || (commonId && coherencyHardSoft)) {
+                        notification = new ServicePathRpcResultBuilder()
+                                .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
+                                .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Pending)
+                                .setStatusMessage("Service compliant, submitting pathComputation Request ...").build();
+                        try {
+                            notificationPublishService.putNotification(notification);
+                        } catch (InterruptedException e) {
+                            LOG.info("notification offer rejected : " + e);
+                        }
+                        sendingPCE = new SendingPceRPCs(input,db,executor);
+                        FutureCallback<Boolean> pceCallback = new FutureCallback<Boolean>() {
+                            String message = "";
+                            ServicePathRpcResult notification = null;
 
-        compliancyCheck = new CompliancyCheck(input);
-        if (!compliancyCheck.check()) {
-            configurationResponseCommon
-                .setAckFinalIndicator("Yes")
-                .setRequestId(input.getServiceHandlerHeader().getRequestId())
-                .setResponseCode("Path not calculated")
-                .setResponseMessage(compliancyCheck.getMessage());
+                            @Override
+                            public void onFailure(Throwable arg0) {
+                                LOG.error("Failure message : " + arg0.toString());
+                                LOG.error("Path calculation failed !");
+                                notification = new ServicePathRpcResultBuilder()
+                                        .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
+                                        .setStatusMessage("PCR Request failed  : " + arg0.getMessage()).build();
+                                try {
+                                    notificationPublishService.putNotification(notification);
+                                } catch (InterruptedException e) {
+                                    LOG.info("notification offer rejected : " + e);
+                                }
+                            }
 
-            output
-                .setConfigurationResponseCommon(configurationResponseCommon.build())
-                .setResponseParameters(null);
+                            @Override
+                            public void onSuccess(Boolean response) {
+                                LOG.info("response : " + response);
+                                if (response) {
+                                    message = "Path Computated !";
+                                    ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder()
+                                            .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
+                                            .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Successful)
+                                            .setStatusMessage(message);
+                                    pathDescriptionBuilder = sendingPCE.getPathDescription();
+                                    if (pathDescriptionBuilder != null) {
+                                        PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org
+                                                .transportpce.b.c._interface.servicepath.rev170426.service.path
+                                                .rpc.result.PathDescriptionBuilder()
+                                                .setAToZDirection(pathDescriptionBuilder.getAToZDirection())
+                                                .setZToADirection(pathDescriptionBuilder.getZToADirection())
+                                                .build();
+                                        tmp.setPathDescription(pathDescription);
+                                    }
+                                    notification = tmp.build();
+                                } else {
+                                    message = sendingPCE.getError();
+                                    notification = new ServicePathRpcResultBuilder()
+                                            .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
+                                            .setServiceName("")
+                                            .setStatus(RpcStatusEx.Failed).setStatusMessage(message)
+                                            .build();
+                                    message = "Path not calculated!";
+                                }
+                                try {
+                                    notificationPublishService.putNotification(notification);
+                                } catch (InterruptedException e) {
+                                    LOG.info("notification offer rejected : " + e);
+                                }
+                                LOG.info(message);
+                            }
+                        };
+                        ListenableFuture<Boolean> pce = sendingPCE.pathComputation();
+                        Futures.addCallback(pce, pceCallback, executor);
+                        LOG.info("PathComputation Request in progress ...");
+                        configurationResponseCommon = new ConfigurationResponseCommonBuilder()
+                                .setAckFinalIndicator("No")
+                                .setRequestId(input.getServiceHandlerHeader().getRequestId())
+                                .setResponseMessage("Service compliant, Path calculating in progress...")
+                                .setResponseCode("200");
 
-            return RpcResultBuilder.success(output.build()).buildFuture();
-        }
-        notification = new ServicePathRpcResultBuilder()
-            .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
-            .setServiceName(input.getServiceName())
-            .setStatus(RpcStatusEx.Pending)
-            .setStatusMessage("Service compliant, submitting pathComputation Request ...")
-            .build();
-        try {
-            notificationPublishService.putNotification(notification);
-        } catch (InterruptedException e) {
-            LOG.info("notification offer rejected : " + e);
-        }
+                        PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder()
+                                .setConfigurationResponseCommon(configurationResponseCommon.build());
+                        return RpcResultBuilder.success(output.build()).buildFuture();
+                    }
 
-        SendingPceRPCs sendingPCE = new SendingPceRPCs();
-        sendingPCE.pathComputation();
-        if (sendingPCE.getSuccess()) {
-            message = "Path Computated !";
-            ServicePathRpcResultBuilder tmp = new ServicePathRpcResultBuilder()
-                .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
-                .setServiceName(input.getServiceName())
-                .setStatus(RpcStatusEx.Successful)
-                .setStatusMessage(message);
-            PathDescriptionBuilder path = sendingPCE.getPathDescription();
-            if (path != null) {
-                PathDescription pathDescription = new org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce
-                        .stubpce.rev170426.service.path.rpc.result.PathDescriptionBuilder()
-                    .setAToZDirection(path.getAToZDirection())
-                    .setZToADirection(path.getZToADirection())
-                    .build();
-                tmp.setPathDescription(pathDescription);
+                } else {
+                    message = txrxCheck.getMessage();
+                    responseCode = "500";
+                }
+            } else {
+                message = txrxCheck.getMessage();
+                responseCode = "500";
             }
-            notification = tmp.build();
+        } else {
+            message = compliancyCheck.getMessage();
+            responseCode = "500";
+            notification = new ServicePathRpcResultBuilder()
+                    .setNotificationType(ServicePathNotificationTypes.PathComputationRequest)
+                    .setServiceName(input.getServiceName()).setStatus(RpcStatusEx.Failed)
+                    .setStatusMessage("Service not compliant : " + message).build();
             try {
                 notificationPublishService.putNotification(notification);
             } catch (InterruptedException e) {
                 LOG.info("notification offer rejected : " + e);
             }
-        } else {
-            message = "Path Computating failed !";
         }
-        LOG.info(message);
-        configurationResponseCommon
-            .setAckFinalIndicator("Yes")
-            .setRequestId(input.getServiceHandlerHeader().getRequestId())
-            .setResponseCode("200")
-            .setResponseMessage(message);
-
-        output
-            .setConfigurationResponseCommon(configurationResponseCommon.build());
+        configurationResponseCommon = new ConfigurationResponseCommonBuilder();
+        configurationResponseCommon.setAckFinalIndicator("Yes")
+        .setRequestId(input.getServiceHandlerHeader().getRequestId())
+        .setResponseMessage(message)
+        .setResponseCode(responseCode).build();
+        PathComputationRequestOutputBuilder output = new PathComputationRequestOutputBuilder();
+        output.setConfigurationResponseCommon(configurationResponseCommon.build());
         return RpcResultBuilder.success(output.build()).buildFuture();
 
     }
+
+    /**
+     * Initialize PathDescriptionList Structure on DataStore.
+     *
+     * @param DataBroker
+     *            Access DataStore
+     */
+    private boolean initializePathDescriptionList(DataBroker db) {
+        Boolean result = true;
+        LOG.info("Preparing to initialize the PathDescription List");
+        WriteTransaction transaction = db.newWriteOnlyTransaction();
+        InstanceIdentifier<PathDescriptionList> iid = InstanceIdentifier.create(PathDescriptionList.class);
+        PathDescriptionList pathDescriptionList = new PathDescriptionListBuilder().build();
+        transaction.put(LogicalDatastoreType.OPERATIONAL, iid, pathDescriptionList);
+        Future<Void> future = transaction.submit();
+        try {
+            Futures.getChecked(future, ExecutionException.class);
+        } catch (ExecutionException e) {
+            LOG.error("Failed to create PathDescription List");
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     * Initialize ServicePathList Structure on DataStore.
+     *
+     * @param DataBroker
+     *            Access DataStore
+     * @return <code>true</code> if ok, <code>false</code> else
+     */
+    private boolean initializeServicePathList(DataBroker db) {
+        Boolean result = true;
+        LOG.info("Preparing to initialize the ServicePathList registry");
+        WriteTransaction transaction = db.newWriteOnlyTransaction();
+        InstanceIdentifier<ServicePathList> iid = InstanceIdentifier.create(ServicePathList.class);
+        ServicePathList servicePathList = new ServicePathListBuilder().build();
+        transaction.put(LogicalDatastoreType.OPERATIONAL, iid, servicePathList);
+        Future<Void> future = transaction.submit();
+        try {
+            Futures.getChecked(future, ExecutionException.class);
+        } catch (ExecutionException e) {
+            LOG.error("Failed to create ServicePathList List : " + e.toString());
+            result = false;
+        }
+        return result;
+    }
+
+    /**
+     * fill PathDescriptionList
+     * with direct paths and
+     * indirect paths.
+     */
+    private void fillPathDesciptionList() {
+        LOG.info("filling PathDescription List...");
+        Topology topo = new Topology();
+        topo.start();
+        LOG.info("Network : " + topo.getNetwork());
+        SuperNodePath superNodePath = new SuperNodePath(topo.getNetwork());
+        String aend = "NodeA";
+        String zend = "NodeZ";
+        superNodePath.run(aend, zend);
+        fill(superNodePath.getDirectPathDesc(aend, zend, superNodePath.getPaths()));
+        fill(superNodePath.getIndirectPathDesc(aend, zend, superNodePath.getPaths()));
+    }
+
+    /**
+     * fill datastore with
+     * Pathdescriptions List.
+     *
+     * @param sortedSet PathDescriptionsOrdered List
+     */
+    private void fill(SortedSet<PathDescriptionsOrdered> sortedSet) {
+        InstanceIdentifier<PathDescriptions> iid;
+        WriteTransaction writeTx;
+        Future<Void> future;
+        if (!sortedSet.isEmpty()) {
+            Iterator<PathDescriptionsOrdered> it = sortedSet.iterator();
+            while (it.hasNext()) {
+                PathDescriptions pathDesc = it.next().getPathDescriptions();
+                if (pathDesc != null) {
+                    iid = InstanceIdentifier.create(PathDescriptionList.class)
+                            .child(PathDescriptions.class, new PathDescriptionsKey(pathDesc.getPathName()));
+                    writeTx = db.newWriteOnlyTransaction();
+                    writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, pathDesc);
+                    future = writeTx.submit();
+                    try {
+                        Futures.getChecked(future, ExecutionException.class);
+                    } catch (ExecutionException e) {
+                        LOG.error("Failed to write PathDescriptions to PathDescriptionsList : " + e.toString());
+                    }
+                } else {
+                    LOG.error("PathDescriptions gets is null !");
+                }
+            }
+        } else {
+            LOG.info("PathDescriptions List is empty !");
+        }
+    }
+
+    /**
+     * read Service from ServiceList DataStore.
+     *
+     * @param serviceName
+     *            Name of Service
+     *
+     * @return <code>Services</code>
+     */
+    @SuppressWarnings("unused")
+    private Services readServiceList(String serviceName) {
+        Services result = null;
+        ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
+        InstanceIdentifier<Services> iid = InstanceIdentifier.create(ServiceList.class).child(Services.class,
+                new ServicesKey(serviceName));
+        Future<Optional<Services>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
+        Optional<Services> optional = Optional.absent();
+        try {
+            optional = Futures.getChecked(future, ExecutionException.class);
+        } catch (ExecutionException e) {
+            LOG.error("Reading service failed:", e);
+        }
+        if (optional.isPresent()) {
+            LOG.debug("Service '" + serviceName + "' present !");
+            result = new ServicesBuilder(optional.get()).build();
+        }
+        return result;
+    }
+
+    /**
+     * read ServicePath Service from ServicePathList DataStore.
+     *
+     * @param serviceName
+     *            Name of ServicePath
+     *
+     * @return <code>Services</code>
+     */
+    @SuppressWarnings("unused")
+    private ServicePaths readServicePathList(String serviceName) {
+        ServicePaths result = null;
+        ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
+        InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
+                .child(ServicePaths.class, new ServicePathsKey(serviceName));
+        Future<Optional<ServicePaths>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
+        Optional<ServicePaths> optional = Optional.absent();
+        try {
+            optional = Futures.getChecked(future, ExecutionException.class);
+        } catch (ExecutionException e) {
+            LOG.error("Reading service failed:", e);
+        }
+        if (optional.isPresent()) {
+            LOG.debug("Service '" + serviceName + "' present !");
+            result = new ServicePathsBuilder(optional.get()).build();
+        }
+        return result;
+    }
+
+    /**
+     * read PathDescription information from PathDescriptionList.
+     *
+     * @param pathName
+     *            Name of PathDescription
+     *
+     * @return <code>PathDescriptions</code>
+     */
+    @SuppressWarnings("unused")
+    private PathDescriptions readPathDescriptionList(String pathName) {
+        PathDescriptions result = null;
+        ReadOnlyTransaction readTx = db.newReadOnlyTransaction();
+        InstanceIdentifier<PathDescriptions> iid = InstanceIdentifier.create(PathDescriptionList.class)
+                .child(PathDescriptions.class, new PathDescriptionsKey(pathName));
+        Future<Optional<PathDescriptions>> future = readTx.read(LogicalDatastoreType.OPERATIONAL,iid);
+        Optional<PathDescriptions> optional = Optional.absent();
+        try {
+            optional = Futures.getChecked(future, ExecutionException.class);
+        } catch (ExecutionException e) {
+            LOG.error("Reading service failed:", e);
+        }
+        if (optional.isPresent()) {
+            LOG.debug("PathDescritions '" + pathName + "' present !");
+            result = new PathDescriptionsBuilder(optional.get()).build();
+        }
+        return result;
+    }
+
+    /**
+     * register ServicePath Service to ServicePathList with PathDescription
+     * information.
+     *
+     * @param input
+     *            PathComputationRequestInput
+     * @return String operations result, null if ok or not otherwise
+     */
+    @SuppressWarnings("unused")
+    private String writeServicePathList(PathComputationRequestInput input) {
+        String serviceName = input.getServiceName();
+        LOG.debug("Write ServicePath '" + serviceName + "' Service");
+        String result = null;
+        LOG.debug("Writing '" + serviceName + "' ServicePath");
+        InstanceIdentifier<ServicePaths> iid = InstanceIdentifier.create(ServicePathList.class)
+                .child(ServicePaths.class, new ServicePathsKey(serviceName));
+
+        org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev170426.service
+            .path.PathDescriptionBuilder path = new org.opendaylight.yang.gen.v1.http.org.transportpce
+            .b.c._interface.service.types.rev170426.service.path.PathDescriptionBuilder();
+        path.setAToZDirection(pathDescriptionBuilder.getAToZDirection());
+        path.setZToADirection(pathDescriptionBuilder.getZToADirection());
+        ServicePaths service = new ServicePathsBuilder().setServicePathName(input.getServiceName())
+                .setSoftConstraints(input.getSoftConstraints()).setHardConstraints(input.getHardConstraints())
+                .setPathDescription(path.build()).build();
+        WriteTransaction writeTx = db.newWriteOnlyTransaction();
+        writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, service);
+        Future<Void> future = writeTx.submit();
+        try {
+            Futures.getChecked(future, ExecutionException.class);
+            result = null;
+        } catch (ExecutionException e) {
+            LOG.error("Failed to write service to Service List");
+            result = "Failed to write service to Service List";
+        }
+        return result;
+    }
+
+    public PathDescriptionBuilder getPathDescriptionBuilder() {
+        return pathDescriptionBuilder;
+    }
+
+    public void setPathDescriptionBuilder(PathDescriptionBuilder pathDescriptionBuilder) {
+        this.pathDescriptionBuilder = pathDescriptionBuilder;
+    }
+
+    @Override
+    public Future<RpcResult<ServiceImplementationRequestOutput>> serviceImplementationRequest(
+            ServiceImplementationRequestInput input) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<ServiceDeleteOutput>> serviceDelete(ServiceDeleteInput input) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
index 0b1fe228e37c8800f4b92382d6016ae44dfb9911..9ef48f373e07f5a400802d18da6f7c30d6729242 100644 (file)
@@ -9,12 +9,13 @@
 
 package org.opendaylight.transportpce.stubpce.impl;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceListener;
-import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.stubpce.rev170426.StubpceService;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathListener;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.TransportpceServicepathService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,23 +23,24 @@ import org.slf4j.LoggerFactory;
 /**
  * Class to register
  * Stubpce Service and Notification.
- * @author Martial Coulibaly ( martial.coulibaly@gfi.com ) on behalf of Orange
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on behalf of Orange
  *
  */
 public class StubpceProvider {
     private static final Logger LOG = LoggerFactory.getLogger(StubpceProvider.class);
     private final RpcProviderRegistry rpcRegistry;
     private final NotificationPublishService notificationPublishService;
+    private final DataBroker dataBroker;
 
 
-    private BindingAwareBroker.RpcRegistration<StubpceService> rpcRegistration;
-    private ListenerRegistration<StubpceListener> stubPcelistenerRegistration;
+    private BindingAwareBroker.RpcRegistration<TransportpceServicepathService> rpcRegistration;
+    private ListenerRegistration<TransportpceServicepathListener> stubPcelistenerRegistration;
 
-    public StubpceProvider(RpcProviderRegistry rpcProviderRegistry,
-        NotificationService notificationService,
-        NotificationPublishService notificationPublishService) {
+    public StubpceProvider(RpcProviderRegistry rpcProviderRegistry,final DataBroker dataBroker,
+            NotificationService notificationService, NotificationPublishService notificationPublishService) {
         this.rpcRegistry = rpcProviderRegistry;
         this.notificationPublishService = notificationPublishService;
+        this.dataBroker = dataBroker;
     }
 
     /**
@@ -46,8 +48,8 @@ public class StubpceProvider {
      */
     public void init() {
         LOG.info("StubpceProvider Session Initiated");
-        final StubpceImpl consumer = new StubpceImpl(notificationPublishService);
-        rpcRegistration = rpcRegistry.addRpcImplementation(StubpceService.class, consumer);
+        final StubpceImpl consumer = new StubpceImpl(notificationPublishService,dataBroker);
+        rpcRegistration = rpcRegistry.addRpcImplementation(TransportpceServicepathService.class, consumer);
     }
 
     /**
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/InterNodePath.java
new file mode 100644 (file)
index 0000000..b1bd423
--- /dev/null
@@ -0,0 +1,554 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.opendaylight.transportpce.stubpce.TpNodeTp;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * class to build all path between superNode elements
+ * ( XPDR and ROADM).
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+
+public class InterNodePath {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(InterNodePath.class);
+    private SuperNode superNode;
+    private List<NodePath> nodepaths;
+    private List<AToZDirection> atoz;
+    private List<ZToADirection> ztoa;
+
+    /**
+     * InterNodePath constructor.
+     *
+     * @param supernode Supernode
+     */
+    public InterNodePath(SuperNode supernode) {
+        setSuperNode(supernode);
+        setNodepaths(new ArrayList<NodePath>());
+        setAtoz(new ArrayList<AToZDirection>());
+        setZtoa(new ArrayList<ZToADirection>());
+    }
+
+    /**
+     * build AToZdirection.
+     *
+     * @param paths <code>Path</code> List
+     */
+    private void getAToZDirection(List<Path> paths) {
+        int order = 0;
+        AToZDirectionBuilder atozDirection = new AToZDirectionBuilder();
+        List<AToZ> atozList = new ArrayList<AToZ>();
+        TpNodeTp tpNodeTp;
+        for (Path path : paths) {
+            tpNodeTp = path.getTpNodeTp();
+            tpNodeTp.createAToZListHop(order);
+            for (AToZ atoz : tpNodeTp.getAToZ()) {
+                atozList.add(atoz);
+                order++;
+            }
+            Link link = path.getLink();
+            AToZKey atozKey = new AToZKey(Integer.toString(order));
+            Resource resource = new ResourceBuilder().setResource(link).build();
+            AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey).setResource(resource).build();
+            atozList.add(hop);
+            order++;
+        }
+        atozDirection.setRate((long) 100).setAToZWavelengthNumber((long) 200).setAToZ(atozList);
+        atoz.add(atozDirection.build());
+    }
+
+    /**
+     * build ZToAdirection.
+     *
+     * @param paths <code>Path</code> List
+     */
+    private void getZToADirection(List<Path> paths) {
+        int order = 0;
+        ZToADirectionBuilder ztoaDirection = new ZToADirectionBuilder();
+        List<ZToA> ztoaList = new ArrayList<ZToA>();
+        TpNodeTp tpNodeTp;
+        for (Path path : paths) {
+            tpNodeTp = path.getTpNodeTp();
+            tpNodeTp.createZToAListHop(order);
+            for (ZToA ztoa : tpNodeTp.getZToA()) {
+                ztoaList.add(ztoa);
+                order++;
+            }
+            Link link = path.getLink();
+            ZToAKey ztoaKey = new ZToAKey(Integer.toString(order));
+            Resource resource = new ResourceBuilder().setResource(link).build();
+            ZToA hop = new ZToABuilder().setId(ztoaKey.getId()).setKey(ztoaKey).setResource(resource).build();
+            ztoaList.add(hop);
+            order++;
+        }
+        ztoaDirection.setRate((long) 100).setZToAWavelengthNumber((long) 200).setZToA(ztoaList);
+        ztoa.add(ztoaDirection.build());
+    }
+
+    /**
+     * Build direction path
+     * for all Supernode elements.
+     *
+     * @param skip Boolean to specify an ROADM without XPDR
+     * @param nodeId Supernode element nodeId
+     * @param zend Supernode path ZEnd nodeId
+     */
+    public void build(Boolean skip, String nodeId,String zend) {
+        LOG.info("Building direction ...");
+        if (skip) {
+            buildDegToDeg(false);
+            buildDegToDeg(true);
+        } else {
+            boolean reverse = false;
+            if (nodeId.contains(zend)) {
+                reverse = true;
+            }
+            NodePath xpdr = null;
+            NodePath srg = null;
+            NodePath deg1 = null;
+            NodePath deg2 = null;
+            for (NodePath node : nodepaths) {
+                //LOG.info(node.toString());
+                String id = node.getNodeId();
+                if (id.contains("XPDR")) {
+                    xpdr = node;
+                }
+                if (id.contains("SRG")) {
+                    srg = node;
+                }
+                if (id.contains("DEG1")) {
+                    deg1 = node;
+                }
+                if (id.contains("DEG2")) {
+                    deg2 = node;
+                }
+            }
+            buildXpdrToSrgToDeg(xpdr,srg,deg1,deg2,reverse);
+            buildDegToSrgToXpdr(xpdr,srg,deg1,deg2,reverse);
+        }
+    }
+
+    /**
+     * build direction path for
+     * Supernode element DEG1, DEG2.
+     *
+     * @param twotoOne boolean to determine direction
+     */
+    private void buildDegToDeg(boolean twotoOne) {
+        LOG.info("buildDegToDeg ...");
+        NodePath deg1 = null;
+        NodePath deg2 = null;
+        for (NodePath node : nodepaths) {
+            //LOG.info(node.toString());
+            String nodeId = node.getNodeId();
+            if (nodeId.contains("DEG1")) {
+                deg1 = node;
+            }
+            if (nodeId.contains("DEG2")) {
+                deg2 = node;
+            }
+        }
+        if (deg1 != null && deg2 != null) {
+            List<Path> result =  new ArrayList<Path>();
+            NodePath deb = deg1;
+            NodePath end = deg2;
+            if (twotoOne) {
+                deb = deg2;
+                end = deg1;
+            }
+            for (Path deg1Path : deb.getPath()) {
+                TpNodeTp tmpdeg = deg1Path.getTpNodeTp();
+                if (tmpdeg.getTpIn().getTpId().contains("TTP")) {
+                    result.clear();
+                    result.addAll(Lists.newArrayList(deg1Path));
+                    if (!twotoOne) {
+                        getAToZDirection(result);
+                    } else {
+                        getZToADirection(result);
+                    }
+                }
+            }
+            for (Path deg2Path : end.getPath()) {
+                TpNodeTp tmpdeg = deg2Path.getTpNodeTp();
+                if (tmpdeg.getTpIn().getTpId().contains("CTP")) {
+                    result.clear();
+                    result.addAll(Lists.newArrayList(deg2Path));
+                    if (!twotoOne) {
+                        getAToZDirection(result);
+                    } else {
+                        getZToADirection(result);
+                    }
+                }
+            }
+        } else {
+            LOG.info("deg1 or/and deg2 is null !");
+        }
+    }
+
+    /**
+     build direction from
+     *Degree  to SRG to XPDR
+     *in Supernode elements.
+     *
+     *@param xpdr NodePath XPDR
+     *@param srg NodePath SRG
+     *@param deg NodePath Degree
+     *@param reverse boolean to determine the direction
+     */
+    private void buildDeg(NodePath xpdr,NodePath srg,NodePath deg, Boolean reverse) {
+        List<Path> result =  new ArrayList<Path>();
+        for (Path degPath : deg.getPath()) {
+            TpNodeTp tmpdeg = degPath.getTpNodeTp();
+            if (tmpdeg.getTpIn().getTpId().contains("TTP")) {
+                for (Path srgPath : srg.getPath()) {
+                    TpNodeTp tmpsrg = srgPath.getTpNodeTp();
+                    if (tmpsrg.getTpIn().getTpId().contains("CP")) {
+                        for (Path xpdrPath : xpdr.getPath()) {
+                            TpNodeTp tmpxpdr = xpdrPath.getTpNodeTp();
+                            if (tmpxpdr.getTpIn().getTpId().contains("NETWORK")) {
+                                result.clear();
+                                result.addAll(Lists.newArrayList(degPath,srgPath,xpdrPath));
+                                if (reverse) {
+                                    getAToZDirection(result);
+                                } else {
+                                    getZToADirection(result);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     *build direction from
+     *DEG1 / DEG2  to SRG to XPDR
+     *in Supernode elements.
+     *
+     *@param xpdr NodePath XPDR
+     *@param srg NodePath SRG
+     *@param deg1 NodePath Degree 1
+     *@param deg2 NodePath Degree 2
+     *@param reverse boolean to determine the direction
+     */
+    private void buildDegToSrgToXpdr(NodePath xpdr,NodePath srg,NodePath deg1,NodePath deg2,boolean reverse) {
+        LOG.info("buildDegToSrgToXpr ...");
+        if (xpdr != null && srg != null && deg1 != null && deg2 != null) {
+            buildDeg(xpdr, srg, deg1, reverse);
+            buildDeg(xpdr, srg, deg2, reverse);
+        } else {
+            LOG.info("xpdr, deg or/and srg is null !");
+        }
+    }
+
+    /**
+     *build direction from
+     *XPDR to SRG to DEG
+     *in Supernode elements.
+     *
+     *@param xpdr NodePath XPDR
+     *@param srg NodePath SRG
+     *@param deg1 NodePath Degree 1
+     *@param deg2 NodePath Degree 2
+     *@param reverse boolean to determine the direction
+     */
+    private void buildXpdrToSrgToDeg(NodePath xpdr,NodePath srg,NodePath deg1,NodePath deg2,boolean reverse) {
+        LOG.info("buildXpdrToSrgToDeg ...");
+        if (xpdr != null && srg != null && deg1 != null && deg2 != null) {
+            List<Path> result =  new ArrayList<Path>();
+            for (Path xpdrPath : xpdr.getPath()) {
+                TpNodeTp tmpxpdr = xpdrPath.getTpNodeTp();
+                if (tmpxpdr.getTpIn().getTpId().contains("CLIENT")) {
+                    for (Path srgPath : srg.getPath()) {
+                        TpNodeTp tmp = srgPath.getTpNodeTp();
+                        Link srglink = srgPath.getLink();
+                        if (tmp.getTpIn().getTpId().contains("PP")) {
+                            for (Path deg1Path : deg1.getPath()) {
+                                TpNodeTp tmpdeg = deg1Path.getTpNodeTp();
+                                if (tmpdeg.getTpIn().getTpId().contains("CTP")
+                                        && srglink.getLinkId().contains("DEG1")) {
+                                    result.clear();
+                                    result.addAll(Lists.newArrayList(xpdrPath,srgPath,deg1Path));
+                                    if (reverse) {
+                                        getZToADirection(result);
+                                    } else {
+                                        getAToZDirection(result);
+                                    }
+                                }
+                            }
+                            for (Path deg2Path : deg2.getPath()) {
+                                TpNodeTp tmpdeg = deg2Path.getTpNodeTp();
+                                if (tmpdeg.getTpIn().getTpId().contains("CTP")
+                                        && srglink.getLinkId().contains("DEG2")) {
+                                    result.clear();
+                                    result.addAll(Lists.newArrayList(xpdrPath,srgPath,deg2Path));
+                                    if (reverse) {
+                                        getZToADirection(result);
+                                    } else {
+                                        getAToZDirection(result);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            LOG.info("xpdr, deg or/and srg is null !");
+        }
+    }
+
+    /**
+     * get all AToZdirection containing
+     * a list of <code>AToZ</code> end by
+     * a String.
+     *
+     * @param endBy String
+     * @param atozDirection AToZdirection List
+     * @param index Integer to determine if it for last Link(1) or last TerminationPoint(2)
+     * @return <code>AToZDirection</code> List
+     */
+    public List<AToZDirection> getAToZDirectionEndBy(String endBy, List<AToZDirection> atozDirection, int index) {
+        List<AToZDirection> result = new ArrayList<AToZDirection>();
+        for (AToZDirection tmp : atozDirection) {
+            List<AToZ> atozList = tmp.getAToZ();
+            int size = atozList.size();
+            if (size > 2) {
+                String id = Integer.toString(size - index);
+                org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
+                    .rev170426.pce.resource.resource.Resource res = null;
+                for (AToZ atoz : atozList) {
+                    if (atoz.getId().compareTo(id) == 0) {
+                        res = atoz.getResource().getResource();
+                        if (res != null) {
+
+                            switch (index) {
+                                case 1: //last link
+                                    if (res instanceof Link) {
+                                        Link tp = (Link) res;
+                                        if (tp != null && tp.getLinkId().contains(endBy)) {
+                                            result.add(tmp);
+                                        }
+                                    }
+                                    break;
+
+                                case 2: //last tp
+                                    if (res instanceof TerminationPoint) {
+                                        TerminationPoint tp = (TerminationPoint) res;
+                                        if (tp != null && tp.getTpId().contains(endBy)) {
+                                            result.add(tmp);
+                                        }
+                                    }
+                                    break;
+
+                                default :
+                                    break;
+                            }
+                        }
+                    }
+                }
+            } else {
+                LOG.info("firstnodeTpId is null !");
+            }
+        }
+        LOG.info("getAToZDirectionEndBy result size : " + result.size() + "\n " + result.toString());
+        return result;
+    }
+
+    /**
+     * replace or remove in
+     * Link in <code>AToZ</code> list
+     * containing in AToZdirection.
+     *
+     * @param endBy String
+     * @param beginBy String
+     * @param atozLink name of ROAMDTOROAMD link
+     * @param atozDirection AToZdirection List
+     * @param remove boolean to determine if removing or not
+     * @return <code>AToZDirection</code> List
+     */
+    public List<AToZDirection> replaceOrRemoveAToZDirectionEndLink(String endBy,String beginBy,String atozLink,
+            List<AToZDirection> atozDirection, boolean remove) {
+        List<AToZDirection> result = new ArrayList<AToZDirection>();
+        List<AToZDirection> tmp = new ArrayList<AToZDirection>();
+        if (remove) {
+            tmp = getAToZDirectionEndBy(endBy, atozDirection, 1);
+            if (!tmp.isEmpty()) {
+                tmp = getAToZDirectionBeginBy(beginBy, tmp);
+            }
+        } else {
+            tmp = getAToZDirectionEndBy(endBy, atozDirection,2);
+        }
+        if (!tmp.isEmpty()) {
+            for (AToZDirection atozdir : tmp) {
+                List<AToZ> atozList = atozdir.getAToZ();
+                int size = atozList.size();
+                if (size > 0) {
+                    String id = Integer.toString(size - 1);
+                    for (ListIterator<AToZ> it = atozList.listIterator(); it.hasNext();) {
+                        AToZ atoz = it.next();
+                        if (atoz.getId().compareTo(id) == 0) {
+                            org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
+                                .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource();
+                            if (res != null  && res instanceof Link) {
+                                Link link = new LinkBuilder()
+                                        .setLinkId(atozLink)
+                                        .build();
+                                AToZKey atozKey = new AToZKey(atoz.getKey());
+                                org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface
+                                    .pathdescription.rev170426.pce.resource.Resource resource = new ResourceBuilder()
+                                    .setResource(link).build();
+                                AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey)
+                                        .setResource(resource).build();
+                                it.remove();
+                                if (!remove) {
+                                    it.add(hop);
+                                }
+                                result.add(atozdir);
+                            }
+                        }
+                    }
+                }
+            }
+        } else {
+            LOG.info("getAToZDirectionEndBy size " + tmp.size());
+        }
+        return result;
+    }
+
+    /**
+     *get all AToZdirection containing
+     * a list of <code>AToZ</code> begin by
+     * a String.
+     *
+     * @param beginBy String
+     * @param atozDirection AToZdirection List
+     * @return <code>AToZDirection</code> List
+     */
+    public List<AToZDirection> getAToZDirectionBeginBy(String beginBy, List<AToZDirection> atozDirection) {
+        List<AToZDirection> result = new ArrayList<AToZDirection>();
+        for (AToZDirection tmp : atozDirection) {
+            List<AToZ> atozList = tmp.getAToZ();
+            int size = atozList.size();
+            if (size > 0) {
+                String id = Integer.toString(0);
+                for (AToZ atoz : atozList) {
+                    if (atoz.getId().compareTo(id) == 0) {
+                        org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
+                            .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource();
+                        if (res != null  && res instanceof TerminationPoint) {
+                            TerminationPoint tp = (TerminationPoint) res;
+                            if (tp != null && tp.getTpId().contains(beginBy)) {
+                                LOG.info("tmp : " + tmp.toString());
+                                result.add(tmp);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        LOG.info("result size : " + result.size());
+        return result;
+    }
+
+    /**
+     * first launch process to
+     * build/fill <code>NodePath</code>
+     * And after that, start building
+     * direction between Supernode
+     * elements.
+     *
+     * @param zend path zend Supernode nodeId
+     */
+    public void buildPath(String zend) {
+        if (superNode != null) {
+            for (org.opendaylight.transportpce.stubpce.topology.Resource res : superNode.getResources()) {
+                NodePath path = new NodePath(res, superNode.getSuperNodeId(), superNode.isXpdrSrgAbsent());
+                path.fill();
+                nodepaths.add(path);
+            }
+            LOG.info("nodepaths size : " + nodepaths.size());
+            build(superNode.isXpdrSrgAbsent(),superNode.getSuperNodeId(), zend);
+        }
+    }
+
+    public static void main(String[] args) {
+        Topology topo = new Topology();
+        topo.start();
+        Network net = topo.getNetwork();
+        if (net != null) {
+            SuperNode res = net.getSuperNodes().get(0);
+            String zend = "NodeZ";
+            LOG.info(res.getSuperNodeId().toString());
+            InterNodePath path = new InterNodePath(res);
+            path.buildPath(zend);
+        }
+    }
+
+    public SuperNode getSuperNode() {
+        return superNode;
+    }
+
+    public void setSuperNode(SuperNode superNode) {
+        this.superNode = superNode;
+    }
+
+    public List<AToZDirection> getAtoz() {
+        return atoz;
+    }
+
+    public void setAtoz(List<AToZDirection> atoz) {
+        this.atoz = atoz;
+    }
+
+    public List<ZToADirection> getZtoa() {
+        return ztoa;
+    }
+
+    public void setZtoa(List<ZToADirection> ztoa) {
+        this.ztoa = ztoa;
+    }
+
+    public List<NodePath> getNodepaths() {
+        return nodepaths;
+    }
+
+    public void setNodepaths(List<NodePath> nodepaths) {
+        this.nodepaths = nodepaths;
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/LogicalConnectionPoint.java
new file mode 100644 (file)
index 0000000..45da247
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+
+/**
+ * class to build Logical
+ * Connection Point.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+@JacksonXmlRootElement(localName = "logical-connection-point")
+public class LogicalConnectionPoint {
+    @JacksonXmlProperty(localName = "tp-id")
+    private String tpId;
+    @JacksonXmlProperty(localName = "node-id")
+    private String nodeId;
+
+    public LogicalConnectionPoint(@JacksonXmlProperty(localName = "tp-id") final String tpId,
+            @JacksonXmlProperty(localName = "node-id") final String nodeId) {
+        this.setTpId(tpId);
+        this.setNodeId(nodeId);
+    }
+
+    public String getTpId() {
+        return tpId;
+    }
+
+    public void setTpId(String tpId) {
+        this.tpId = tpId;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @Override
+    public String toString() {
+        java.lang.String name = "[";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (tpId != null) {
+            builder.append("tpId=");
+            builder.append(tpId);
+            builder.append(", ");
+        }
+        if (nodeId != null) {
+            builder.append("nodeId=");
+            builder.append(nodeId);
+        }
+        return builder.append(']').toString();
+
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Network.java
new file mode 100644 (file)
index 0000000..1849cba
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import java.util.List;
+
+/**
+ * Class to create topology
+ * structure according to the idea of
+ * SuperNode.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+@JacksonXmlRootElement(localName = "network")
+public class Network {
+    /** SuperNode List.*/
+    @JacksonXmlElementWrapper(localName = "super-nodes")
+    @JacksonXmlProperty(localName = "super-node")
+    private List<SuperNode> superNodes;
+    /** Links between Supernodes. */
+    @JacksonXmlProperty(localName = "roadm-to-roadm")
+    private RoadmToRoadm roadmToroadm;
+
+    /**
+     * Network constructor.
+     *
+     * @param nodes Supernode list
+     * @param links roadmtoroadm links
+     */
+    public Network(
+            @JacksonXmlProperty(localName = "Nsupernode") final List<SuperNode> nodes,
+            @JacksonXmlProperty(localName = "roadm-to-roadm") final RoadmToRoadm links) {
+        setSuperNodes(nodes);
+        setRoadmToroadm(links);
+    }
+
+    public List<SuperNode> getSuperNodes() {
+        return superNodes;
+    }
+
+    public void setSuperNodes(List<SuperNode> superNodes) {
+        this.superNodes = superNodes;
+    }
+
+
+    public RoadmToRoadm getRoadmToroadm() {
+        return roadmToroadm;
+    }
+
+    public void setRoadmToroadm(RoadmToRoadm roadmToroadm) {
+        this.roadmToroadm = roadmToroadm;
+    }
+
+    @Override
+    public String toString() {
+        int index;
+        int size;
+        java.lang.String name = "Network [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        index = 0;
+        size = superNodes.size();
+        builder.append("SuperNodes [");
+        if (size > 0) {
+            for (SuperNode tmp : superNodes) {
+                builder.append(tmp.toString());
+                index++;
+                if (index < size) {
+                    builder.append(", ");
+                }
+            }
+        }
+        builder.append("]");
+        if (roadmToroadm != null) {
+            builder.append(", roadmToroadm=");
+            builder.append(roadmToroadm.toString());
+        }
+        return builder.append(']').toString();
+
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodeLinkNode.java
new file mode 100644 (file)
index 0000000..07faa03
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import java.util.List;
+
+/**
+ * Class to create structure
+ * NodeToLinkToNode.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class NodeLinkNode {
+    /** aend first endpoint. */
+    private String aend;
+    /** zend second endpoint. */
+    private String zend;
+    /** atoz link. */
+    private List<String> atozLink;
+    /** ztoa link. */
+    private List<String> ztoaLink;
+    /** direct boolean to specify direct path. */
+    private Boolean direct;
+
+    /**
+     * NodeLinkNode Constructor.
+     *
+     * @param aend first endpoint
+     * @param zend second endpoint
+     * @param link1 atoz link
+     * @param link2 ztoa link
+     * @param direct boolean to specify direct path
+     */
+    public NodeLinkNode(String aend, String zend, List<String> link1, List<String> link2,Boolean direct) {
+        setAend(aend);
+        setZend(zend);
+        setAtozLink(link1);
+        setZtoaLink(link2);
+        setDirect(direct);
+    }
+
+    public Boolean getDirect() {
+        return direct;
+    }
+
+    public void setDirect(Boolean direct) {
+        this.direct = direct;
+    }
+
+    public String getAend() {
+        return aend;
+    }
+
+    public void setAend(String aend) {
+        this.aend = aend;
+    }
+
+    public String getZend() {
+        return zend;
+    }
+
+    public void setZend(String zend) {
+        this.zend = zend;
+    }
+
+    @Override
+    public String toString() {
+        java.lang.String name = "NodeLinkNode [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (aend != null) {
+            builder.append("aend=");
+            builder.append(aend);
+            builder.append(", ");
+        }
+        if (atozLink != null) {
+            builder.append("atozLink=");
+            builder.append(atozLink);
+            builder.append(", ");
+        }
+        if (ztoaLink != null) {
+            builder.append("ztoaLink=");
+            builder.append(ztoaLink);
+            builder.append(", ");
+        }
+        if (zend != null) {
+            builder.append("zend=");
+            builder.append(zend);
+            builder.append(", ");
+        }
+        builder.append(", direct=");
+        builder.append(direct);
+        return builder.append(']').toString();
+    }
+
+    public List<String> getAtozLink() {
+        return atozLink;
+    }
+
+    public void setAtozLink(List<String> atozLink) {
+        this.atozLink = atozLink;
+    }
+
+    public List<String> getZtoaLink() {
+        return ztoaLink;
+    }
+
+    public void setZtoaLink(List<String> ztoaLink) {
+        this.ztoaLink = ztoaLink;
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/NodePath.java
new file mode 100644 (file)
index 0000000..634c279
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.transportpce.stubpce.TpNodeTp;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Node;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.NodeBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.TerminationPointBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * build all path with one resource
+ * from Supernode.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class NodePath {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(NodePath.class);
+    /** element of Supernode. */
+    private org.opendaylight.transportpce.stubpce.topology.Resource resource;
+    /** <code>TpNodeTp</code> list. */
+    private List<TpNodeTp> tpNodeTps;
+    /** <code>Link</code> list. */
+    private List<Link> links;
+    /** SuperNode element nodeId. */
+    private String nodeId;
+    /** Supernode Id. */
+    private String superNodeId;
+    /** boolean to determine if Supernode contains an XPDR. */
+    private boolean isXpdrSrgAbsent;
+    /** Path List. */
+    private List<Path> path;
+
+    /**
+     *NodePath constructor.
+     *
+     * @param res element of Supernode
+     * @param superNodeId supernode Id
+     * @param isXpdrSrgAbsent boolean to determine if Supernode contains an XPDR
+     */
+    public NodePath(org.opendaylight.transportpce.stubpce.topology.Resource res,
+            String superNodeId, boolean isXpdrSrgAbsent) {
+        setResource(res);
+        setNodeId(res.getNodeId());
+        setSuperNodeId(superNodeId);
+        setXpdrSrgAbsent(isXpdrSrgAbsent);
+        setLinks(new ArrayList<Link>());
+        setTpNodeTps(new ArrayList<TpNodeTp>());
+        setPath(new ArrayList<Path>());
+    }
+
+    @Override
+    public String toString() {
+        java.lang.String name = "NodePath [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (nodeId != null) {
+            builder.append("nodeId= ");
+            builder.append(nodeId);
+            builder.append(", ");
+        }
+        if (path.size() > 0) {
+            builder.append("Paths [");
+            builder.append(path.toString());
+            builder.append(" ]");
+        }
+        return builder.append(']').toString();
+    }
+
+    /**
+     *get all resources (links,
+     *logicalConnectionpoints, nodeId)
+     *from Supernode element.
+     */
+    public void fill() {
+        Boolean xpdr = false;
+        if (resource != null) {
+            String nodeid = resource.getNodeId();
+            List<String> resLinks = resource.getLinks();
+            List<LogicalConnectionPoint> resLcps = resource.getLcps();
+            for (String tmp : resLinks) {
+                Link link = new LinkBuilder()
+                        .setLinkId(tmp)
+                        .build();
+                links.add(link);
+            }
+            if (nodeid.contains("XPDR")) {
+                LOG.info("building xpdr resource ...");
+                xpdr = true;
+                buildXpdrTopo(nodeid,resLinks,resLcps,xpdr);
+                links.add(new LinkBuilder()
+                        .setLinkId("TAIL-LINKS")
+                        .build());
+            }
+            if (nodeid.contains("SRG")) {
+                LOG.info("building SRG resource ...");
+                buildSRGTopo(nodeid, resLinks, resLcps);
+            }
+            if (nodeid.contains("DEG")) {
+                LOG.info("building DEG resource ...");
+                xpdr = false;
+                buildXpdrTopo(nodeid,resLinks,resLcps,xpdr);
+                links.add(new LinkBuilder()
+                        .setLinkId("EXTERNAL-LINKS")
+                        .build());
+            }
+        }
+        createDirection();
+    }
+
+    /**
+     * reverse a TpNodeTp
+     * List.
+     *
+     * @return TpNodeTp list
+     */
+    private List<TpNodeTp> reverseTpNodetpList() {
+        List<TpNodeTp> result = new ArrayList<TpNodeTp>();
+        for (TpNodeTp tpNodetp : tpNodeTps) {
+            TpNodeTp tmp = tpNodetp.reverse();
+            result.add(tmp);
+        }
+        return result;
+    }
+
+    /**
+     *create list of Path
+     *(TpNodeTp/Link).
+     */
+    private void createDirection() {
+        /** create direction */
+        LOG.info("creating direction ...");
+        Path resourcePath = null;
+        List<TpNodeTp> direction = new ArrayList<TpNodeTp>();
+        for (Link link : links) {
+            String linkId = link.getLinkId();
+            LOG.info("LinkId : " + linkId);
+            if (!isXpdrSrgAbsent) {
+                if (StringUtils.countMatches(link.getLinkId(), "ROADM") < 2) {
+                    if ((linkId.contains("XPDR") && linkId.startsWith("ROADM"))
+                        || ((linkId.startsWith("DEG") && linkId.contains("SRG")))
+                        || (nodeId.contains("XPDR") && linkId.contains("TAIL-LINKS"))) {
+                        LOG.info("reversing TpNodetp list for link '" + linkId + "'");
+                        direction = reverseTpNodetpList();
+                    } else {
+                        direction = tpNodeTps;
+                    }
+                } else {
+                    LOG.info("link is deg to deg link !");
+                }
+            } else {
+                if (StringUtils.countMatches(link.getLinkId(), "ROADM") == 2) {
+                    direction = reverseTpNodetpList();
+                } else {
+                    direction = tpNodeTps;
+                }
+            }
+            if (tpNodeTps.size() > 0) {
+                for (TpNodeTp tpNodeTp : direction) {
+                    resourcePath = new Path(tpNodeTp, link);
+                    LOG.info(resourcePath.toString());
+                    path.add(resourcePath);
+                }
+            } else {
+                LOG.info("tpNodeTps is empty !");
+            }
+        }
+    }
+
+    /**
+     * build a list of
+     * Termination Point in
+     * XPDR or DEG
+     * ordered in AToZdirection
+     * on a Supernode (XPDR to SRG)
+     * (ROADMA-DEG to ROADMZ-DEG).
+     *
+     * @param xpdr determine if it is an XPDR or not
+     * @param resLcps list of LogicalConnectionPoint
+     * @return String list of TerminationPoints
+     */
+    private List<String> getOrderedTps(boolean xpdr, List<LogicalConnectionPoint> resLcps) {
+        List<String> result = new ArrayList<String>();
+        if (xpdr) {
+            for (LogicalConnectionPoint lcp : resLcps) {
+                String tmp = lcp.getTpId();
+                if (tmp.contains("CLIENT")) {
+                    result.add(0, tmp);
+                } else if (tmp.contains("NETWORK")) {
+                    result.add(1, tmp);
+                }
+            }
+        } else {
+            for (LogicalConnectionPoint lcp : resLcps) {
+                String tmp = lcp.getTpId();
+                if (tmp.contains("CTP")) {
+                    result.add(0, tmp);
+                } else if (tmp.contains("TTP")) {
+                    result.add(1, tmp);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * build TpNodeTp
+     * structure in an
+     * XPDR.
+     *
+     * @param nodeid XPDR Id
+     * @param resLinks list of links
+     * @param resLcps list of LogicalConnectionPoints
+     * @param xpdr determine if it is an XPDR or not
+     */
+    private void buildXpdrTopo(String nodeid, List<String> resLinks, List<LogicalConnectionPoint> resLcps,
+            boolean xpdr) {
+       /** build TpNodetp .*/
+        TerminationPointBuilder in = null;
+        TerminationPointBuilder out = null;
+        List<String> lcps = getOrderedTps(xpdr,resLcps);
+        if (lcps.size() == 2) {
+            in = new TerminationPointBuilder()
+                    .setTpNodeId(nodeid)
+                    .setTpId(lcps.get(0));
+            out = new TerminationPointBuilder()
+                    .setTpNodeId(nodeid)
+                    .setTpId(lcps.get(1));
+        } else {
+            LOG.info("lcps size not equal to 2");
+
+        }
+        Node node = new NodeBuilder()
+                .setNodeId(nodeid)
+                .build();
+        TpNodeTp tmp = new TpNodeTp(in.build(), out.build(), node);
+        tpNodeTps.add(tmp);
+    }
+
+    /**
+     * build TpNodeTp
+     * structure in an
+     * SGR.
+     *
+     * @param nodeid SRG nodeId
+     * @param resLinks list of links
+     * @param resLcps list of LogicalConnectionPoints
+     */
+    private void buildSRGTopo(String nodeid, List<String> resLinks,List<LogicalConnectionPoint> resLcps) {
+        /** build TpNodetp .*/
+        Node node = new NodeBuilder()
+                .setNodeId(nodeid)
+                .build();
+        TerminationPoint out = new TerminationPointBuilder()
+                .setTpNodeId(nodeid)
+                .setTpId("SRG1-CP-TXRX")
+                .build();
+
+        for (LogicalConnectionPoint lcp : resLcps) {
+            if (lcp.getTpId().compareTo("SRG1-CP-TXRX") != 0) {
+                TerminationPoint in = new TerminationPointBuilder()
+                        .setTpNodeId(nodeid)
+                        .setTpId(lcp.getTpId())
+                        .build();
+                tpNodeTps.add(new TpNodeTp(in, out, node));
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        Topology topo = new Topology();
+        topo.start();
+        Network net = topo.getNetwork();
+        if (net != null) {
+            SuperNode superNode = net.getSuperNodes().get(0);
+            LOG.info("SuperNode : " + superNode.getSuperNodeId());
+            for (org.opendaylight.transportpce.stubpce.topology.Resource res :
+                superNode.getResources()) {
+                LOG.info(res.toString());
+                NodePath path = new NodePath(res, superNode.getSuperNodeId(), superNode.isXpdrSrgAbsent());
+                path.fill();
+            }
+        }
+    }
+
+    public org.opendaylight.transportpce.stubpce.topology.Resource getResource() {
+        return resource;
+    }
+
+    public void setResource(org.opendaylight.transportpce.stubpce.topology.Resource resource) {
+        this.resource = resource;
+    }
+
+    public List<TpNodeTp> getTpNodeTps() {
+        return tpNodeTps;
+    }
+
+    public void setTpNodeTps(List<TpNodeTp> tpNodeTps) {
+        this.tpNodeTps = tpNodeTps;
+    }
+
+    public List<Link> getLinks() {
+        return links;
+    }
+
+    public void setLinks(List<Link> links) {
+        this.links = links;
+    }
+
+    public List<Path> getPath() {
+        return path;
+    }
+
+    public void setPath(List<Path> path) {
+        this.path = path;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public String getSuperNodeId() {
+        return superNodeId;
+    }
+
+    public void setSuperNodeId(String superNodeId) {
+        this.superNodeId = superNodeId;
+    }
+
+    public boolean isXpdrSrgAbsent() {
+        return isXpdrSrgAbsent;
+    }
+
+    public void setXpdrSrgAbsent(boolean isXpdrSrgAbsent) {
+        this.isXpdrSrgAbsent = isXpdrSrgAbsent;
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Path.java
new file mode 100644 (file)
index 0000000..6de05e9
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import org.opendaylight.transportpce.stubpce.TpNodeTp;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
+
+/**
+ * Class to create structure
+ * TpNodeTp and link.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class Path {
+    /** TpNodeTp. */
+    private TpNodeTp tpNodeTp;
+    /** Link at TpNodeTp. */
+    private Link link;
+
+    /**
+     *Path constructor.
+     *
+     * @param tpnodetp TpNodeTp
+     * @param link link at the end of TpNodeTp
+     */
+    public Path(TpNodeTp tpnodetp, Link link) {
+        setTpNodeTp(tpnodetp);
+        setLink(link);
+    }
+
+    public Path(TpNodeTp tpNodeTp) {
+        setTpNodeTp(tpNodeTp);
+    }
+
+    public TpNodeTp getTpNodeTp() {
+        return tpNodeTp;
+    }
+
+    public void setTpNodeTp(TpNodeTp tpNodeTp) {
+        this.tpNodeTp = tpNodeTp;
+    }
+
+    public Link getLink() {
+        return link;
+    }
+
+    public void setLink(Link link) {
+        this.link = link;
+    }
+
+    @Override
+    public String toString() {
+        java.lang.String name = "Path [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (tpNodeTp != null) {
+            builder.append("tpNodeTp= ");
+            builder.append(tpNodeTp);
+            builder.append(", ");
+        }
+        if (link != null) {
+            builder.append(link);
+        }
+        return builder.append(']').toString();
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/PathDescriptionsOrdered.java
new file mode 100644 (file)
index 0000000..c31c55e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptions;
+
+/**
+ * class to create structure
+ * of <code>PathDescriptions</code>
+ * ordered.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class PathDescriptionsOrdered implements Comparable<PathDescriptionsOrdered> {
+    private PathDescriptions pathDescriptions;
+    private int ord;
+
+    /**
+     * PathDescriptionsOrdered constructor.
+     *
+     * @param paths PathDescriptions
+     * @param order Integer
+     */
+    public PathDescriptionsOrdered(PathDescriptions paths, int order) {
+        setPathDescriptions(paths);
+        setOrd(order);
+    }
+
+    @Override
+    public int compareTo(PathDescriptionsOrdered paths) {
+        return this.ord - paths.getOrd();
+    }
+
+    public PathDescriptions getPathDescriptions() {
+        return pathDescriptions;
+    }
+
+    public void setPathDescriptions(PathDescriptions pathDescriptions) {
+        this.pathDescriptions = pathDescriptions;
+    }
+
+    public int getOrd() {
+        return ord;
+    }
+
+    public void setOrd(int ord) {
+        this.ord = ord;
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Resource.java
new file mode 100644 (file)
index 0000000..141cae4
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import java.util.List;
+
+
+/**
+ * Class to create structure of
+ * Supernode element.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+@JacksonXmlRootElement(localName = "resource")
+public class Resource {
+    /** element nodeId. */
+    @JacksonXmlProperty(localName = "node-id")
+    private String nodeId;
+    /** list of element links. */
+    @JacksonXmlElementWrapper(localName = "links")
+    @JacksonXmlProperty(localName = "link")
+    private List<String> links;
+    /** list of element LogicalConnectionPoint. */
+    @JacksonXmlElementWrapper(localName = "logical-connection-points")
+    @JacksonXmlProperty(localName = "logical-connection-point")
+    private List<LogicalConnectionPoint> lcps;
+
+
+    /**
+     * Resource constructor.
+     *
+     * @param nodeId element nodeId
+     * @param links list of element links
+     * @param lcps list of element LogicalConnectionPoint
+     */
+    public Resource(@JacksonXmlProperty(localName = "node-id") final String nodeId,
+            @JacksonXmlProperty(localName = "Reslinks") final List<String> links,
+            @JacksonXmlProperty(localName = "Reslcps") final List<LogicalConnectionPoint> lcps) {
+        this.setNodeId(nodeId);
+        this.setLinks(links);
+        this.setLpcs(lcps);
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public List<String> getLinks() {
+        return links;
+    }
+
+    public void setLinks(List<String> links) {
+        this.links = links;
+    }
+
+    public List<LogicalConnectionPoint> getLcps() {
+        return lcps;
+    }
+
+    public void setLpcs(List<LogicalConnectionPoint> lcps) {
+        this.lcps = lcps;
+    }
+
+    @Override
+    public String toString() {
+        int index;
+        int size;
+        java.lang.String name = "Resource [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (nodeId != null) {
+            builder.append("nodeId=");
+            builder.append(nodeId);
+        }
+        index = 0;
+        size = lcps.size();
+        builder.append(", LogicalConnectionPoints [");
+        for (LogicalConnectionPoint tmp : lcps) {
+            builder.append(tmp.toString());
+            index++;
+            if (index < size) {
+                builder.append(", ");
+            }
+        }
+        builder.append("]");
+        index = 0;
+        size = links.size();
+        builder.append(", links [");
+        for (String tmp : links) {
+            builder.append(tmp);
+            index++;
+            if (index < size) {
+                builder.append(", ");
+            }
+        }
+        builder.append("]");
+        return builder.append(']').toString();
+
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/RoadmToRoadm.java
new file mode 100644 (file)
index 0000000..2699d33
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import java.util.List;
+
+
+/**
+ * Class to create list of links
+ * between Supernode.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+@JacksonXmlRootElement(localName = "roadm-to-roadm")
+public class RoadmToRoadm {
+    /** List of links. */
+    @JacksonXmlElementWrapper(localName = "links")
+    @JacksonXmlProperty(localName = "link")
+    private List<String> links;
+
+    /**
+     * RoadmToRoadm structure.
+     *
+     * @param links list of links
+     */
+    public RoadmToRoadm(@JacksonXmlProperty(localName = "Rlinks") final List<String> links) {
+        setLinks(links);
+    }
+
+    public List<String> getLinks() {
+        return links;
+    }
+
+    public void setLinks(List<String> links) {
+        this.links = links;
+    }
+
+    @Override
+    public String toString() {
+        int index;
+        int size;
+        java.lang.String name = "RoadmToRoadm [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        index = 0;
+        size = links.size();
+        builder.append("Links [");
+        for (String tmp : links) {
+            builder.append(tmp.toString());
+            index++;
+            if (index < size) {
+                builder.append(", ");
+            }
+        }
+        builder.append("]");
+        return builder.append(']').toString();
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNode.java
new file mode 100644 (file)
index 0000000..fcf825a
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * class to create Supernode
+ * structure.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+@JacksonXmlRootElement(localName = "super-node")
+public class SuperNode {
+    /** Supernode Id. */
+    @JacksonXmlProperty(localName = "super-node-id")
+    private String superNodeId;
+    /** list of elements cotaining in Supernode. */
+    @JacksonXmlElementWrapper(localName = "resources")
+    @JacksonXmlProperty(localName = "resource")
+    private List<Resource> resources;
+
+    /**
+     * SuperNode constructor.
+     *
+     * @param supernodeid superNode Id
+     * @param resources List of Supernode elements
+     */
+    public SuperNode(@JacksonXmlProperty(localName = "super-node-id") final String supernodeid,
+            @JacksonXmlProperty(localName = "Spresource") final List<Resource> resources) {
+        setSuperNodeId(supernodeid);
+        setResources(resources);
+    }
+
+    /**
+     * SuperNode constructor.
+     *
+     * @param supernodeid supernode Id
+     */
+    public SuperNode(String supernodeid) {
+        setSuperNodeId(supernodeid);
+        setResources(new ArrayList<Resource>());
+    }
+
+    /**
+     *Test if Supernode contains
+     *an XPDR.
+     * @return true if XPDR present, false else
+     */
+    public boolean isXpdrSrgAbsent() {
+        boolean result = true;
+        int present = 0;
+        if (resources.size() > 0) {
+            for (Resource resource : resources) {
+                String nodeId = resource.getNodeId();
+                if (nodeId != null) {
+                    if (nodeId.contains("XPDR")) {
+                        present++;
+                    }
+                    if (nodeId.contains("SRG")) {
+                        present++;
+                    }
+                }
+            }
+        }
+        if (present == 2) {
+            result = false;
+        }
+        return result;
+    }
+
+    public List<Resource> getResources() {
+        return resources;
+    }
+
+    public void setResources(List<Resource> resources) {
+        this.resources = resources;
+    }
+
+    public String getSuperNodeId() {
+        return superNodeId;
+    }
+
+    public void setSuperNodeId(String superNodeId) {
+        this.superNodeId = superNodeId;
+    }
+
+    @Override
+    public String toString() {
+        int index;
+        int size;
+        java.lang.String name = "SuperNode [";
+        java.lang.StringBuilder builder = new java.lang.StringBuilder(name);
+        if (superNodeId != null) {
+            builder.append("superNodeId=");
+            builder.append(superNodeId);
+        }
+        index = 0;
+        size = resources.size();
+        builder.append(", Resources [");
+        for (Resource tmp : resources) {
+            builder.append(tmp.toString());
+            index++;
+            if (index < size) {
+                builder.append(", ");
+            }
+        }
+        builder.append("]");
+        return builder.append(']').toString();
+    }
+
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/SuperNodePath.java
new file mode 100644 (file)
index 0000000..732f318
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.AToZDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ZToADirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.atoz.direction.AToZKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToABuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.path.description.ztoa.direction.ZToAKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.Resource;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.Link;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev170426.pce.resource.resource.resource.LinkBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev170426.path.description.list.PathDescriptionsBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Class to build Path between
+ * two Supernode.
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class SuperNodePath {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(SuperNodePath.class);
+    /** List of NodeLinkNode. */
+    private List<NodeLinkNode> paths;
+    /** Supernode topology. */
+    private Network network;
+
+    /**
+     * SuperNodePath constructor.
+     *
+     * @param network Supernode topology
+     */
+    public SuperNodePath(Network network) {
+        setPaths(new ArrayList<NodeLinkNode>());
+        this.network = network;
+    }
+
+    /**
+     * test if Supernode is an
+     * extremity of path to build.
+     *
+     * @param end extremity node Id
+     * @param supernodes Supernodes list to build path
+     * @return true if link extremity, false else
+     */
+    private Boolean endNode(String end, List<String> supernodes) {
+        Boolean result = false;
+        if (end != null && end.compareTo(" ") != 0) {
+            for (String node : supernodes) {
+                if (node.compareTo(end) == 0) {
+                    result = true;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * get Supernode
+     * with supernode Id.
+     *
+     * @param nodeId supernode id to get
+     * @return SuperNode supernode gets
+     */
+    public SuperNode getSuperNode(String nodeId) {
+        SuperNode result = null;
+        if (network != null) {
+            for (SuperNode tmp : network.getSuperNodes()) {
+                if (tmp.getSuperNodeId().compareTo(nodeId) == 0) {
+                    result = tmp;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     *find links between
+     *two Supernodes.
+     *
+     * @param aend begin extremity
+     * @param zend end extremity
+     * @param links Roadm to Roadm links
+     * @param direct determine if link is direct or not
+     * @return String list of links name
+     */
+    private List<String> findLinks(String aend, String zend, List<String> links, boolean direct) {
+        List<String> result = new ArrayList<String>();
+        if (links.size() > 0) {
+            aend = aend.replace("Node", "ROADM");
+            zend = zend.replace("Node", "ROADM");
+            String atozlink = null;
+            String ztoalink = null;
+            for (String tmp : links) {
+                if (tmp.contains(aend)
+                        && tmp.contains(zend)) {
+                    LOG.info("direct path found for : " + aend + " / " + zend);
+                    if (tmp.startsWith(aend)) {
+                        atozlink = tmp;
+                    }
+                    if (tmp.startsWith(zend)) {
+                        ztoalink = tmp;
+                    }
+                    if (atozlink != null && ztoalink != null) {
+                        result.add(atozlink.concat("/").concat(ztoalink));
+                        atozlink = null;
+                        ztoalink = null;
+                    }
+                }
+            }
+        } else {
+            LOG.info("no roadm-to-roadm links !");
+        }
+        return result;
+    }
+
+    /**
+     *find next Supernode hop.
+     *
+     * @param link roadm to roadm link
+     * @param aend begin supernode
+     * @param node list of supernode id
+     * @return String  supernodeId next hop
+     */
+    private String findHop(String link, String aend, List<String> node) {
+        String result = null;
+        aend = aend.replace("Node", "ROADM");
+        for (String tmp : node) {
+            tmp = tmp.replace("Node", "ROADM");
+            if (tmp.compareTo(aend) != 0) {
+                if (link.contains(aend) && link.contains(tmp)) {
+                    LOG.info("hop : " + tmp);
+                    result = tmp;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     *get all Supernode in
+     *topology.
+     *
+     * @return String list of Supernode Id
+     */
+    private List<String> getSuperNodeId() {
+        List<String> result = new ArrayList<String>();
+        if (network.getSuperNodes().size() > 0) {
+            for (SuperNode tmp : network.getSuperNodes()) {
+                result.add(tmp.getSuperNodeId());
+            }
+        }
+        return result;
+    }
+
+    /**
+     * get all roadm to roadm
+     * links in topology.
+     *
+     * @return String list of roadm to roadm links
+     */
+    private List<String> getRoadmLinks() {
+        List<String> result = new ArrayList<String>();
+        if (network.getRoadmToroadm().getLinks().size() > 0) {
+            for (String tmp : network.getRoadmToroadm().getLinks()) {
+                result.add(tmp);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * create NodeLinkNode
+     * structure.
+     *
+     * @param links String list of roadm to roadm links
+     * @param aend beginning Supernode
+     * @param zend ending Supernode
+     * @param direct determine if link is direct or not
+     */
+    private void fill(List<String> links,String aend, String zend, boolean direct) {
+        String term = "indirect";
+        if (direct) {
+            term = "direct";
+        }
+        if (!links.isEmpty()) {
+            List<String> atoz = new ArrayList<String>();
+            List<String> ztoa = new ArrayList<String>();
+            for (String tmp : links) {
+                String [] split = tmp.split("/");
+                if (split.length == 2) {
+                    atoz.add(split[0]);
+                    ztoa.add(split[1]);
+                }
+            }
+            if (!atoz.isEmpty() && atoz.size() == ztoa.size()) {
+                NodeLinkNode node = new NodeLinkNode(aend, zend, atoz,ztoa,direct);
+                paths.add(node);
+            }
+
+        } else {
+            LOG.info(term + " links not found !");
+        }
+    }
+
+    /**
+     * launch SupernodePath process
+     * to build NodeLinkNode.
+     *
+     * @param aend beginning extremity path
+     * @param zend ending extremity path
+     */
+    public void run(String aend, String zend) {
+        if (network != null) {
+            List<String> supernodes = getSuperNodeId();
+            List<String> roadmLinks = getRoadmLinks();
+            if (aend != null && zend != null) {
+                int size = supernodes.size();
+                String hop = null;
+                List<String> links = null;
+                if (size > 0) {
+                    if (endNode(aend, supernodes) && endNode(zend, supernodes)) {
+                        LOG.info("Getting direct links ...");
+                        links = new ArrayList<String>();
+                        links = findLinks(aend,zend,roadmLinks,true);
+                        fill(links, aend, zend, true);
+                        LOG.info("Getting indirect links ..");
+                        links = new ArrayList<String>();
+                        for (String tmp : roadmLinks) {
+                            hop = findHop(tmp, aend, supernodes);
+                            if (hop != null) {
+                                if (hop.compareTo(zend.replace("Node", "ROADM")) != 0) {
+                                    LOG.info("next hop found : " + hop);
+                                    links.addAll(findLinks(aend,hop,roadmLinks,false));
+                                    links.addAll(findLinks(hop,zend,roadmLinks,false));
+                                } else {
+                                    break;
+                                }
+                            }
+                        }
+                        fill(links, aend, zend, false);
+                    } else {
+                        LOG.info("aend or/and zend not exists !");
+                    }
+                }
+            } else {
+                LOG.info("aend or/and is null !");
+            }
+        } else {
+            LOG.info("network is null !!");
+        }
+    }
+
+    /**
+     * modify all AToZ Id
+     * in AToZ List containing
+     * in AToZdirection.
+     *
+     * @param order beginning order
+     * @param atozDirection AToZdirection List
+     * @return AToZdirection List
+     */
+    public List<AToZDirection> modifyOrder(int order, List<AToZDirection> atozDirection) {
+        List<AToZDirection> result = new ArrayList<AToZDirection>();
+        for (AToZDirection tmp : atozDirection) {
+            List<AToZ> atozList = tmp.getAToZ();
+            int size = atozList.size();
+            if (size > 0) {
+                for (ListIterator<AToZ> it = atozList.listIterator(); it.hasNext();) {
+                    AToZ atoz = it.next();
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
+                        .rev170426.pce.resource.resource.Resource res = atoz.getResource().getResource();
+                    int tmpkey = order + Integer.parseInt(atoz.getKey().getId());
+                    AToZKey atozKey = new AToZKey(Integer.toString(tmpkey));
+                    org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface
+                        .pathdescription.rev170426.pce.resource.Resource resource = new ResourceBuilder()
+                        .setResource(res).build();
+                    AToZ hop = new AToZBuilder().setId(atozKey.getId()).setKey(atozKey).setResource(resource).build();
+                    it.remove();
+                    it.add(hop);
+                    tmpkey++;
+                }
+                result.add(tmp);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * merge two AToZdirection List.
+     *
+     * @param cleanInterA first AToZdirection List
+     * @param cleanInterZ second AToZdirection List
+     * @param first boolean to determine if it is the first time merge is done
+     * @return AToZDirection List
+     */
+    public List<AToZDirection> merge(List<AToZDirection> cleanInterA, List<AToZDirection> cleanInterZ,
+            boolean first) {
+        List<AToZDirection> result = new ArrayList<AToZDirection>();
+        if (!cleanInterA.isEmpty()) {
+            int order  = cleanInterA.get(0).getAToZ().size();
+            if (order > 0) {
+                List<AToZDirection> modify = modifyOrder(order, cleanInterZ);
+                if (!modify.isEmpty()) {
+                    for (AToZDirection tmp : cleanInterA) {
+                        List<AToZ> atozList = new ArrayList<AToZ>(tmp.getAToZ());
+                        for (AToZDirection add : modify) {
+                            ListIterator<AToZ> it = atozList.listIterator();
+                            /** on va a la fin de la liste */
+                            while (it.hasNext()) {
+                                it.next();
+                            }
+                            List<AToZ> addList = add.getAToZ();
+                            for (AToZ atoz : addList) {
+                                it.add(atoz);
+                            }
+                            AToZDirectionBuilder newDirection = new AToZDirectionBuilder();
+                            newDirection.setRate((long) 100).setAToZWavelengthNumber((long) 200).setAToZ(atozList);
+                            result.add(newDirection.build());
+                            atozList = new ArrayList<AToZ>(tmp.getAToZ());
+                        }
+                    }
+                } else {
+                    LOG.info("modify List is empty ! ");
+                }
+            } else {
+                LOG.info("order is not superior to 0");
+            }
+        } else {
+            if (first && !cleanInterZ.isEmpty()) {
+                LOG.info("first merge so result is a copy of second AToZDirection List !");
+                result = new ArrayList<AToZDirection>(cleanInterZ);
+            } else {
+                LOG.info("cleanInterA is empty !");
+            }
+        }
+        return result;
+    }
+
+    /**
+     * gets Degree number
+     * for roadm links.
+     *
+     * @param atozLink atoz roadm link
+     * @param ztoaLink ztoa roadm link
+     * @return String list of degree
+     */
+    public List<String> getDeg(String atozLink, String ztoaLink) {
+        List<String> result = new ArrayList<String>();
+        if (atozLink != null && ztoaLink != null) {
+            String [] split = atozLink.split("-", 4);
+            if (split.length == 4) {
+                result = Lists.newArrayList(split[1],split[3]);
+            }
+        } else {
+            LOG.info("atozlink and/or ztoalink is null !");
+        }
+        return result;
+    }
+
+    /**
+     * reverse link name
+     * (ROADMA-DEG1-ROADMZ-DEG2
+     * to
+     * ROADMZ-DEG2-ROADMA-DEG1).
+     *
+     * @param linkId Link name
+     * @return String link name reversed
+     */
+    public String reverseLinkId(String linkId) {
+        StringBuilder builder = new StringBuilder();
+        String [] split = linkId.split("-");
+        int size = split.length;
+        switch (size) {
+            case 3:
+                if (linkId.contains("XPDR")) {
+                    if (linkId.startsWith("XPDR")) {
+                        builder.append(split[1]).append("-")
+                        .append(split[2]).append("-")
+                        .append(split[0]);
+                    } else {
+                        builder.append(split[2]).append("-")
+                        .append(split[0]).append("-")
+                        .append(split[1]);
+                    }
+                }
+                break;
+
+            case 4:
+                builder.append(split[2]).append("-")
+                .append(split[3]).append("-")
+                .append(split[0]).append("-")
+                .append(split[1]);
+                break;
+
+            default:
+                break;
+        }
+        return builder.toString();
+    }
+
+    /**
+     * convert AToAdirection to
+     * ZToAdirection.
+     *
+     * @param atozDirection AToZdirection to convert
+     * @return ZToAdirection
+     */
+    public ZToADirection convertToZtoaDirection(AToZDirection atozDirection) {
+        ZToADirectionBuilder ztoaDirection = new ZToADirectionBuilder();
+        if (atozDirection != null) {
+            List<AToZ> atozList = atozDirection.getAToZ();
+            List<ZToA> ztoaList = new ArrayList<ZToA>();
+            if (!atozList.isEmpty()) {
+                List<AToZ> reverse = Lists.reverse(atozList);
+                /** Building path. */
+                ZToAKey ztoaKey = null;
+                Resource resource = null;
+                org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription
+                    .rev170426.pce.resource.resource.Resource resLink = null;
+                ZToA hop = null;
+                int odr = 0;
+                for (AToZ atoz : reverse) {
+                    ztoaKey = new ZToAKey(Integer.toString(odr));
+                    resLink = atoz.getResource().getResource();
+                    if (resLink != null) {
+                        if (resLink instanceof Link) {
+                            Link link = (Link) resLink;
+                            String newLinkId = reverseLinkId(link.getLinkId());
+                            if (newLinkId != null) {
+                                resource = new ResourceBuilder().setResource(
+                                        new LinkBuilder()
+                                        .setLinkId(newLinkId)
+                                        .build()
+                                        ).build();
+                            }
+
+                        } else {
+                            resource = new ResourceBuilder().setResource(resLink).build();
+                        }
+                    }
+                    if (resource != null) {
+                        hop = new ZToABuilder()
+                                .setKey(ztoaKey)
+                                .setResource(resource)
+                                .build();
+                        ztoaList.add(hop);
+                        odr++;
+                    } else {
+                        LOG.info("resource is null ");
+                    }
+                }
+                if (!ztoaList.isEmpty()) {
+                    ztoaDirection.setRate((long) 100).setZToAWavelengthNumber((long) 200).setZToA(ztoaList);
+                } else {
+                    LOG.info("ztoaList is empty !");
+                }
+            }
+        }
+        return ztoaDirection.build();
+    }
+
+    /**
+     *build Pathdescritions ordered List
+     *to be loaded in Pathdescriptions
+     *datastore.
+     *
+     * @param atozDirection AToZdirection List
+     * @param term direct ou indirect
+     * @return PathDescriptionsOrdered List
+     */
+    private SortedSet<PathDescriptionsOrdered> buildPathDescription(List<AToZDirection> atozDirection, String term) {
+        SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
+        PathDescriptionsBuilder pathDescr = new PathDescriptionsBuilder();
+        int size = atozDirection.size();
+        if (!atozDirection.isEmpty()) {
+            LOG.info("result list AToZDirection size  : " + atozDirection.size());
+            List<ZToADirection> ztoadirList = new ArrayList<ZToADirection>();
+            for (AToZDirection atozdir : atozDirection) {
+                ZToADirection ztodir = convertToZtoaDirection(atozdir);
+                if (ztodir != null) {
+                    ztoadirList.add(ztodir);
+                }
+            }
+            if (!ztoadirList.isEmpty() && size == ztoadirList.size()) {
+                LOG.info("building PathDescriptions ...");
+                int index = 1;
+                String pathName = null;
+                for (int indexPath = 0 ; indexPath < size ; indexPath++) {
+                    pathName = term.concat(Integer.toString(index));
+                    LOG.info("pathName : " + pathName);
+                    pathDescr.setAToZDirection(atozDirection.get(indexPath))
+                    .setZToADirection(ztoadirList.get(indexPath)).setPathName(pathName);
+                    LOG.info(pathDescr.build().toString());
+                    result.add(new PathDescriptionsOrdered(pathDescr.build(),index));
+                    index++;
+                }
+            } else {
+                LOG.info("Something wrong happen during atodir conversion...");
+            }
+
+        } else {
+            LOG.info("atozDirection is empty");
+        }
+        return result;
+    }
+
+    /**
+     * gets link extremity.
+     *
+     * @param link link
+     * @return Supernode List of extremities
+     */
+    public List<SuperNode> getSuperNodeEndLink(String link) {
+        List<SuperNode> result = new ArrayList<SuperNode>();
+        if (link != null) {
+            String [] split = link.split("-");
+            if (split.length == 4) {
+                String aend = split[0].replaceAll("ROADM", "Node");
+                String zend = split[2].replaceAll("ROADM", "Node");
+                if (aend != null && zend != null) {
+                    LOG.info("getting super node for : " + aend + " and " + zend);
+                    SuperNode aendSp = getSuperNode(aend);
+                    SuperNode zendSp = getSuperNode(zend);
+                    if (aendSp != null && zendSp != null) {
+                        result.add(aendSp);
+                        result.add(zendSp);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * build all direct paths.
+     *
+     * @param aend beginning extremity path
+     * @param zend ending extremity path
+     * @param paths NodeLinkNode list paths
+     * @return PathDescriptionsOrdered List of direct paths
+     */
+    public SortedSet<PathDescriptionsOrdered> getDirectPathDesc(String aend, String zend,List<NodeLinkNode> paths) {
+        List<AToZDirection> atozdirectionPaths = new ArrayList<AToZDirection>();
+        SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
+        SuperNode aendSp = getSuperNode(aend);
+        SuperNode zendSp = getSuperNode(zend);
+        if (!paths.isEmpty()) {
+            for (NodeLinkNode tmp : paths) {
+                if (tmp.getDirect()) {
+                    LOG.info("Direct NodeLinkNode : " + tmp.toString());
+                    String atozLink = null;
+                    String ztoaLink = null;
+                    atozLink = tmp.getAtozLink().get(0);
+                    ztoaLink = tmp.getZtoaLink().get(0);
+                    if (atozLink != null && ztoaLink != null) {
+                        LOG.info("atozlink : " + atozLink);
+                        LOG.info("ztoalink : " + ztoaLink);
+                        InterNodePath interAend = new InterNodePath(aendSp);
+                        interAend.buildPath(zend);
+                        InterNodePath interZend = new InterNodePath(zendSp);
+                        interZend.buildPath(zend);
+                        List<String> deg = getDeg(atozLink,ztoaLink);
+                        LOG.info("deg : " + deg.toString());
+                        if (deg.size() == 2) {
+                            List<AToZDirection> cleanInterA =
+                                    interAend.replaceOrRemoveAToZDirectionEndLink(deg.get(0),"",atozLink,
+                                            interAend.getAtoz(),false);
+                            List<AToZDirection> cleanInterZ =
+                                    interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS",deg.get(1),"",
+                                            interZend.getAtoz(),true);
+                            if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) {
+                                atozdirectionPaths.addAll(merge(cleanInterA,cleanInterZ,false));
+                            } else {
+                                LOG.info("cleanInterA ad/or cleanInterZ is empty !");
+                            }
+                        } else {
+                            LOG.info("deg size is not correct, must be 2 ! ");
+                        }
+                    } else {
+                        LOG.info("atozlink and / or ztoalink is null");
+                    }
+                }
+            }
+
+        } else {
+            LOG.info("List of direct path is empty !");
+        }
+        if (!atozdirectionPaths.isEmpty()) {
+            LOG.info("result size : " + result.size());
+            result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_direct_"));
+        } else {
+            LOG.info("result is empty");
+        }
+        return result;
+    }
+
+    /**
+     * build all indirect paths.
+     *
+     * @param aend beginning extremity path
+     * @param zend ending extremity path
+     * @param paths NodeLinkNode list paths
+     * @return PathDescriptionsOrdered List of indirect paths
+     */
+    public SortedSet<PathDescriptionsOrdered> getIndirectPathDesc(String aend, String zend,List<NodeLinkNode> paths) {
+        List<AToZDirection> atozdirectionPaths = new ArrayList<AToZDirection>();
+        SortedSet<PathDescriptionsOrdered> result = new TreeSet<PathDescriptionsOrdered>();
+        SuperNode aendSp = getSuperNode(aend);
+        SuperNode zendSp = getSuperNode(zend);
+        if (!paths.isEmpty()) {
+            for (NodeLinkNode tmp : paths) {
+                if (!tmp.getDirect()) {
+                    LOG.info("Indirect NodeLinkNode : " + tmp.toString());
+                    int size = tmp.getAtozLink().size();
+                    /** must be two for now just one hop. */
+                    LOG.info("number of links  : " + size);
+                    boolean first = true;
+                    if (size == 2) {
+                        List<String> atozLinks = tmp.getAtozLink();
+                        List<String> ztoaLinks = tmp.getZtoaLink();
+                        if (!atozLinks.isEmpty() && !ztoaLinks.isEmpty()) {
+                            LOG.info("atozlink : " + atozLinks.toString());
+                            LOG.info("ztoalink : " + ztoaLinks.toString());
+                            int loop = 0;
+                            while (loop < 2) {
+                                List<SuperNode> hop = getSuperNodeEndLink(atozLinks.get(loop));
+                                if (!hop.isEmpty() && hop.size() == 2) {
+                                    aendSp = hop.get(0);
+                                    zendSp = hop.get(1);
+                                    InterNodePath interAend = new InterNodePath(aendSp);
+                                    interAend.buildPath(zend);
+                                    LOG.info("interAend : " + interAend.getAtoz().toString());
+                                    InterNodePath interZend = new InterNodePath(zendSp);
+                                    interZend.buildPath(zend);
+                                    LOG.info("interZend : " + interZend.getAtoz().toString());
+                                    List<String> deg1 = getDeg(atozLinks.get(loop),ztoaLinks.get(loop));
+                                    LOG.info("deg1 : " + deg1.toString());
+                                    if (!deg1.isEmpty() && deg1.size() == 2) {
+                                        List<AToZDirection> cleanInterA = null;
+                                        List<AToZDirection> cleanInterZ = null;
+                                        if (zendSp.getSuperNodeId().compareTo(zend) == 0) {
+                                            cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0),
+                                                    "",atozLinks.get(loop),interAend.getAtoz(),false);
+                                            LOG.info("next hop is zend");
+                                            cleanInterZ = interZend.replaceOrRemoveAToZDirectionEndLink("TAIL-LINKS",
+                                                    deg1.get(1),"",interZend.getAtoz(),true);
+                                        } else if (loop < 1) {
+                                            cleanInterA = interAend.replaceOrRemoveAToZDirectionEndLink(deg1.get(0),
+                                                    "",atozLinks.get(loop),interAend.getAtoz(),false);
+                                            cleanInterZ = interZend.getAToZDirectionEndBy(deg1.get(1),
+                                                    interZend.getAtoz(), 1);
+                                        }
+                                        if (!cleanInterA.isEmpty() && !cleanInterZ.isEmpty()) {
+                                            atozdirectionPaths = merge(atozdirectionPaths,cleanInterA,first);
+                                            atozdirectionPaths = merge(atozdirectionPaths, cleanInterZ,false);
+                                            first = false;
+                                        } else {
+                                            LOG.info("cleanInterA ad/or cleanInterZ is empty !");
+                                            break;
+                                        }
+                                    }
+                                } else {
+                                    LOG.info("Hop list is empty");
+                                }
+                                loop++;
+                            }
+                        }
+                    } else {
+                        LOG.info("Link size is not supported , must be two !");
+                    }
+                }
+            }
+        } else {
+            LOG.info("List of indirect path is empty !");
+        }
+        if (!atozdirectionPaths.isEmpty()) {
+            LOG.info("result size : " + result.size());
+            result = buildPathDescription(atozdirectionPaths,aend.concat("To").concat(zend).concat("_indirect_"));
+        } else {
+            LOG.info("result is empty");
+        }
+        return result;
+    }
+
+    public static void main(String[] args) {
+        Topology topo = new Topology();
+        topo.start();
+        SuperNodePath path = new SuperNodePath(topo.getNetwork());
+        String aend = "NodeA";
+        String zend = "NodeZ";
+        path.run(aend, zend);
+        path.getDirectPathDesc(aend, zend, path.getPaths());
+        path.getIndirectPathDesc(aend, zend, path.getPaths());
+    }
+
+    public List<NodeLinkNode> getPaths() {
+        return paths;
+    }
+
+    public void setPaths(List<NodeLinkNode> paths) {
+        this.paths = paths;
+    }
+}
diff --git a/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java b/tests/stubpce/src/main/java/org/opendaylight/transportpce/stubpce/topology/Topology.java
new file mode 100644 (file)
index 0000000..72fd5dd
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2017 Orange, 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.transportpce.stubpce.topology;
+
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to build Supernode
+ * topology (fakepce.xml file has to be
+ * in src/main/ressources folder
+ * to be loaded in taget/classes).
+ *
+ *
+ * @author <a href="mailto:martial.coulibaly@gfi.com">Martial Coulibaly</a> on
+ *         behalf of Orange
+ */
+public class Topology {
+    /** Logging. */
+    private static final Logger LOG = LoggerFactory.getLogger(Topology.class);
+    /** file must be in src/main/resources in order to be in
+     * target/classes after compilation.
+     */
+
+    /** Structure of Supernode topology. */
+    private Network network;
+    public BundleContext bcontext;
+    /** String to get Supernode topolgy info freom xml file. */
+    private String xml = null;
+
+    /**
+     * load fakepce.xml file
+     * and convert the informations
+     * in Network structure.
+     *
+     */
+    public void start() {
+        setNetwork(null);
+        XmlMapper xmlMapper = new XmlMapper();
+        try {
+            InputStream is = FrameworkUtil.getBundle(Topology.class).getBundleContext()
+                    .getBundle().getEntry("/fakepce.xml").openStream();
+            /*File file = new File("target/classes/fakepce.xml");
+            InputStream is = new FileInputStream(file);*/
+            xml = inputStreamToString(is);
+            if (xml != null) {
+                setNetwork(xmlMapper.readValue(xml, Network.class));
+                LOG.info("Network : " + network.toString());
+            } else {
+                LOG.info("String xml is null");
+            }
+        } catch (IOException e) {
+            LOG.error("The file fakepce.xml not found", e);
+        }
+    }
+
+    /**
+     * get xml file
+     * content.
+     *
+     * @param is InputStream
+     * @return String xml file content
+     * @throws IOException exception raised
+     */
+    private String inputStreamToString(InputStream is) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        String line;
+        BufferedReader br = new BufferedReader(new InputStreamReader(is));
+        while ((line = br.readLine()) != null) {
+            sb.append(line);
+        }
+        br.close();
+        return sb.toString();
+    }
+
+    public static void main(String[] args) {
+        Topology topo = new Topology();
+        topo.start();
+    }
+
+    public Network getNetwork() {
+        return network;
+    }
+
+    public void setNetwork(Network network) {
+        this.network = network;
+    }
+
+    public void setBcontext(BundleContext bcontext) {
+        this.bcontext = bcontext;
+    }
+
+    public BundleContext getBcontext() {
+        return this.bcontext;
+    }
+}
diff --git a/tests/stubpce/src/main/resources/fakepce.xml b/tests/stubpce/src/main/resources/fakepce.xml
new file mode 100644 (file)
index 0000000..2d4433a
--- /dev/null
@@ -0,0 +1,198 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<network>
+  <roadm-to-roadm>
+    <links>
+      <link>ROADMA-DEG1-ROADMB-DEG1</link>
+      <link>ROADMA-DEG2-ROADMZ-DEG2</link>
+      <link>ROADMZ-DEG1-ROADMB-DEG1</link>
+      <link>ROADMZ-DEG2-ROADMA-DEG2</link>
+      <link>ROADMB-DEG1-ROADMA-DEG1</link>
+      <link>ROADMB-DEG2-ROADMZ-DEG1</link>
+    </links>
+  </roadm-to-roadm>
+  <super-nodes>
+    <super-node>
+      <super-node-id>NodeA</super-node-id>
+      <resources>
+        <resource>
+          <node-id>XPDRA</node-id>
+          <links>
+            <link>XPDRA-ROADMA-SRG1</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>CLIENT1</tp-id>
+              <node-id>XPDRA</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>NETWORK1</tp-id>
+              <node-id>XPDRA</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMA-SRG1</node-id>
+          <links>
+            <link>ROADMA-SRG1-XPDRA</link>
+            <link>SRG1-CP-DEG1-CP</link>
+            <link>SRG1-CP-DEG2-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>SRG1-PP1</tp-id>
+              <node-id>ROADMA-SRG1</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>SRG1-PP2</tp-id>
+              <node-id>ROADMA-SRG1</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMA-DEG1</node-id>
+          <links>
+            <link>ROADMA-DEG1-ROADMA-DEG2</link>
+            <link>DEG1-CP-SRG1-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG1-CTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG1</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG1-TTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG1</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMA-DEG2</node-id>
+          <links>
+            <link>ROADMA-DEG2-ROADMA-DEG1</link>
+            <link>DEG2-CP-SRG1-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG2-CTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG2</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG2-TTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG2</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+      </resources>
+    </super-node>
+    <super-node>
+      <super-node-id>NodeB</super-node-id>
+      <resources>
+        <resource>
+          <node-id>ROADMB-DEG1</node-id>
+          <links>
+            <link>ROADMB-DEG1-ROADMB-DEG2</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG1-CTP-TXRX</tp-id>
+              <node-id>ROADMB-DEG1</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG1-TTP-TXRX</tp-id>
+              <node-id>ROADMB-DEG1</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMB-DEG2</node-id>
+          <links>
+            <link>ROADMB-DEG2-ROADMB-DEG1</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG2-CTP-TXRX</tp-id>
+              <node-id>ROADMB-DEG2</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG2-TTP-TXRX</tp-id>
+              <node-id>ROADMB-DEG2</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+      </resources>
+    </super-node>
+    <super-node>
+      <super-node-id>NodeZ</super-node-id>
+      <resources>
+        <resource>
+          <node-id>XPDRC</node-id>
+          <links>
+            <link>XPDRC-ROADMZ-SRG1</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>CLIENT1</tp-id>
+              <node-id>XPDRC</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>NETWORK1</tp-id>
+              <node-id>XPDRC</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMZ-SRG1</node-id>
+          <links>
+            <link>ROADMZ-SRG1-XPDRC</link>
+            <link>SRG1-CP-DEG1-CP</link>
+            <link>SRG1-CP-DEG2-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>SRG1-PP1</tp-id>
+              <node-id>ROADMZ-SRG1</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>SRG1-PP2</tp-id>
+              <node-id>ROADMZ-SRG1</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMA-DEG1</node-id>
+          <links>
+            <link>ROADMZ-DEG1-ROADMZ-DEG2</link>
+            <link>DEG1-CP-SRG1-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG1-CTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG1</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG1-TTP-TXRX</tp-id>
+              <node-id>ROADMA-DEG1</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+        <resource>
+          <node-id>ROADMZ-DEG2</node-id>
+          <links>
+            <link>ROADMZ-DEG2-ROADMZ-DEG1</link>
+            <link>DEG2-CP-SRG1-CP</link>
+          </links>
+          <logical-connection-points>
+            <logical-connection-point>
+              <tp-id>DEG2-CTP-TXRX</tp-id>
+              <node-id>ROADMZ-DEG2</node-id>
+            </logical-connection-point>
+            <logical-connection-point>
+              <tp-id>DEG2-TTP-TXRX</tp-id>
+              <node-id>ROADMZ-DEG2</node-id>
+            </logical-connection-point>
+          </logical-connection-points>
+        </resource>
+      </resources>
+    </super-node>
+  </super-nodes>
+</network>
index c585e88cf12c04db6ab33d1989e1a197d8dd2fbe..30a4f3a948fe5715366cb998d693705cd073a390 100644 (file)
@@ -14,22 +14,32 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   odl:use-default-for-reference-types="true">\r
 \r
   <reference id="rpcRegistry"\r
-       interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>\r
+             interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"/>\r
 \r
   <reference id="notificationPublishService"\r
           interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService"\r
           odl:type="default" />\r
 \r
   <reference id="notificationService"\r
-          interface="org.opendaylight.controller.md.sal.binding.api.NotificationService"\r
-          odl:type="default" />\r
+             interface="org.opendaylight.controller.md.sal.binding.api.NotificationService"\r
+             odl:type="default" />\r
+\r
+  <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"\r
+             odl:type="default" />\r
 \r
   <bean id="provider"\r
     class="org.opendaylight.transportpce.stubpce.impl.StubpceProvider"\r
     init-method="init" destroy-method="close">\r
     <argument ref="rpcRegistry" />\r
     <argument ref="notificationPublishService" />\r
-       <argument ref="notificationService"/>\r
+    <argument ref="notificationService"/>\r
+    <argument ref="dataBroker" />\r
+  </bean>\r
+\r
+  <bean id="injectxmlfile"\r
+    class="org.opendaylight.transportpce.stubpce.topology.Topology"\r
+    init-method="start">\r
+    <property name="bcontext" ref="blueprintBundleContext"/>\r
   </bean>\r
 \r
 </blueprint>\r