X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pce%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fpce%2Fgnpy%2FGnpyResult.java;h=ab127889f9d2834c15dcc08d379bc07343e729a8;hb=bc9a08be9d7cdeb30ecffd3c82ddd656a3a23043;hp=2767005e222a59e9a58afa93560dfabb152b264c;hpb=695a5251d67a1133d16c6b81b6bc45d646a671ad;p=transportpce.git 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 2767005e2..ab127889f 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 @@ -8,38 +8,32 @@ package org.opendaylight.transportpce.pce.gnpy; -import com.google.common.base.Preconditions; import com.google.gson.stream.JsonReader; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; - -import javassist.ClassPool; - +import java.util.stream.Collectors; import javax.annotation.Nonnull; - import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; -import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator; -import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext; -import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; -import org.opendaylight.mdsal.binding.generator.util.JavassistUtils; -import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.Result; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.explicit.route.hop.type.num.unnum.hop.NumUnnumHop; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.properties.path.properties.PathMetric; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.generic.path.properties.path.properties.PathRouteObjects; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.result.Response; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.result.response.response.type.NoPathCase; -import org.opendaylight.yang.gen.v1.gnpy.path.rev190502.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,20 +45,23 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.ordered.constraints.sp.hop.type.hop.type.NodeBuilder; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints; import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraintsBuilder; +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; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +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; @@ -79,50 +76,44 @@ public class GnpyResult { private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class); private Response response = null; + private Map mapNodeRefIp = new HashMap<>(); + private EffectiveModelContext effectiveModelcontext; - public GnpyResult(String gnpyResponseString) throws Exception { - - // Create the schema context - final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); - Iterable moduleInfos; - moduleInfos = Collections.singleton(BindingReflections.getModuleInfo(Result.class)); - moduleContext.addModuleInfos(moduleInfos); - SchemaContext schemaContext = moduleContext.tryToCreateSchemaContext().get(); - - // Create the binding binding normalized node codec registry - BindingRuntimeContext bindingRuntimeContext = BindingRuntimeContext.create(moduleContext, schemaContext); - final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry( - StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()))); - codecRegistry.onBindingRuntimeContextUpdated(bindingRuntimeContext); + public GnpyResult(String gnpyResponseString, GnpyTopoImpl gnpyTopo, + BindingDOMCodecServices bindingDOMCodecServices) throws GnpyException { + this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp(); + effectiveModelcontext = bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext(); // Create the data object - QName pathQname = QName.create("gnpy:path", "2019-05-02", "result"); - LOG.debug("the Qname is {} / namesapce {} ; module {}; ", pathQname.toString(), pathQname.getNamespace(), - pathQname.getModule()); + 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); DataObject dataObject = null; - //Create the object response - //Create JsonReader from String + + // Create the object response InputStream streamGnpyRespnse = new ByteArrayInputStream(gnpyResponseString.getBytes(StandardCharsets.UTF_8)); - InputStreamReader gnpyResultReader = new InputStreamReader(streamGnpyRespnse); + InputStreamReader gnpyResultReader = new InputStreamReader(streamGnpyRespnse,StandardCharsets.UTF_8); JsonReader jsonReader = new JsonReader(gnpyResultReader); Optional> transformIntoNormalizedNode = parseInputJSON(jsonReader, - Result.class); + Result.class); + if (!transformIntoNormalizedNode.isPresent()) { + throw new GnpyException("In GnpyResult: the Normalized Node is not present"); + } NormalizedNode normalizedNode = transformIntoNormalizedNode.get(); - if (codecRegistry.fromNormalizedNode(yangId, normalizedNode) != null) { - LOG.debug("The key of the generated object", - codecRegistry.fromNormalizedNode(yangId, normalizedNode).getKey()); - dataObject = codecRegistry.fromNormalizedNode(yangId, normalizedNode).getValue(); + Entry, DataObject> fromNormalizedNode = bindingDOMCodecServices + .fromNormalizedNode(yangId, normalizedNode); + + if (fromNormalizedNode != null) { + dataObject = fromNormalizedNode.getValue(); } else { - LOG.warn("The codec registry from the normalized node is null!"); + throw new GnpyException("In GnpyResult: the codec registry from the normalized node is null"); } - List responses = null; - responses = ((Result) dataObject).getResponse(); - if (responses != null) { - LOG.info("The response id is {}; ", responses.get(0).getResponseId()); - } else { - LOG.warn("The response is null!"); + List responses = new ArrayList<>(((Result) dataObject).nonnullResponse().values()); + if (responses.isEmpty()) { + throw new GnpyException("In GnpyResult: the response from GNpy is null!"); } + LOG.info("The response id is {}; ", responses.get(0).getResponseId()); this.response = responses.get(0); analyzeResult(); } @@ -131,27 +122,27 @@ public class GnpyResult { boolean isFeasible = false; if (response != null) { if (response.getResponseType() instanceof NoPathCase) { - isFeasible = false; - LOG.info("The path is not feasible "); + LOG.info("In GnpyResult: The path is not feasible "); } else if (response.getResponseType() instanceof PathCase) { isFeasible = true; - LOG.info("The path is feasible "); + LOG.info("In GnpyResult: The path is feasible "); } } return isFeasible; } - public void analyzeResult() { + public List analyzeResult() { + List pathRouteObjectList = null; if (response != null) { - Long responseId = response.getResponseId(); - LOG.info("Response-Id {}", responseId); if (response.getResponseType() instanceof NoPathCase) { NoPathCase noPathCase = (NoPathCase) response.getResponseType(); String noPathType = noPathCase.getNoPath().getNoPath(); - LOG.info("GNPy: No path - {}",noPathType); - if (((noPathType == "NO_FEASIBLE_BAUDRATE_WITH_SPACING") && (noPathType == "NO_FEASIBLE_MODE")) - && ((noPathType == "MODE_NOT_FEASIBLE") && (noPathType == "NO_SPECTRUM"))) { - List pathMetricList = noPathCase.getNoPath().getPathProperties().getPathMetric(); + LOG.info("GNPy: No path - {}", noPathType); + if (((noPathType.equals("NO_FEASIBLE_BAUDRATE_WITH_SPACING")) + && (noPathType.equals("NO_FEASIBLE_MODE"))) && ((noPathType.equals("MODE_NOT_FEASIBLE")) + && (noPathType.equals("NO_SPECTRUM")))) { + Collection pathMetricList = noPathCase.getNoPath() + .getPathProperties().nonnullPathMetric().values(); LOG.info("GNPy : path is not feasible : {}", noPathType); for (PathMetric pathMetric : pathMetricList) { String metricType = pathMetric.getMetricType().getSimpleName(); @@ -162,79 +153,85 @@ public class GnpyResult { } else if (response.getResponseType() instanceof PathCase) { LOG.info("GNPy : path is feasible"); PathCase pathCase = (PathCase) response.getResponseType(); - List pathMetricList = pathCase.getPathProperties().getPathMetric(); + Collection pathMetricList = pathCase + .getPathProperties().nonnullPathMetric().values(); + // Path metrics for (PathMetric pathMetric : pathMetricList) { String metricType = pathMetric.getMetricType().getSimpleName(); BigDecimal accumulativeValue = pathMetric.getAccumulativeValue(); LOG.info("Metric type {} // AccumulatriveValue {}", metricType, accumulativeValue); } + // Path route objects + pathRouteObjectList = pathCase.getPathProperties().getPathRouteObjects(); + LOG.info("in GnpyResult: finishing the computation of pathRouteObjectList"); } } + return pathRouteObjectList; } - public HardConstraints analyzeGnpyPath() { + public HardConstraints computeHardConstraintsFromGnpyPath(List pathRouteObjectList) { HardConstraints hardConstraints = null; - if (response != null) { - Long responseId = response.getResponseId(); - LOG.info("Response-Id {}", responseId); - if (response.getResponseType() instanceof NoPathCase) { - NoPathCase noPathCase = (NoPathCase) response.getResponseType(); - LOG.info("No path feasible {}", noPathCase.toString()); - } else if (response.getResponseType() instanceof PathCase) { - PathCase pathCase = (PathCase) response.getResponseType(); - List pathMetricList = pathCase.getPathProperties().getPathMetric(); - for (PathMetric pathMetric : pathMetricList) { - String metricType = pathMetric.getMetricType().getSimpleName(); - BigDecimal accumulativeValue = pathMetric.getAccumulativeValue(); - LOG.info("Metric type {} // AccumulatriveValue {}", metricType, accumulativeValue); - } - - // Includes the list of nodes in the GNPy computed path as constraints for the PCE - List orderedHopsList = null; - List pathRouteObjectList = pathCase.getPathProperties().getPathRouteObjects(); - int counter = 0; - for (PathRouteObjects pathRouteObjects : pathRouteObjectList) { - if (pathRouteObjects.getPathRouteObject().getType() instanceof NumUnnumHop) { - NumUnnumHop numUnnumHop = (NumUnnumHop) pathRouteObjects.getPathRouteObject().getType(); - String nodeId = numUnnumHop.getNodeId(); + // Includes the list of nodes in the GNPy computed path as constraints + // for the PCE + List orderedHopsList = new ArrayList<>(); + int counter = 0; + for (PathRouteObjects pathRouteObjects : pathRouteObjectList) { + if (pathRouteObjects.getPathRouteObject().getType() instanceof NumUnnumHop) { + NumUnnumHop numUnnumHop = (org.opendaylight.yang.gen.v1.gnpy.path.rev200909.explicit.route.hop.type + .NumUnnumHop) pathRouteObjects.getPathRouteObject().getType(); + String nodeIp = numUnnumHop.getNumUnnumHop().getNodeId(); + try { + IpAddress nodeIpAddress = new IpAddress(new Ipv4Address(nodeIp)); + // find the corresponding node-id (in ord-ntw) corresponding to nodeId (in gnpy response) + String nodeId = findOrdNetworkNodeId(nodeIpAddress); + if (nodeId != null) { org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017 - .ordered.constraints.sp.hop.type.hop.type.Node node = new NodeBuilder() - .setNodeId(nodeId).build(); + .ordered.constraints.sp.hop.type.hop.type.Node node = new NodeBuilder().setNodeId(nodeId) + .build(); HopType hopType = new HopTypeBuilder().setHopType(node).build(); - OrderedHops orderedHops = new OrderedHopsBuilder().setHopNumber(counter).setHopType(hopType) - .build(); - LOG.info("- gnpyResult class : Hard Constraint: {} // - Hop Node {}", counter, nodeId); + OrderedHops orderedHops = new OrderedHopsBuilder() + .setHopNumber(Uint16.valueOf(counter)).setHopType(hopType) + .build(); orderedHopsList.add(orderedHops); counter++; } + } catch (IllegalArgumentException e) { + LOG.debug(" in GnpyResult: the element {} is not a ipv4Address ", nodeIp); } - Include include = new IncludeBuilder().setOrderedHops(orderedHopsList).build(); - General general = new GeneralBuilder().setInclude(include).build(); - hardConstraints = new HardConstraintsBuilder().setCoRoutingOrGeneral(general).build(); } } + Include include = new IncludeBuilder() + .setOrderedHops(orderedHopsList.stream() + .collect(Collectors.toMap(OrderedHops::key, orderedHops -> orderedHops))) + .build(); + General general = new GeneralBuilder().setInclude(include).build(); + hardConstraints = new HardConstraintsBuilder().setCoRoutingOrGeneral(general).build(); return hardConstraints; } + private String findOrdNetworkNodeId(IpAddress nodeIpAddress) { + Iterator> it = this.mapNodeRefIp.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getValue().equals(nodeIpAddress)) { + return entry.getKey(); + } + } + return null; + } + /** - * Parses the input json with concrete implementation of - * {@link JsonParserStream}. - * - * @param reader - * of the given JSON - * @throws Exception - * + * Parses the input json with concrete implementation of {@link JsonParserStream}. + * @param reader of the given JSON + * @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, schemaContext, schemaContext);) { - LOG.debug("GNPy: the path to the reader {}", reader.getPath()); - LOG.debug("GNPy: the reader {}", reader.toString()); - LOG.debug("GNPy: the jsonParser class {} // jsonParser to string {}", jsonParser.getClass(), - jsonParser.toString()); + JsonParserStream jsonParser = JsonParserStream.create(streamWriter, + 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()); @@ -243,56 +240,48 @@ public class GnpyResult { return Optional.ofNullable(result.getResult()); } - private SchemaContext getSchemaContext(Class objectClass) throws Exception { - final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create(); - Iterable moduleInfos; - SchemaContext schemaContext = null; - moduleInfos = Collections.singleton(BindingReflections.getModuleInfo(objectClass)); - moduleContext.addModuleInfos(moduleInfos); - schemaContext = moduleContext.tryToCreateSchemaContext().get(); - return schemaContext; - } /** - * Transforms the given input {@link NormalizedNode} into the given - * {@link DataObject}. - * - * @param normalizedNode - * normalized node you want to convert - * @param rootNode - * {@link QName} of converted normalized node root + * Transforms the given input {@link NormalizedNode} into the given {@link DataObject}. * - *

- * The input object should be {@link ContainerNode} - *

+ * @param a generic + * @param normalizedNode a non null representation of the normalizedNode + * @param rootNode root node + * @param codecRegistry codec registry + * @return value of the binding Node Entry */ + @SuppressWarnings("unchecked") public Optional getDataObject(@Nonnull NormalizedNode normalizedNode, - @Nonnull QName rootNode, BindingNormalizedNodeSerializer codecRegistry) { + @Nonnull QName rootNode, BindingNormalizedNodeSerializer codecRegistry) { if (normalizedNode != null) { - LOG.debug("GNPy: The codecRegistry is ", codecRegistry.toString()); + LOG.debug("GNPy: The codecRegistry is {}", codecRegistry); } else { LOG.warn("GNPy: The codecRegistry is null"); } - Preconditions.checkNotNull(normalizedNode); + //Preconditions.checkNotNull(normalizedNode); if (normalizedNode instanceof ContainerNode) { YangInstanceIdentifier.PathArgument directChildIdentifier = YangInstanceIdentifier.of(rootNode) - .getLastPathArgument(); + .getLastPathArgument(); Optional> directChild = NormalizedNodes.getDirectChild(normalizedNode, - directChildIdentifier); + directChildIdentifier); if (!directChild.isPresent()) { throw new IllegalStateException(String.format("Could not get the direct child of %s", rootNode)); } normalizedNode = directChild.get(); - LOG.debug("GNPy: the normalized node is ", normalizedNode.getNodeType()); + LOG.debug("GNPy: the normalized node is {}", normalizedNode.getNodeType()); } YangInstanceIdentifier rootNodeYangInstanceIdentifier = YangInstanceIdentifier.of(rootNode); - LOG.debug("GNPy: the root Node Yang Instance Identifier is ", rootNodeYangInstanceIdentifier.toString()); + LOG.debug("GNPy: the root Node Yang Instance Identifier is {}", rootNodeYangInstanceIdentifier); Map.Entry bindingNodeEntry = codecRegistry.fromNormalizedNode(rootNodeYangInstanceIdentifier, - normalizedNode); + normalizedNode); if (bindingNodeEntry == null) { LOG.debug("The binding Node Entry is null"); return Optional.empty(); } return Optional.ofNullable((T) bindingNodeEntry.getValue()); } + + public Response getResponse() { + return response; + } }