GNPy migration to Aluminium 03/92403/14
authorChristophe Betoule <christophe.betoule@orange.com>
Thu, 3 Sep 2020 16:27:08 +0000 (18:27 +0200)
committerguillaume.lambert <guillaume.lambert@orange.com>
Thu, 17 Sep 2020 08:28:01 +0000 (10:28 +0200)
  - use BindingDOMCodecServices instead of direct implementation
  - update the GNPy YANG model in the API
    by removing the key index from route-object-include-exclude
  - add log debug for request and response to and from GNPy api
  - Junit tests will be managed in another change

JIRA: TRNSPRTPCE-314

Signed-off-by: Christophe Betoule <christophe.betoule@orange.com>
Co-authored-by: manuedelf <emmanuelle.delfour@orange.com>
Co-authored-by: Gilles Thouenon <gilles.thouenon@orange.com>
Change-Id: Ic9f7d04ab04f963e9c3374637b93b7920fe8a3d8

23 files changed:
api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang [moved from api/src/main/yang/gnpy-path-computation-simplified@2020-02-02.yang with 99% similarity]
pce/pom.xml
pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java
pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ConnectToGnpyServer.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/AToZComparator.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/ZToAComparator.java [new file with mode: 0644]
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java
pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java
pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java
pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml
pce/src/test/java/org/opendaylight/transportpce/pce/PceSendingPceRPCsTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/GnpyStub.java
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImplTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImplTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/impl/PceProviderTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/impl/PceServiceRPCImplTest.java
pce/src/test/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImplTest.java

