From: Christophe Betoule Date: Thu, 3 Sep 2020 16:27:08 +0000 (+0200) Subject: GNPy migration to Aluminium X-Git-Tag: 2.0.0~2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=3698762c472dcee815709036258f76af446bec35;p=transportpce.git GNPy migration to Aluminium - 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 Co-authored-by: manuedelf Co-authored-by: Gilles Thouenon Change-Id: Ic9f7d04ab04f963e9c3374637b93b7920fe8a3d8 --- diff --git a/api/src/main/yang/gnpy-path-computation-simplified@2020-02-02.yang b/api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang 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 630887ea3..7275ddf2c 100644 --- a/api/src/main/yang/gnpy-path-computation-simplified@2020-02-02.yang +++ b/api/src/main/yang/gnpy-path-computation-simplified@2020-09-09.yang @@ -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"; diff --git a/pce/pom.xml b/pce/pom.xml index b5447d041..3bfa0f621 100644 --- a/pce/pom.xml +++ b/pce/pom.xml @@ -101,6 +101,11 @@ 1.2.0 test + + org.glassfish.jersey.inject + jersey-hk2 + test + diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java index 93c1b7410..5dc2c9c7f 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/PceSendingPceRPCs.java @@ -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; diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java index 371d32524..392fb377d 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/constraints/PceConstraintsCalc.java @@ -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 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 listHops, PceConstraints constraints) { + Collections.sort(listHops, ORDERED_HOP_COMPARATOR); for (int i = 0; i < listHops.size(); i++) { HopType hoptype = listHops.get(i).getHopType().getHopType(); diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ConnectToGnpyServer.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ConnectToGnpyServer.java index 78980d8ac..a26f19604 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ConnectToGnpyServer.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ConnectToGnpyServer.java @@ -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; } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java index e07756081..b40fc2255 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java @@ -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 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 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 normalizedNode = transformIntoNormalizedNode.get(); + Entry, 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> parseInputJSON(JsonReader reader, - Class objectClass) throws Exception { + Class 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 objectClass) throws GnpyException, Exception { - Collection moduleInfos = Collections.singleton(BindingReflections - .getModuleInfo(objectClass)); - return BindingRuntimeHelpers.createEffectiveModel(moduleInfos); - } /** * Transforms the given input {@link NormalizedNode} into the given {@link DataObject}. diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java index 39f406313..d3d2a5f05 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyServiceImpl.java @@ -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 ROUTE_OBJECT_COMPARATOR = + Comparator.comparing(RouteObjectIncludeExclude::getIndex); private Map pathRequest = new HashMap<>(); private List synchronization = new ArrayList<>(); @@ -88,8 +94,10 @@ public class GnpyServiceImpl { private Map mapFiberIp = new HashMap<>(); private List trxList = new ArrayList<>(); private Map elements = new HashMap<>(); - private Map routeObjectIncludeExcludes = new HashMap<>(); + private List 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 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 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 listAtoZ) throws GnpyException { + private void extractRouteObjectIcludeAtoZ(Collection 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()) diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java index d8560b60b..7f69ba6dc 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java @@ -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 pathRequestList = new ArrayList(gnpySvc.getPathRequest().values()); + List pathRequestList = new ArrayList<>(gnpySvc.getPathRequest().values()); List synchronizationList = gnpySvc.getSynchronization(); // Send the computed path to GNPY tool - List elementsList = new ArrayList(gnpyTopo.getElements().values()); + List elementsList = new ArrayList<>(gnpyTopo.getElements().values()); List 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 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(); diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java index e71ee7cbc..a51f2d18f 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java @@ -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 id, GnpyApi object) throws GnpyException; void writeStringFile(String jsonString, String fileName) throws GnpyException; } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java index 5b6ccaf68..f553d7dee 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java @@ -9,104 +9,63 @@ 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 id, GnpyApi object) throws GnpyException { - - if (device != null) { - Optional> 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 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 index 000000000..ecdc0c4a0 --- /dev/null +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/AToZComparator.java @@ -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, 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 index 000000000..5e3021f6a --- /dev/null +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/utils/ZToAComparator.java @@ -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, 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())); + } + } + +} diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java index 1de4866e1..f394e2b02 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/MapUtils.java @@ -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 supportingLinkIterator = link.nonnullSupportingLink().values().iterator(); + if (!supportingLinkIterator.hasNext()) { + return ""; + } + SupportingLink first = supportingLinkIterator.next(); + if (first == null || first.getLinkRef() == null) { return ""; } + return first.getLinkRef().toString(); } diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java index dde21e1a7..720ffcd01 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/networkanalyzer/PceLink.java @@ -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 linkConcatenationList = + this.omsAttributesSpan.nonnullLinkConcatenation().values(); + if (linkConcatenationList == null) { LOG.error("in PceLink : Null field in the OmsAttrubtesSpan"); return 0L; } + Iterator 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) { diff --git a/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java b/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java index e022c91ed..c9fd310df 100644 --- a/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java +++ b/pce/src/main/java/org/opendaylight/transportpce/pce/service/PathComputationServiceImpl.java @@ -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 pathMetricList = new ArrayList(pathCase.getPathProperties().getPathMetric().values()); + List pathMetricList = + new ArrayList<>(pathCase.getPathProperties().getPathMetric().values()); List 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(); diff --git a/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml b/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml index 1646a68a1..4f85558d7 100755 --- a/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml +++ b/pce/src/main/resources/OSGI-INF/blueprint/pce-blueprint.xml @@ -15,6 +15,9 @@ Author: Martial Coulibaly on behalf of Orange + + + @@ -29,6 +32,7 @@ Author: Martial Coulibaly on behalf of Orange init-method="init" destroy-method="close"> +