JsonStringConverter in GNPy 38/95038/6
authormanuedelf <emmanuelle.delfour@orange.com>
Thu, 4 Feb 2021 14:34:08 +0000 (15:34 +0100)
committermanuedelf <emmanuelle.delfour@orange.com>
Wed, 10 Feb 2021 18:16:45 +0000 (19:16 +0100)
Replace ServiceDataStoreOperations with use of generic
JsonStringConverter while generating the payload for GNPy request api.

Signed-off-by: manuedelf <emmanuelle.delfour@orange.com>
Change-Id: I7f0d460188a9f5eced0628957c79bc58514d7677

pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyResult.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/GnpyUtilitiesImpl.java
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperations.java [deleted file]
pce/src/main/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImpl.java [deleted file]
pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImplTest.java [deleted file]

index ab127889f9d2834c15dcc08d379bc07343e729a8..a31abefc5dd23e39fec852c1f66a67233c4aa9d6 100644 (file)
@@ -8,13 +8,7 @@
 
 package org.opendaylight.transportpce.pce.gnpy;
 
-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.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -22,11 +16,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Optional;
 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.spi.BindingDOMCodecServices;
+import org.opendaylight.transportpce.common.converter.JsonStringConverter;
 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;
@@ -47,21 +39,10 @@ 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.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.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.EffectiveModelContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -77,39 +58,20 @@ public class GnpyResult {
     private static final Logger LOG = LoggerFactory.getLogger(GnpyResult.class);
     private Response response = null;
     private Map<String, IpAddress> mapNodeRefIp = new HashMap<>();
-    private EffectiveModelContext effectiveModelcontext;
+    private JsonStringConverter<Result> converter;
 
     public GnpyResult(String gnpyResponseString, GnpyTopoImpl gnpyTopo,
             BindingDOMCodecServices bindingDOMCodecServices) throws GnpyException {
         this.mapNodeRefIp = gnpyTopo.getMapNodeRefIp();
-        effectiveModelcontext = bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext();
-
+        this.converter = new JsonStringConverter<>(bindingDOMCodecServices);
         // Create the data object
         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
-        InputStream streamGnpyRespnse = new ByteArrayInputStream(gnpyResponseString.getBytes(StandardCharsets.UTF_8));
-        InputStreamReader gnpyResultReader = new InputStreamReader(streamGnpyRespnse,StandardCharsets.UTF_8);
-        JsonReader jsonReader = new JsonReader(gnpyResultReader);
-        Optional<NormalizedNode<? extends PathArgument, ?>> transformIntoNormalizedNode = parseInputJSON(jsonReader,
-            Result.class);
-        if (!transformIntoNormalizedNode.isPresent()) {
-            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 (fromNormalizedNode != null) {
-            dataObject = fromNormalizedNode.getValue();
-        } else {
-            throw new GnpyException("In GnpyResult: the codec registry from the normalized node is null");
-        }
-        List<Response> responses = new ArrayList<>(((Result) dataObject).nonnullResponse().values());
+        Result result = converter.createDataObjectFromJsonString(yangId, gnpyResponseString,
+                JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
+        List<Response> responses = new ArrayList<>(result.nonnullResponse().values());
         if (responses.isEmpty()) {
             throw new GnpyException("In GnpyResult: the response from GNpy is null!");
         }
@@ -220,67 +182,6 @@ public class GnpyResult {
         return null;
     }
 
-    /**
-     * Parses the input json with concrete implementation of {@link JsonParserStream}.
-     * @param reader of the given JSON
-     * @throws Exception exception
-     */
-    private Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> parseInputJSON(JsonReader reader,
-        Class<? extends DataObject> objectClass) {
-        NormalizedNodeResult result = new NormalizedNodeResult();
-        try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
-            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());
-            return Optional.empty();
-        }
-        return Optional.ofNullable(result.getResult());
-    }
-
-
-    /**
-     * Transforms the given input {@link NormalizedNode} into the given {@link DataObject}.
-     *
-     * @param <T> 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 <T extends DataObject> Optional<T> getDataObject(@Nonnull NormalizedNode<?, ?> normalizedNode,
-        @Nonnull QName rootNode, BindingNormalizedNodeSerializer codecRegistry) {
-        if (normalizedNode != null) {
-            LOG.debug("GNPy: The codecRegistry is {}", codecRegistry);
-        } else {
-            LOG.warn("GNPy: The codecRegistry is null");
-        }
-        //Preconditions.checkNotNull(normalizedNode);
-        if (normalizedNode instanceof ContainerNode) {
-            YangInstanceIdentifier.PathArgument directChildIdentifier = YangInstanceIdentifier.of(rootNode)
-                .getLastPathArgument();
-            Optional<NormalizedNode<?, ?>> directChild = NormalizedNodes.getDirectChild(normalizedNode,
-                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());
-        }
-        YangInstanceIdentifier rootNodeYangInstanceIdentifier = YangInstanceIdentifier.of(rootNode);
-        LOG.debug("GNPy: the root Node Yang Instance Identifier is {}", rootNodeYangInstanceIdentifier);
-        Map.Entry<?, ?> bindingNodeEntry = codecRegistry.fromNormalizedNode(rootNodeYangInstanceIdentifier,
-            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;
     }
index 9a9f2d73199ca215546451655ddcd4e5039799a6..092a13a51ff645e5d31b453d692c50254aea6261 100644 (file)
@@ -8,10 +8,12 @@
 
 package org.opendaylight.transportpce.pce.gnpy;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
+import org.opendaylight.transportpce.common.converter.JsonStringConverter;
 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;
@@ -30,6 +32,7 @@ import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdes
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.routing.constraints.rev171017.routing.constraints.sp.HardConstraints;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,6 +52,7 @@ public class GnpyUtilitiesImpl {
     private GnpyResult gnpyZtoA;
     private Uint32 requestId;
     private BindingDOMCodecServices bindingDOMCodecServices;
+    private JsonStringConverter<GnpyApi> converter;
 
 
     public GnpyUtilitiesImpl(NetworkTransactionService networkTransaction, PathComputationRequestInput input,
@@ -60,6 +64,7 @@ public class GnpyUtilitiesImpl {
         this.gnpyZtoA = null;
         this.requestId = Uint32.valueOf(0);
         this.bindingDOMCodecServices = bindingDOMCodecServices;
+        this.converter =  new JsonStringConverter<>(bindingDOMCodecServices);
     }
 
     public boolean verifyComputationByGnpy(AToZDirection atoz, ZToADirection ztoa, PceConstraints pceHardConstraints)
@@ -137,18 +142,20 @@ public class GnpyUtilitiesImpl {
                         .collect(Collectors.toMap(PathRequest::key, pathRequest -> pathRequest)))
                 .build())
             .build();
-        InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
-        String gnpyJson;
-        ServiceDataStoreOperationsImpl sd = new ServiceDataStoreOperationsImpl(bindingDOMCodecServices);
-        gnpyJson = sd.createJsonStringFromDataObject(idGnpyApi, gnpyApi);
-        LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
-        ConnectToGnpyServer connect = new ConnectToGnpyServer();
-        String gnpyJsonModified = gnpyJson
-            .replace("gnpy-eqpt-config:", "")
-            .replace("gnpy-path-computation-simplified:", "")
-            .replace("gnpy-network-topology:", "");
-
-        return connect.returnGnpyResponse(gnpyJsonModified);
+        try {
+            InstanceIdentifier<GnpyApi> idGnpyApi = InstanceIdentifier.builder(GnpyApi.class).build();
+            String gnpyJson = converter.createJsonStringFromDataObject(idGnpyApi, gnpyApi,
+                    JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02);
+            LOG.debug("GNPy Id: {} / json created : {}", idGnpyApi, gnpyJson);
+            ConnectToGnpyServer connect = new ConnectToGnpyServer();
+            String gnpyJsonModified = gnpyJson.replace("gnpy-eqpt-config:", "")
+                    .replace("gnpy-path-computation-simplified:", "").replace("gnpy-network-topology:", "");
+
+            return connect.returnGnpyResponse(gnpyJsonModified);
+        } catch (IOException e) {
+            LOG.error("Cannot convert data object to json string {}", gnpyApi);
+            throw new GnpyException("Cannot convert data object to json string", e);
+        }
     }
 
     public GnpyResult getGnpyAtoZ() {
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
deleted file mode 100644 (file)
index a51f2d1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright © 2018 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;
-
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public interface ServiceDataStoreOperations {
-
-    String createJsonStringFromDataObject(InstanceIdentifier<GnpyApi> 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
deleted file mode 100644 (file)
index f553d7d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright © 2018 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;
-
-import com.google.common.collect.FluentIterable;
-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 org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yang.gen.v1.gnpy.gnpy.api.rev190103.GnpyApi;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-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.SchemaPath;
-
-public class ServiceDataStoreOperationsImpl implements ServiceDataStoreOperations {
-
-    private static final JsonParser PARSER = new JsonParser();
-    private BindingDOMCodecServices bindingDOMCodecServices;
-
-    public ServiceDataStoreOperationsImpl(BindingDOMCodecServices bindingDOMCodecServices) throws GnpyException {
-        this.bindingDOMCodecServices = bindingDOMCodecServices;
-    }
-
-    @Override
-    public String createJsonStringFromDataObject(final InstanceIdentifier<GnpyApi> id, GnpyApi object)
-        throws GnpyException {
-        final SchemaPath scPath = SchemaPath.create(FluentIterable
-                .from(id.getPathArguments())
-                .transform(input -> BindingReflections.findQName(input.getType())), true);
-        /*
-         * This function needs : - context - scPath.getParent() -
-         * scPath.getLastComponent().getNamespace(), -
-         * JsonWriterFactory.createJsonWriter(writer)
-         */
-
-        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("Cannot convert data to Json string", e);
-        }
-    }
-
-    // Write the json as a string in a file
-    @Override
-    public void writeStringFile(String jsonString, String fileName) throws GnpyException {
-        try (FileWriter file = new FileWriter(fileName,StandardCharsets.UTF_8)) {
-            file.write(jsonString);
-        } catch (IOException e) {
-            throw new GnpyException("In ServiceDataStoreOperationsImpl : exception during file writing",e);
-        }
-    }
-}
diff --git a/pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImplTest.java b/pce/src/test/java/org/opendaylight/transportpce/pce/gnpy/ServiceDataStoreOperationsImplTest.java
deleted file mode 100644 (file)
index 2ea73d3..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright © 2020 Orange Labs, 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;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.transportpce.test.AbstractTest;
-
-public class ServiceDataStoreOperationsImplTest extends AbstractTest {
-
-    private ServiceDataStoreOperationsImpl serviceDataStoreOperations;
-    private BindingDOMCodecServices bindingDOMCodecServices = Mockito.mock(BindingDOMCodecServices.class);
-
-    @Before
-    public void setUp() throws GnpyException {
-        serviceDataStoreOperations = new ServiceDataStoreOperationsImpl(bindingDOMCodecServices);
-    }
-
-    @Test
-    public void writeStringFile() throws GnpyException {
-        serviceDataStoreOperations.writeStringFile("filename","data");
-    }
-}