similarity index 99%
rename from api/src/main/yang/gnpy-path-computation-simplified@2020-02-02.yang
rename to api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang
index 630887ea3d856ffa0ae2164c6e38342e9485812f..7275ddf2c9664878692ae234e0e56421c00d2657 100644 (file)
@@ -22,6 +22,10 @@ module gnpy-path-computation-simplified {
 
   description "YANG model for gnpy path computation simplified for transportPCE";
 
+  revision "2020-09-09" {
+    description "remove key from route-object-include-exclude";
+  }
+
   revision "2020-02-02" {
     description "second draft with detailed blocking reasons";
     reference "YANG model for path computation with gnpy inputs";
@@ -306,7 +310,6 @@ module gnpy-path-computation-simplified {
       description
         "Container for the route object list";
       list route-object-include-exclude {
-        key index;
         description
           "List of explicit route objects to include or
            exclude in path computation";
index b5447d04102992b6f57a06a01100f5e9b82c0124..3bfa0f62185547b8ed91ddfa56d5bafed43a7aec 100644 (file)
             <version>1.2.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.inject</groupId>
+            <artifactId>jersey-hk2</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 93c1b7410dd32e3d546d69c92b5a528d9186512f..5dc2c9c7f213df8bfc080182c74371bf3787f807 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.transportpce.pce;
 
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
 import org.opendaylight.transportpce.common.ResponseCodes;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
@@ -58,6 +59,7 @@ public class PceSendingPceRPCs {
     private Boolean success;
     private String message;
     private String responseCode;
+    private BindingDOMCodecServices bindingDOMCodecServices;
 
     public PceSendingPceRPCs() {
         setPathDescription(null);
@@ -66,12 +68,13 @@ public class PceSendingPceRPCs {
     }
 
     public PceSendingPceRPCs(PathComputationRequestInput input,
-        NetworkTransactionService networkTransaction) {
+        NetworkTransactionService networkTransaction, BindingDOMCodecServices bindingDOMCodecServices) {
         setPathDescription(null);
 
         // TODO compliance check to check that input is not empty
         this.input = input;
         this.networkTransaction = networkTransaction;
+        this.bindingDOMCodecServices = bindingDOMCodecServices;
     }
 
     public void cancelResourceReserve() {
@@ -154,7 +157,8 @@ public class PceSendingPceRPCs {
         try {
             ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
             if (connectToGnpy.isGnpyURLExist()) {
-                GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input);
+                GnpyUtilitiesImpl gnpy = new GnpyUtilitiesImpl(networkTransaction, input,
+                        bindingDOMCodecServices);
                 if (rc.getStatus() && gnpyToCheckFeasiblity(atoz,ztoa,gnpy)) {
                     setPathDescription(new PathDescriptionBuilder().setAToZDirection(atoz).setZToADirection(ztoa));
                     return;
index 371d3252454620da39afa2d1f5a9dca92044ff19..392fb377d7ee46275e0eff552f02d7c647acfd5e 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.transportpce.pce.constraints;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
@@ -45,6 +47,8 @@ import org.slf4j.LoggerFactory;
 public class PceConstraintsCalc {
     /* Logging. */
     private static final Logger LOG = LoggerFactory.getLogger(PceConstraintsCalc.class);
+    private static final Comparator<OrderedHops> ORDERED_HOP_COMPARATOR =
+            Comparator.comparing(OrderedHops::getHopNumber);
 
     private PceConstraints pceHardConstraints = new PceConstraints();
     private PceConstraints pceSoftConstraints = new PceConstraints();
@@ -184,6 +188,7 @@ public class PceConstraintsCalc {
     }
 
     private void readIncludeNodes(List<OrderedHops> listHops, PceConstraints constraints) {
+        Collections.sort(listHops, ORDERED_HOP_COMPARATOR);
         for (int i = 0; i < listHops.size(); i++) {
             HopType hoptype = listHops.get(i).getHopType().getHopType();
 
index 78980d8ac7f1e21f71e8f64ffb831e6792b26301..a26f1960435e8d5bf9cee14f4e507ddd0717fa75 100644 (file)
@@ -34,7 +34,7 @@ public class ConnectToGnpyServer {
 
     public String returnGnpyResponse(String jsonTxt) throws GnpyException  {
         String jsonRespTxt = null;
-
+        LOG.debug("Sending request {}",jsonTxt);
         try {
             // Send the request to the GNPy
             HttpURLConnection conn = connectToGNPy("POST");
@@ -53,6 +53,7 @@ public class ConnectToGnpyServer {
         } catch (IOException e) {
             throw new GnpyException("In connectToGnpyServer: excpetion",e);
         }
+        LOG.debug("Receiving response {}",jsonRespTxt);
         return jsonRespTxt;
     }
 
index e0775608113b20291ad534e8a621db20eebcafed..b40fc22551cc59d6f5aa0d2e948d0d33b3dd56f5 100644 (file)
@@ -17,7 +17,6 @@ import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -25,18 +24,15 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import javax.annotation.Nonnull;
-import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
-import org.opendaylight.mdsal.binding.dom.adapter.AdapterContext;
-import org.opendaylight.mdsal.binding.dom.adapter.ConstantAdapterContext;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.Result;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.NumUnnumHop;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathMetric;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.Response;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.NoPathCase;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.PathCase;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.Result;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHop;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCase;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.General;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.GeneralBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.constraints.sp.co.routing.or.general.general.Include;
@@ -51,7 +47,7 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -64,7 +60,7 @@ import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -80,20 +76,15 @@ public class GnpyResult {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
     private Response response = null;
     private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
-    private final AdapterContext adapterContext = new ConstantAdapterContext();
+    private EffectiveModelContext effectiveModelcontext;
 
-    public GnpyResult(String gnpyResponseString, GnpyTopoImpl gnpyTopo) throws GnpyException, Exception {
+    public GnpyResult(String gnpyResponseString, GnpyTopoImpl gnpyTopo,
+            BindingDOMCodecServices bindingDOMCodecServices) throws GnpyException {
         this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
-        // Create the schema context
-        Collection<? extends YangModuleInfo> moduleInfos = Collections.singleton(BindingReflections
-                .getModuleInfo(Result.class));
-        BindingRuntimeHelpers.createEffectiveModel(moduleInfos);
-
-        // Create the binding binding normalized node codec registry
-        final BindingNormalizedNodeSerializer codecRegistry = adapterContext.currentSerializer();
+        effectiveModelcontext = bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext();
 
         // Create the data object
-        QName pathQname = QName.create("gnpy:path", "2020-02-02", "result");
+        QName pathQname = QName.create("gnpy:path", "2020-09-09", "result");
         LOG.debug("the Qname is {} / namesapce {} ; module {}; ", pathQname, pathQname.getNamespace(),
             pathQname.getModule());
         YangInstanceIdentifier yangId = YangInstanceIdentifier.of(pathQname);
@@ -109,9 +100,11 @@ public class GnpyResult {
             throw new GnpyException("In GnpyResult: the Normalized Node is not present");
         }
         NormalizedNode<? extends PathArgument, ?> normalizedNode = transformIntoNormalizedNode.get();
+        Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode = bindingDOMCodecServices
+                .fromNormalizedNode(yangId, normalizedNode);
 
-        if (codecRegistry.fromNormalizedNode(yangId, normalizedNode) != null) {
-            dataObject = codecRegistry.fromNormalizedNode(yangId, normalizedNode).getValue();
+        if (fromNormalizedNode != null) {
+            dataObject = fromNormalizedNode.getValue();
         } else {
             throw new GnpyException("In GnpyResult: the codec registry from the normalized node is null");
         }
@@ -183,7 +176,7 @@ public class GnpyResult {
         int counter = 0;
         for (PathRouteObjects pathRouteObjects : pathRouteObjectList) {
             if (pathRouteObjects.getPathRouteObject().getType() instanceof NumUnnumHop) {
-                NumUnnumHop numUnnumHop = (org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type
+                NumUnnumHop numUnnumHop = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type
                     .NumUnnumHop) pathRouteObjects.getPathRouteObject().getType();
                 String nodeIp = numUnnumHop.getNumUnnumHop().getNodeId();
                 try {
@@ -229,13 +222,12 @@ public class GnpyResult {
      * @throws Exception exception
      */
     private Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> parseInputJSON(JsonReader reader,
-        Class<? extends DataObject> objectClass) throws Exception {
+        Class<? extends DataObject> objectClass) {
         NormalizedNodeResult result = new NormalizedNodeResult();
-        SchemaContext schemaContext = getSchemaContext(objectClass);
         try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
             JsonParserStream jsonParser = JsonParserStream.create(streamWriter,
-                JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext),
-                schemaContext);) {
+                JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(effectiveModelcontext),
+                effectiveModelcontext);) {
             jsonParser.parse(reader);
         } catch (IOException e) {
             LOG.warn("GNPy: exception {} occured during parsing Json input stream", e.getMessage());
@@ -244,11 +236,6 @@ public class GnpyResult {
         return Optional.ofNullable(result.getResult());
     }
 
-    private SchemaContext getSchemaContext(Class<? extends DataObject> objectClass) throws GnpyException, Exception {
-        Collection<? extends YangModuleInfo> moduleInfos = Collections.singleton(BindingReflections
-                .getModuleInfo(objectClass));
-        return BindingRuntimeHelpers.createEffectiveModel(moduleInfos);
-    }
 
     /**
      * Transforms the given input {@link NormalizedNode} into the given {@link DataObject}.
index 39f40631336930083d937706700b122d8a7dc9db..d3d2a5f059eea35bf5bbe4635ed1a974c3ca5855 100644 (file)
@@ -11,6 +11,9 @@ package org.opendaylight.transportpce.pce.gnpy;
 import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -19,34 +22,35 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints.ResourcePair;
+import org.opendaylight.transportpce.pce.gnpy.utils.AToZComparator;
+import org.opendaylight.transportpce.pce.gnpy.utils.ZToAComparator;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.ElementsKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.RouteIncludeEro;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeHopType;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeNodeId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TePathDisjointness;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.TeTpId;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.common.constraints_config.TeBandwidth;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.common.constraints_config.TeBandwidthBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.Type;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.NumUnnumHopBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.constraints.PathConstraints;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.constraints.PathConstraintsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.gnpy.specific.parameters.EffectiveFreqSlot;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.ExplicitRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.ExplicitRouteObjectsBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequestBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequestKey;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.Synchronization;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.SynchronizationBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.synchronization.Svec;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.synchronization.SvecBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.RouteIncludeEro;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeHopType;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeNodeId;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TePathDisjointness;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.TeTpId;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidth;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.common.constraints_config.TeBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.Type;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.NumUnnumHopBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num.unnum.hop.NumUnnumHop;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraints;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.constraints.PathConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlot;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.gnpy.specific.parameters.EffectiveFreqSlotBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.ExplicitRouteObjectsBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExclude;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.path.route.objects.explicit.route.objects.RouteObjectIncludeExcludeBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequestKey;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.SynchronizationBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.Svec;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.synchronization.SvecBuilder;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirection;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ZToADirection;
@@ -79,6 +83,8 @@ public class GnpyServiceImpl {
     private static final double FLEX_CENTRAL_FREQ = 193.1;
   //Convert THz to Hz
     private static final double CONVERT_TH_HZ = 1e12;
+    private static final Comparator<RouteObjectIncludeExclude> ROUTE_OBJECT_COMPARATOR =
+            Comparator.comparing(RouteObjectIncludeExclude::getIndex);
 
     private Map<PathRequestKey, PathRequest> pathRequest = new HashMap<>();
     private List<Synchronization> synchronization = new ArrayList<>();
@@ -88,8 +94,10 @@ public class GnpyServiceImpl {
     private Map<String, IpAddress> mapFiberIp = new HashMap<>();
     private List<String> trxList = new ArrayList<>();
     private Map<ElementsKey, Elements> elements = new HashMap<>();
-    private Map<RouteObjectIncludeExcludeKey,RouteObjectIncludeExclude> routeObjectIncludeExcludes = new HashMap<>();
+    private List<RouteObjectIncludeExclude> routeObjectIncludeExcludes = new ArrayList<>();
     private IpAddress currentNodeIpAddress = null;
+    private AToZComparator atoZComparator =  new AToZComparator();
+    private ZToAComparator ztoAComparator =  new ZToAComparator();
 
     /*
      * Construct the GnpyServiceImpl
@@ -140,10 +148,13 @@ public class GnpyServiceImpl {
         // Create explicitRouteObjects
         List<AToZ> listAtoZ = new ArrayList<>(atoz.nonnullAToZ().values());
         if (!listAtoZ.isEmpty()) {
+            Collections.sort(listAtoZ, atoZComparator);
             extractRouteObjectIcludeAtoZ(listAtoZ);
         } else {
             extractHardConstraints(pceHardConstraints);
         }
+
+        Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
         //Create Path Constraint
@@ -178,10 +189,12 @@ public class GnpyServiceImpl {
         // Create explicitRouteObjects
         @NonNull List<ZToA> listZtoA = new ArrayList<>(ztoa.nonnullZToA().values());
         if (!listZtoA.isEmpty()) {
+            Collections.sort(listZtoA, ztoAComparator);
             extractRouteObjectIcludeZtoA(listZtoA);
         } else {
             extractHardConstraints(pceHardConstraints);
         }
+        Collections.sort(routeObjectIncludeExcludes, ROUTE_OBJECT_COMPARATOR);
         ExplicitRouteObjects explicitRouteObjects = new ExplicitRouteObjectsBuilder()
             .setRouteObjectIncludeExclude(routeObjectIncludeExcludes).build();
         //Create Path Constraint
@@ -205,7 +218,7 @@ public class GnpyServiceImpl {
     }
 
     //Extract RouteObjectIncludeExclude list in the case of pre-computed path A-to-Z
-    private void extractRouteObjectIcludeAtoZ(List<AToZ> listAtoZ) throws GnpyException {
+    private void extractRouteObjectIcludeAtoZ(Collection<AToZ> listAtoZ) throws GnpyException {
         Long index = 0L;
         for (AToZ entry : listAtoZ) {
             index = createResource(entry.getResource().getResource(),index);
@@ -287,12 +300,12 @@ public class GnpyServiceImpl {
         }
 
         for (Elements element : this.elements.values()) {
-            if (element.getUid().contains(ipAddress.getIpv4Address().getValue())) {
+            if (element.getUid().equals(ipAddress.getIpv4Address().getValue())) {
                 if ((this.currentNodeIpAddress == null) || (!this.currentNodeIpAddress.equals(ipAddress))) {
                     this.currentNodeIpAddress = ipAddress;
-                    RouteObjectIncludeExclude routeObjectIncludeExclude =
-                        addRouteObjectIncludeExclude(ipAddress, Uint32.valueOf(1),idx);
-                    routeObjectIncludeExcludes.put(routeObjectIncludeExclude.key(),routeObjectIncludeExclude);
+                    RouteObjectIncludeExclude routeObjectIncludeExclude = addRouteObjectIncludeExclude(ipAddress,
+                            Uint32.valueOf(1), idx);
+                    routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
                     idx += 1;
                 }
                 return idx;
@@ -323,7 +336,7 @@ public class GnpyServiceImpl {
             }
             RouteObjectIncludeExclude routeObjectIncludeExclude =
                 addRouteObjectIncludeExclude(fiberIp, Uint32.valueOf(1),idx);
-            routeObjectIncludeExcludes.put(routeObjectIncludeExclude.key(),routeObjectIncludeExclude);
+            routeObjectIncludeExcludes.add(routeObjectIncludeExclude);
             idx += 1;
         }
         return idx;
@@ -333,7 +346,7 @@ public class GnpyServiceImpl {
     private RouteObjectIncludeExclude addRouteObjectIncludeExclude(IpAddress ipAddress, Uint32 teTpValue, Long index) {
         TeNodeId teNodeId = new TeNodeId(ipAddress);
         TeTpId teTpId = new TeTpId(teTpValue);
-        NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev200202.explicit.route.hop.type.num
+        NumUnnumHop numUnnumHop = new org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type.num
             .unnum.hop.NumUnnumHopBuilder()
                 .setNodeId(teNodeId.getIpv4Address().getValue())
                 .setLinkTpId(teTpId.getUint32().toString())
index d8560b60ba9cf315ba583681e91827d22597b736..7f69ba6dc5b12835c96ac2863dc62a384f952cec 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.transportpce.pce.gnpy;
 
 import java.util.ArrayList;
 import java.util.List;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.pce.constraints.PceConstraints;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
@@ -18,9 +19,9 @@ import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.ServiceFile
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.gnpy.api.TopologyFileBuilder;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Connections;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.network.topology.rev181214.topo.Elements;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathRouteObjects;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.synchronization.info.Synchronization;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathRouteObjects;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.synchronization.info.Synchronization;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.PathComputationRequestInput;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirection;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.AToZDirectionBuilder;
@@ -47,8 +48,11 @@ public class GnpyUtilitiesImpl {
     private GnpyResult gnpyAtoZ;
     private GnpyResult gnpyZtoA;
     private Uint32 requestId;
+    private BindingDOMCodecServices bindingDOMCodecServices;
 
-    public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input)
+
+    public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input,
+            BindingDOMCodecServices bindingDOMCodecServices)
         throws GnpyException {
 
         this.networkTransaction = networkTransaction;
@@ -57,6 +61,7 @@ public class GnpyUtilitiesImpl {
         this.gnpyAtoZ = null;
         this.gnpyZtoA = null;
         this.requestId = Uint32.valueOf(0);
+        this.bindingDOMCodecServices = bindingDOMCodecServices;
     }
 
     public boolean verifyComputationByGnpy(AToZDirection atoz, ZToADirection ztoa, PceConstraints pceHardConstraints)
@@ -78,10 +83,10 @@ public class GnpyUtilitiesImpl {
 
     public GnpyResult gnpyResponseOneDirection(GnpyServiceImpl gnpySvc) throws GnpyException, Exception {
         requestId = Uint32.valueOf((requestId.toJava()) + 1);
-        List<PathRequest> pathRequestList = new ArrayList(gnpySvc.getPathRequest().values());
+        List<PathRequest> pathRequestList = new ArrayList<>(gnpySvc.getPathRequest().values());
         List<Synchronization> synchronizationList = gnpySvc.getSynchronization();
         // Send the computed path to GNPY tool
-        List<Elements> elementsList = new ArrayList(gnpyTopo.getElements().values());
+        List<Elements> elementsList = new ArrayList<>(gnpyTopo.getElements().values());
         List<Connections> connectionsList = gnpyTopo.getConnections();
         String gnpyResponse = getGnpyResponse(elementsList, connectionsList, pathRequestList,
             synchronizationList);
@@ -89,7 +94,7 @@ public class GnpyUtilitiesImpl {
         if (gnpyResponse == null) {
             throw new GnpyException("In GnpyUtilities: no response from GNPy server");
         }
-        GnpyResult result = new GnpyResult(gnpyResponse, gnpyTopo);
+        GnpyResult result = new GnpyResult(gnpyResponse, gnpyTopo, bindingDOMCodecServices);
         result.analyzeResult();
         return result;
     }
@@ -125,7 +130,7 @@ public class GnpyUtilitiesImpl {
             .build();
         InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
         String gnpyJson;
-        ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(networkTransaction);
+        ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(bindingDOMCodecServices);
         gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
         LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
         ConnectToGnpyServer connect = new ConnectToGnpyServer();
index e71ee7cbc091a6c965b1017c49b912db4cc0cafb..a51f2d18f0f5a1d3cb92a2945486597e3b551cf2 100644 (file)
@@ -8,17 +8,12 @@
 
 package org.opendaylight.transportpce.pce.gnpy;
 
-import org.opendaylight.transportpce.common.DataStoreContext;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public interface ServiceDataStoreOperations {
 
-    void createXMLFromDevice(DataStoreContext dataStoreContextUtil, OrgOpenroadmDevice device, String output)
-        throws GnpyException;
-
-    String createJsonStringFromDataObject(InstanceIdentifier<?> id, DataObject object) throws GnpyException, Exception;
+    String createJsonStringFromDataObject(InstanceIdentifier<GnpyApi> id, GnpyApi object) throws GnpyException;
 
     void writeStringFile(String jsonString, String fileName) throws GnpyException;
 }
index 5b6ccaf685b041faa1bd47f64d03d1dbca75b2b1..f553d7dee0bc91e10a0704f3738ebf4dcb269f6e 100644 (file)
 package org.opendaylight.transportpce.pce.gnpy;
 
 import com.google.common.collect.FluentIterable;
-import java.io.BufferedWriter;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonWriter;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.transportpce.common.DataStoreContext;
-import org.opendaylight.transportpce.common.converter.XMLDataObjectConverter;
-import org.opendaylight.transportpce.common.network.NetworkTransactionService;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.Result;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
 import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
-    value = "DLS_DEAD_LOCAL_STORE",
-    justification = "FIXME aluminium migration pending: need to convert GNPy to BindingDOMCodecServices")
 public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperations {
 
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceDataStoreOperationsImpl.class);
+    private static final JsonParser PARSER = new JsonParser();
+    private BindingDOMCodecServices bindingDOMCodecServices;
 
-    public ServiceDataStoreOperationsImpl(NetworkTransactionService networkTransactionService) {
+    public ServiceDataStoreOperationsImpl(BindingDOMCodecServices bindingDOMCodecServices) throws GnpyException {
+        this.bindingDOMCodecServices = bindingDOMCodecServices;
     }
 
     @Override
-    public void createXMLFromDevice(DataStoreContext dataStoreContextUtil, OrgOpenroadmDevice device, String output)
+    public String createJsonStringFromDataObject(final InstanceIdentifier<GnpyApi> id, GnpyApi object)
         throws GnpyException {
-
-        if (device != null) {
-            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
-            XMLDataObjectConverter cwDsU = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil);
-            transformIntoNormalizedNode = cwDsU.toNormalizedNodes(device, OrgOpenroadmDevice.class);
-            if (!transformIntoNormalizedNode.isPresent()) {
-                throw new GnpyException(String.format(
-                    "In ServiceDataStoreOperationsImpl: Cannot transform the device %s into normalized nodes",
-                    device.toString()));
-            }
-            Writer writerFromDataObject =
-                cwDsU.writerFromDataObject(device, OrgOpenroadmDevice.class,cwDsU.dataContainer());
-            try (BufferedWriter writer = new BufferedWriter(new FileWriter(output,StandardCharsets.UTF_8))) {
-                writer.write(writerFromDataObject.toString());
-            } catch (IOException e) {
-                throw new GnpyException(
-                    String.format("In ServiceDataStoreOperationsImpl : Bufferwriter error %s",e));
-            }
-            LOG.debug("GNPy: device xml : {}", writerFromDataObject);
-        }
-    }
-
-    @Override
-    public String createJsonStringFromDataObject(final InstanceIdentifier<?> id, DataObject object)
-        throws GnpyException, Exception {
-
         final SchemaPath scPath = SchemaPath.create(FluentIterable
                 .from(id.getPathArguments())
                 .transform(input -> BindingReflections.findQName(input.getType())), true);
-
-        // Prepare the variables
-        // Create the schema context
-        Collection<? extends YangModuleInfo> moduleInfos = Collections.singleton(BindingReflections
-                .getModuleInfo(Result.class));
-        @NonNull
-        EffectiveModelContext schemaContext = BindingRuntimeHelpers.createEffectiveModel(moduleInfos);
-
         /*
          * This function needs : - context - scPath.getParent() -
          * scPath.getLastComponent().getNamespace(), -
          * JsonWriterFactory.createJsonWriter(writer)
          */
-        final Writer writer = new StringWriter();
 
-        try (NormalizedNodeStreamWriter domWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
-                JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.createSimple(schemaContext),
-                scPath.getParent(), scPath.getLastComponent().getNamespace(),
-                JsonWriterFactory.createJsonWriter(writer, 2));) {
-            // The write part
-            //FIXME
-            //codecRegistry.getSerializer(id.getTargetType()).serialize(object, codecRegistry.newWriter(id, domWriter));
+        JSONCodecFactory codecFactory = JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02
+                .getShared(bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext());
+        try (Writer writer = new StringWriter();
+                JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(writer, 2);) {
+            NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter(
+                    codecFactory, scPath.getParent(), scPath.getLastComponent().getNamespace(), jsonWriter);
+            try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStreamWriter)) {
+                nodeWriter.write(bindingDOMCodecServices.toNormalizedNode(id, object).getValue());
+                nodeWriter.flush();
+            }
+            JsonObject asJsonObject = PARSER.parse(writer.toString()).getAsJsonObject();
+            return new Gson().toJson(asJsonObject);
         } catch (IOException e) {
-            throw new GnpyException("In ServiceDataStoreOperationsImpl: exception during json file creation",e);
+            throw new GnpyException("Cannot convert data to Json string", e);
         }
-        return writer.toString();
     }
 
     // Write the json as a string in a file
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/AToZComparator.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/AToZComparator.java
new file mode 100644 (file)
index 0000000..ecdc0c4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright Â© 2020 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.pce.gnpy.utils;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.atoz.direction.AToZ;
+
+@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
+    value = "SE_NO_SERIALVERSIONID",
+    justification = "https://github.com/rzwitserloot/lombok/wiki/WHY-NOT:-serialVersionUID")
+public class AToZComparator implements Comparator<AToZ>, Serializable {
+
+    @Override
+    public int compare(AToZ o1, AToZ o2) {
+        if (o1 == null && o2 == null) {
+            return 0;
+        } else if (o1 == null) {
+            return 1;
+        } else if (o2 == null) {
+            return -1;
+        } else if (o1.getId() == null && o2.getId() == null) {
+            return 0;
+        } else if (o1.getId() == null) {
+            return 1;
+        } else if (o2.getId() == null) {
+            return -1;
+        } else {
+            return Integer.valueOf(o1.getId()).compareTo(Integer.valueOf(o2.getId()));
+        }
+    }
+
+}
diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/ZToAComparator.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/ZToAComparator.java
new file mode 100644 (file)
index 0000000..5e3021f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright Â© 2020 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.pce.gnpy.utils;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev200629.path.description.ztoa.direction.ZToA;
+
+@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
+    value = "SE_NO_SERIALVERSIONID",
+    justification = "https://github.com/rzwitserloot/lombok/wiki/WHY-NOT:-serialVersionUID")
+public class ZToAComparator implements Comparator<ZToA>, Serializable {
+
+    @Override
+    public int compare(ZToA o1, ZToA o2) {
+        if (o1 == null && o2 == null) {
+            return 0;
+        } else if (o1 == null) {
+            return 1;
+        } else if (o2 == null) {
+            return -1;
+        } else if (o1.getId() == null && o2.getId() == null) {
+            return 0;
+        } else if (o1.getId() == null) {
+            return 1;
+        } else if (o2.getId() == null) {
+            return -1;
+        } else {
+            return Integer.valueOf(o1.getId()).compareTo(Integer.valueOf(o2.getId()));
+        }
+    }
+
+}
index 1de4866e145e0bfa75c93c53cc23d6d3ea240a4c..f394e2b0298dd5cbcfb18781886a37b6d1e1f2d2 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.transportpce.pce.networkanalyzer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
@@ -143,12 +144,15 @@ public final class MapUtils {
     }
 
     public static String getSupLink(Link link) {
-        SupportingLink first = link.nonnullSupportingLink().values().iterator().next();
-        if (first != null && first.getLinkRef() != null) {
-            return first.getLinkRef().toString();
-        } else {
+        Iterator<SupportingLink> supportingLinkIterator = link.nonnullSupportingLink().values().iterator();
+        if (!supportingLinkIterator.hasNext()) {
+            return "";
+        }
+        SupportingLink first = supportingLinkIterator.next();
+        if (first == null || first.getLinkRef() == null) {
             return "";
         }
+        return first.getLinkRef().toString();
     }
 
 
index dde21e1a79a0f01e2d09578a94fa998d02ce7af2..720ffcd013e844c19e84cd5574263e59175080d6 100644 (file)
@@ -12,6 +12,8 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import org.eclipse.jdt.annotation.NonNull;
@@ -153,24 +155,31 @@ public class PceLink implements Serializable {
 
     //Compute the OSNR of a span
     public double calcSpanOSNR() {
-        try {
-            double pout; //power on the output of the previous ROADM (dBm)
-            pout = retrievePower(this.omsAttributesSpan.nonnullLinkConcatenation()
-                    .values().iterator().next().getFiberType());
-            double spanLoss = this.omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue(); // span loss (dB)
-            double pin = pout - spanLoss; //power on the input of the current ROADM (dBm)
-            double spanOsnrDb;
-            spanOsnrDb = NOISE_MASK_A * pin + NOISE_MASK_B;
-            if (spanOsnrDb > UPPER_BOUND_OSNR) {
-                spanOsnrDb =  UPPER_BOUND_OSNR;
-            } else if (spanOsnrDb < LOWER_BOUND_OSNR) {
-                spanOsnrDb = LOWER_BOUND_OSNR;
-            }
-            return spanOsnrDb;
-        } catch (NullPointerException e) {
+        if (this.omsAttributesSpan == null) {
+            return 0L;
+        }
+        Collection<LinkConcatenation> linkConcatenationList =
+            this.omsAttributesSpan.nonnullLinkConcatenation().values();
+        if (linkConcatenationList == null) {
             LOG.error("in PceLink : Null field in the OmsAttrubtesSpan");
             return 0L;
         }
+        Iterator<LinkConcatenation> linkConcatenationiterator = linkConcatenationList.iterator();
+        if (!linkConcatenationiterator.hasNext()) {
+            return 0L;
+        }
+        // power on the output of the previous ROADM (dBm)
+        double pout = retrievePower(linkConcatenationiterator.next().getFiberType());
+        // span loss (dB)
+        double spanLoss = this.omsAttributesSpan.getSpanlossCurrent().getValue().doubleValue();
+        double pin = pout - spanLoss; // power on the input of the current ROADM (dBm)
+        double spanOsnrDb = NOISE_MASK_A * pin + NOISE_MASK_B;
+        if (spanOsnrDb > UPPER_BOUND_OSNR) {
+            spanOsnrDb = UPPER_BOUND_OSNR;
+        } else if (spanOsnrDb < LOWER_BOUND_OSNR) {
+            spanOsnrDb = LOWER_BOUND_OSNR;
+        }
+        return spanOsnrDb;
     }
 
     private double retrievePower(FiberType fiberType) {
index e022c91ed70622d8fb5e6d33ad35216d143953ec..c9fd310dfe551dd06a92657db7427a1d30774269 100644 (file)
@@ -16,12 +16,13 @@ import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
 import org.opendaylight.transportpce.common.network.NetworkTransactionService;
 import org.opendaylight.transportpce.pce.PceComplianceCheck;
 import org.opendaylight.transportpce.pce.PceComplianceCheckResult;
 import org.opendaylight.transportpce.pce.PceSendingPceRPCs;
 import org.opendaylight.transportpce.pce.gnpy.GnpyResult;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveInput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveOutput;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.pce.rev200128.CancelResourceReserveOutputBuilder;
@@ -58,13 +59,16 @@ public class PathComputationServiceImpl implements PathComputationService {
     private final NotificationPublishService notificationPublishService;
     private NetworkTransactionService networkTransactionService;
     private final ListeningExecutorService executor;
-    ServicePathRpcResult notification = null;
+    private ServicePathRpcResult notification = null;
+    private BindingDOMCodecServices bindingDOMCodecServices;
 
     public PathComputationServiceImpl(NetworkTransactionService networkTransactionService,
-                                      NotificationPublishService notificationPublishService) {
+                                      NotificationPublishService notificationPublishService,
+                                      BindingDOMCodecServices bindingDOMCodecServices) {
         this.notificationPublishService = notificationPublishService;
         this.networkTransactionService = networkTransactionService;
         this.executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
+        this.bindingDOMCodecServices = bindingDOMCodecServices;
     }
 
     public void init() {
@@ -152,7 +156,8 @@ public class PathComputationServiceImpl implements PathComputationService {
                         RpcStatusEx.Pending, "Service compliant, submitting pathComputation Request ...", null);
                 String message = "";
                 String responseCode = "";
-                PceSendingPceRPCs sendingPCE = new PceSendingPceRPCs(input, networkTransactionService);
+                PceSendingPceRPCs sendingPCE = new PceSendingPceRPCs(input, networkTransactionService,
+                        bindingDOMCodecServices);
                 sendingPCE.pathComputation();
                 message = sendingPCE.getMessage();
                 responseCode = sendingPCE.getResponseCode();
@@ -229,25 +234,26 @@ public class PathComputationServiceImpl implements PathComputationService {
         ResponseType respType = null;
         boolean feasible = true;
         if (responseGnpy != null) {
-            if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result
+            if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result
                     .response.response.type.NoPathCase) {
                 LOG.info("GNPy : path is not feasible");
-                org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.NoPathCase
-                    noPathGnpy = (org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type
+                org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCase
+                    noPathGnpy = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type
                     .NoPathCase) responseGnpy.getResponseType();
                 NoPathCase noPathCase = new NoPathCaseBuilder().setNoPath(noPathGnpy.getNoPath()).build();
                 respType = noPathCase;
                 feasible = false;
-            } else if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result
+            } else if (responseGnpy.getResponseType() instanceof org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result
                     .response.response.type.PathCase) {
                 LOG.info("GNPy : path is feasible");
-                org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.PathCase pathCase =
-                        (org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.PathCase)
+                org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase pathCase =
+                        (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCase)
                         responseGnpy.getResponseType();
-                List<org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties
-                    .PathMetric> pathMetricList = new ArrayList(pathCase.getPathProperties().getPathMetric().values());
+                List<org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties
+                    .PathMetric> pathMetricList =
+                    new ArrayList<>(pathCase.getPathProperties().getPathMetric().values());
                 List<PathMetric> gnpyPathMetricList = new ArrayList<>();
-                for (org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathMetric
+                for (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric
                         pathMetricGnpy : pathMetricList) {
                     PathMetric pathMetric = new PathMetricBuilder().setMetricType(pathMetricGnpy.getMetricType())
                             .setAccumulativeValue(pathMetricGnpy.getAccumulativeValue()).build();
index 1646a68a15b05b573984d32d23981713138b9b97..4f85558d7cf229e7184b78e6485890904779f453 100755 (executable)
@@ -15,6 +15,9 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
 
   <reference id="networkTransactionImpl" interface="org.opendaylight.transportpce.common.network.NetworkTransactionService" />
 
+  <reference id="bindingDOMCodecServices" interface="org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices" />
+
+
   <reference id="dataBroker"
         interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
 
@@ -29,6 +32,7 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
         init-method="init" destroy-method="close">
     <argument ref="networkTransactionImpl"/>
     <argument ref="notificationPublishService" />
+    <argument ref="bindingDOMCodecServices" />
   </bean>
 
   <bean id="provider"
index 34633933490327bcf1414c89014ef07254af7704..788e82c23a84e409b4674151ad9913eb91e1d63b 100644 (file)
@@ -38,7 +38,7 @@ public class PceSendingPceRPCsTest extends AbstractTest {
         networkTransaction = new NetworkTransactionImpl(new RequestProcessor(this.getDataBroker()));
         PceTestUtils.writeNetworkInDataStore(this.getDataBroker());
         pceSendingPceRPCs =
-                new PceSendingPceRPCs(PceTestData.getPCE_test1_request_54(), networkTransaction);
+                new PceSendingPceRPCs(PceTestData.getPCE_test1_request_54(), networkTransaction, null);
     }
 
     @Test
@@ -52,7 +52,7 @@ public class PceSendingPceRPCsTest extends AbstractTest {
         jerseyServer.setUp();
         pceSendingPceRPCs =
                 new PceSendingPceRPCs(PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"),
-                        networkTransaction);
+                        networkTransaction, null);
 
         pceSendingPceRPCs.pathComputation();
         ConnectToGnpyServer connectToGnpy = new ConnectToGnpyServer();
index b8a61a4be0b780069455f52d890246ec066230f8..ff6762ad0c6686ce209728ac2e289ecc61028313 100644 (file)
@@ -23,7 +23,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import org.opendaylight.transportpce.pce.utils.JsonUtil;
 import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.service.PathRequest;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.service.PathRequest;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
index a7cb109215a3b0d587abcf33197f242527c39770..bab81ffd37b7cf95de5cea3ac78bd4e8b66ace41 100644 (file)
@@ -126,7 +126,7 @@ public class GnpyUtilitiesImplTest extends AbstractTest {
     @Test
     public void askNewPathFromGnpyNullResultTest() throws Exception {
         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
-                PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"));
+                PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"), null);
         assertNull("No hard constraints should be available", gnpyUtilitiesImpl.askNewPathFromGnpy(null));
 
     }
@@ -134,7 +134,7 @@ public class GnpyUtilitiesImplTest extends AbstractTest {
     @Test
     public void askNewPathFromGnpyTest() throws Exception {
         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
-                PceTestData.getGnpyPCERequest("XPONDER-3", "XPONDER-4"));
+                PceTestData.getGnpyPCERequest("XPONDER-3", "XPONDER-4"), null);
         PceConstraintsCalc constraints = new PceConstraintsCalc(PceTestData.getPCE_simpletopology_test1_request(),
                 networkTransaction);
         PceConstraints pceHardConstraints = constraints.getPceHardConstraints();
@@ -151,7 +151,7 @@ public class GnpyUtilitiesImplTest extends AbstractTest {
         ZToADirectionBuilder ztoADirectionBldr = buildZtoA();
 
         gnpyUtilitiesImpl = new GnpyUtilitiesImpl(networkTransaction,
-                PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"));
+                PceTestData.getGnpyPCERequest("XPONDER-1", "XPONDER-2"), null);
         PceConstraintsCalc constraints = new PceConstraintsCalc(PceTestData.getPCE_simpletopology_test1_request(),
                 networkTransaction);
         PceConstraints pceHardConstraints = constraints.getPceHardConstraints();
index af17e1cdb20a3774882c0f8b88b950f6f6b18c9b..64a5c728337bca146d7a9286f9549ddaff57d8bd 100644 (file)
@@ -24,15 +24,8 @@ public class ServiceDataStoreOperationsImplTest extends AbstractTest {
     OrgOpenroadmDevice orgOpenroadmDevice = Mockito.mock(OrgOpenroadmDevice.class);
 
     @Before
-    public void setUp() {
-        serviceDataStoreOperations = new ServiceDataStoreOperationsImpl(networkTransaction);
-    }
-
-    // TODO: fix augmentation issue
-    @Test
-    public void createXMLFromDeviceTest() throws GnpyException {
-        serviceDataStoreOperations.createXMLFromDevice(this.getDataStoreContextUtil(),
-                orgOpenroadmDevice, "some-output");
+    public void setUp() throws GnpyException {
+        serviceDataStoreOperations = new ServiceDataStoreOperationsImpl(null);
     }
 
     @Test
index 129339457bcb79f42602668a8be754ce430e1bc4..9b46f6c0c751cf2c811b2e7446406a0a1bc0c4a9 100644 (file)
@@ -44,7 +44,8 @@ public class PceProviderTest extends AbstractTest {
         notificationPublishService = new NotificationPublishServiceMock();
         requestProcessor = Mockito.mock(RequestProcessor.class);
         networkTransaction = new NetworkTransactionImpl(requestProcessor);
-        pathComputationService = new PathComputationServiceImpl(networkTransaction, notificationPublishService);
+        pathComputationService = new PathComputationServiceImpl(networkTransaction, notificationPublishService,
+                null);
         pceProvider = new PceProvider(rpcService, pathComputationService);
     }
 
index a740b19b57555db343ac9f6d8b89906a22f29b82..9e785ad57ea4c3d11d8fc5f965eb0b35c5dbbc91 100644 (file)
@@ -42,7 +42,8 @@ public class PceServiceRPCImplTest extends AbstractTest {
                 TransactionUtils.getNetworkForSpanLoss());
         notificationPublishService = new NotificationPublishServiceMock();
         networkTransaction =  new NetworkTransactionImpl(new RequestProcessor(this.getDataBroker()));
-        pathComputationService = new PathComputationServiceImpl(networkTransaction, notificationPublishService);
+        pathComputationService = new PathComputationServiceImpl(networkTransaction, notificationPublishService,
+                null);
         pceServiceRPC = new PceServiceRPCImpl(pathComputationService);
 
     }
index 35bb8e4bcce828ddb706dd6b9a19cc74dcc4eeca..bae865b44d067a1392e62480d3adde5b26921860 100644 (file)
@@ -26,15 +26,15 @@ import org.opendaylight.transportpce.pce.utils.PceTestData;
 import org.opendaylight.transportpce.pce.utils.PceTestUtils;
 import org.opendaylight.transportpce.pce.utils.TransactionUtils;
 import org.opendaylight.transportpce.test.AbstractTest;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.PathBandwidth;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.PathPropertiesBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathMetric;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.generic.path.properties.path.properties.PathMetricBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.no.path.info.NoPathBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.Response;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.ResponseBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.NoPathCaseBuilder;
-import org.opendaylight.yang.gen.v1.gnpy.path.rev200202.result.response.response.type.PathCaseBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.PathBandwidth;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.PathPropertiesBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetric;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.generic.path.properties.path.properties.PathMetricBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.no.path.info.NoPathBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.Response;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.ResponseBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.NoPathCaseBuilder;
+import org.opendaylight.yang.gen.v1.gnpy.path.rev200909.result.response.response.type.PathCaseBuilder;
 
 
 @Ignore
@@ -54,7 +54,7 @@ public class PathComputationServiceImplTest extends AbstractTest {
         gnpyResult = Mockito.mock(GnpyResult.class);
         pathComputationServiceImpl = new PathComputationServiceImpl(
                 networkTransactionService,
-                this.getNotificationPublishService());
+                this.getNotificationPublishService(), null);
         pathComputationServiceImpl.init();
     }
 
@@ -98,7 +98,7 @@ public class PathComputationServiceImplTest extends AbstractTest {
         GnpyResult gnpyResult2 =
                 new GnpyResult("A-to-Z",
                         new GnpyTopoImpl(new NetworkTransactionImpl(
-                                new RequestProcessor(dataBroker))));
+                                new RequestProcessor(dataBroker))), null);
         pathComputationServiceImpl.generateGnpyResponse(gnpyResult2.getResponse(), "A-to-Z");
     }