From: manuedelf Date: Thu, 4 Feb 2021 09:47:08 +0000 (+0100) Subject: Add generic json String converter X-Git-Tag: 3.0.0~30 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;ds=sidebyside;h=refs%2Fchanges%2F37%2F95037%2F6;p=transportpce.git Add generic json String converter In order to replace DataStoreServiceOperations in PCE, create a generic json string converter in common module. This converter will be used for serialization in nbi notifications module. Signed-off-by: manuedelf Change-Id: I8df37176a349668d5c9191481b9896c95013925a --- diff --git a/common/src/main/java/org/opendaylight/transportpce/common/converter/JsonStringConverter.java b/common/src/main/java/org/opendaylight/transportpce/common/converter/JsonStringConverter.java new file mode 100644 index 000000000..2a071a7eb --- /dev/null +++ b/common/src/main/java/org/opendaylight/transportpce/common/converter/JsonStringConverter.java @@ -0,0 +1,107 @@ +/* + * Copyright © 2021 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.common.converter; + +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.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices; +import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +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.JsonParserStream; +import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory; +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.SchemaPath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JsonStringConverter { + private static final Logger LOG = LoggerFactory.getLogger(JsonStringConverter.class); + private static final JsonParser PARSER = new JsonParser(); + private BindingDOMCodecServices bindingDOMCodecServices; + + + public JsonStringConverter(BindingDOMCodecServices bindingDOMCodecServices) { + this.bindingDOMCodecServices = bindingDOMCodecServices; + } + + /** + * Create a json string from dataobject T. + * @param id InstanceIdentifier + * @param dataObject T + * @param supplier RFC7951 or DRAFT_LHOTKA_NETMOD_YANG_JSON_02 + * @return Json string representation of the object + * @throws IOException if something went wrong. + */ + public String createJsonStringFromDataObject(final InstanceIdentifier id, T dataObject, + JSONCodecFactorySupplier supplier) throws IOException { + 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 = supplier + .getShared(bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext()); + try (Writer writer = new StringWriter(); + JsonWriter jsonWriter = JsonWriterFactory.createJsonWriter(writer, 4);) { + NormalizedNodeStreamWriter jsonStreamWriter = JSONNormalizedNodeStreamWriter.createExclusiveWriter( + codecFactory, scPath.getParent(), scPath.getLastComponent().getNamespace(), jsonWriter); + try (NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStreamWriter)) { + nodeWriter.write(bindingDOMCodecServices.toNormalizedNode(id, dataObject).getValue()); + nodeWriter.flush(); + } + JsonObject asJsonObject = PARSER.parse(writer.toString()).getAsJsonObject(); + return new Gson().toJson(asJsonObject); + } catch (IOException e) { + LOG.error("Cannot convert object {} to string ", dataObject); + throw e; + } + } + + /** + * Create a dataObject of T type from json string. + * @param path YangInstanceIdentifier + * @param jsonString String + * @param supplier RFC7951 or DRAFT_LHOTKA_NETMOD_YANG_JSON_02 + * @return T the created object. + */ + public T createDataObjectFromJsonString(YangInstanceIdentifier path, String jsonString, + JSONCodecFactorySupplier supplier) { + JsonReader reader = new JsonReader(new StringReader(jsonString)); + NormalizedNodeResult result = new NormalizedNodeResult(); + try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + JsonParserStream jsonParser = JsonParserStream.create(streamWriter, + supplier + .getShared(bindingDOMCodecServices.getRuntimeContext().getEffectiveModelContext()))) { + jsonParser.parse(reader); + return (T) bindingDOMCodecServices + .fromNormalizedNode(path, result.getResult()).getValue(); + } catch (IOException e) { + LOG.warn("An error occured during parsing Json input stream", e); + return null; + } + } +} diff --git a/common/src/test/java/org/opendaylight/transportpce/common/converter/JsonStringConverterTest.java b/common/src/test/java/org/opendaylight/transportpce/common/converter/JsonStringConverterTest.java new file mode 100644 index 000000000..4ab67162d --- /dev/null +++ b/common/src/test/java/org/opendaylight/transportpce/common/converter/JsonStringConverterTest.java @@ -0,0 +1,64 @@ +/* + * Copyright © 2021 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.common.converter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.Test; +import org.opendaylight.transportpce.test.AbstractTest; +import org.opendaylight.transportpce.test.converter.DataObjectConverter; +import org.opendaylight.transportpce.test.converter.JSONDataObjectConverter; +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.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier; + +public class JsonStringConverterTest extends AbstractTest { + + @Test + public void createJsonStringFromDataObjectTest() { + DataObjectConverter dataObjectConverter = JSONDataObjectConverter + .createWithDataStoreUtil(getDataStoreContextUtil()); + try (Reader reader = new FileReader("src/test/resources/gnpy_request.json", StandardCharsets.UTF_8)) { + NormalizedNode normalizedNode = dataObjectConverter + .transformIntoNormalizedNode(reader).get(); + GnpyApi gnpyRequest = (GnpyApi) getDataStoreContextUtil().getBindingDOMCodecServices() + .fromNormalizedNode(YangInstanceIdentifier.of(GnpyApi.QNAME), normalizedNode).getValue(); + JsonStringConverter gnpyJsonCOnverter = new JsonStringConverter( + getDataStoreContextUtil().getBindingDOMCodecServices()); + String jsonString = gnpyJsonCOnverter + .createJsonStringFromDataObject(InstanceIdentifier.builder(GnpyApi.class).build(), + gnpyRequest, JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02); + assertEquals("Should be a valid request", + Files.readString(Paths.get("src/test/resources/expected_string.json")), jsonString); + } catch (IOException e) { + fail("Cannot load path description "); + } + } + + @Test + public void createDataObjectFromJsonStringTest() throws IOException { + String json = Files.readString(Paths.get("src/test/resources/expected_string.json")); + JsonStringConverter gnpyJsonCOnverter = new JsonStringConverter( + getDataStoreContextUtil().getBindingDOMCodecServices()); + GnpyApi request = gnpyJsonCOnverter + .createDataObjectFromJsonString(YangInstanceIdentifier.of(GnpyApi.QNAME), json, + JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02); + assertNotNull("Should not be null", request); + } +} diff --git a/common/src/test/resources/expected_string.json b/common/src/test/resources/expected_string.json new file mode 100644 index 000000000..9a7044d6c --- /dev/null +++ b/common/src/test/resources/expected_string.json @@ -0,0 +1 @@ +{"gnpy-api":{"topology-file":{"elements":[{"uid":"127.0.0.31","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-3"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.30","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-3"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.51","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-5"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.50","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-5"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.11","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-1"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.10","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-1"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"243.0.0.10","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.12,"con_out":0,"length":60,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.12","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.11","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.12,"con_out":0,"length":60,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.14","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.13","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.2127659574468085124099303584443987347185611724853515625,"con_out":0,"length":140,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.8","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.11999999999999999555910790149937383830547332763671875,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.9","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.2","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.3","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.12,"con_out":0,"length":60,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.1","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.11999999999999999555910790149937383830547332763671875,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.6","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.2127659574468085124099303584443987347185611724853515625,"con_out":0,"length":140,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.7","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.4","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.29,"con_out":0,"length":100,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"243.0.0.5","metadata":{"location":{"latitude":0,"longitude":0,"city":"N/A","region":"N/A"}},"type":"gnpy-network-topology:Fiber","type_variety":"SSMF","params":{"con_in":0,"loss_coef":0.12,"con_out":0,"length":60,"att_in":0,"length_units":"gnpy-network-topology:km"}},{"uid":"127.0.0.20","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-2"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.41","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-4"}},"type":"gnpy-network-topology:Transceiver"},{"uid":"127.0.0.40","metadata":{"location":{"latitude":0,"longitude":0,"region":"OpenROADM-4"}},"type":"gnpy-network-topology:Roadm","params":{"target_pch_out_db":-20}},{"uid":"127.0.0.21","metadata":{"location":{"latitude":0,"longitude":0,"region":"XPONDER-2"}},"type":"gnpy-network-topology:Transceiver"}],"connections":[{"from_node":"127.0.0.51","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"127.0.0.31"},{"from_node":"127.0.0.10","to_node":"243.0.0.1"},{"from_node":"243.0.0.1","to_node":"127.0.0.30"},{"from_node":"127.0.0.20","to_node":"127.0.0.21"},{"from_node":"127.0.0.20","to_node":"243.0.0.2"},{"from_node":"243.0.0.2","to_node":"127.0.0.10"},{"from_node":"127.0.0.20","to_node":"243.0.0.3"},{"from_node":"243.0.0.3","to_node":"127.0.0.50"},{"from_node":"127.0.0.40","to_node":"127.0.0.41"},{"from_node":"127.0.0.40","to_node":"243.0.0.4"},{"from_node":"243.0.0.4","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"243.0.0.5"},{"from_node":"243.0.0.5","to_node":"127.0.0.30"},{"from_node":"127.0.0.31","to_node":"127.0.0.30"},{"from_node":"127.0.0.50","to_node":"127.0.0.51"},{"from_node":"127.0.0.20","to_node":"243.0.0.6"},{"from_node":"243.0.0.6","to_node":"127.0.0.30"},{"from_node":"127.0.0.30","to_node":"243.0.0.7"},{"from_node":"243.0.0.7","to_node":"127.0.0.40"},{"from_node":"127.0.0.11","to_node":"127.0.0.10"},{"from_node":"127.0.0.30","to_node":"243.0.0.8"},{"from_node":"243.0.0.8","to_node":"127.0.0.10"},{"from_node":"127.0.0.40","to_node":"243.0.0.9"},{"from_node":"243.0.0.9","to_node":"127.0.0.50"},{"from_node":"127.0.0.30","to_node":"243.0.0.10"},{"from_node":"243.0.0.10","to_node":"127.0.0.50"},{"from_node":"127.0.0.50","to_node":"243.0.0.11"},{"from_node":"243.0.0.11","to_node":"127.0.0.20"},{"from_node":"127.0.0.50","to_node":"243.0.0.12"},{"from_node":"243.0.0.12","to_node":"127.0.0.40"},{"from_node":"127.0.0.21","to_node":"127.0.0.20"},{"from_node":"127.0.0.41","to_node":"127.0.0.40"},{"from_node":"127.0.0.30","to_node":"243.0.0.13"},{"from_node":"243.0.0.13","to_node":"127.0.0.20"},{"from_node":"127.0.0.10","to_node":"127.0.0.11"},{"from_node":"127.0.0.10","to_node":"243.0.0.14"},{"from_node":"243.0.0.14","to_node":"127.0.0.20"}]},"service-file":{"path-request":[{"request-id":2,"bidirectional":false,"dst-tp-id":"ZHN0VHBJZA\u003d\u003d","source":"127.0.0.11","explicit-route-objects":{"route-object-include-exclude":[{"num-unnum-hop":{"node-id":"127.0.0.20","link-tp-id":"1","hop-type":"STRICT"},"index":0,"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero"},{"num-unnum-hop":{"node-id":"127.0.0.30","link-tp-id":"1","hop-type":"STRICT"},"index":1,"explicit-route-usage":"gnpy-path-computation-simplified:route-include-ero"}]},"path-constraints":{"te-bandwidth":{"spacing":50000000000,"trx_mode":"W100G","trx_type":"openroadm-beta1","effective-freq-slot":[{"N":0,"M":4}],"technology":"flexi-grid","path_bandwidth":100}},"src-tp-id":"c3JjVHBJZA\u003d\u003d","destination":"127.0.0.41"}]}}} \ No newline at end of file diff --git a/common/src/test/resources/gnpy_request.json b/common/src/test/resources/gnpy_request.json new file mode 100644 index 000000000..0219eef29 --- /dev/null +++ b/common/src/test/resources/gnpy_request.json @@ -0,0 +1,630 @@ +{ + "gnpy-api": { + "topology-file": { + "elements": [ + { + "uid": "127.0.0.40", + "type": "gnpy-network-topology:Roadm", + "metadata": { + "location": { + "region": "OpenROADM-4", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "target_pch_out_db": -20 + } + }, + { + "uid": "127.0.0.50", + "type": "gnpy-network-topology:Roadm", + "metadata": { + "location": { + "region": "OpenROADM-5", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "target_pch_out_db": -20 + } + }, + { + "uid": "127.0.0.20", + "type": "gnpy-network-topology:Roadm", + "metadata": { + "location": { + "region": "OpenROADM-2", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "target_pch_out_db": -20 + } + }, + { + "uid": "127.0.0.10", + "type": "gnpy-network-topology:Roadm", + "metadata": { + "location": { + "region": "OpenROADM-1", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "target_pch_out_db": -20 + } + }, + { + "uid": "127.0.0.30", + "type": "gnpy-network-topology:Roadm", + "metadata": { + "location": { + "region": "OpenROADM-3", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "target_pch_out_db": -20 + } + }, + { + "uid": "127.0.0.11", + "type": "gnpy-network-topology:Transceiver", + "metadata": { + "location": { + "region": "XPONDER-1", + "latitude": 0, + "longitude": 0 + } + } + }, + { + "uid": "127.0.0.51", + "type": "gnpy-network-topology:Transceiver", + "metadata": { + "location": { + "region": "XPONDER-5", + "latitude": 0, + "longitude": 0 + } + } + }, + { + "uid": "127.0.0.41", + "type": "gnpy-network-topology:Transceiver", + "metadata": { + "location": { + "region": "XPONDER-4", + "latitude": 0, + "longitude": 0 + } + } + }, + { + "uid": "127.0.0.31", + "type": "gnpy-network-topology:Transceiver", + "metadata": { + "location": { + "region": "XPONDER-3", + "latitude": 0, + "longitude": 0 + } + } + }, + { + "uid": "127.0.0.21", + "type": "gnpy-network-topology:Transceiver", + "metadata": { + "location": { + "region": "XPONDER-2", + "latitude": 0, + "longitude": 0 + } + } + }, + { + "uid": "243.0.0.1", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.11999999999999999555910790149937383830547332763671875, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.2", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.3", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 60, + "loss_coef": 0.12, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.4", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.5", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 60, + "loss_coef": 0.12, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.6", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 140, + "loss_coef": 0.2127659574468085124099303584443987347185611724853515625, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.7", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.8", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.11999999999999999555910790149937383830547332763671875, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.9", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.10", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 60, + "loss_coef": 0.12, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.11", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 60, + "loss_coef": 0.12, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.12", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.13", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 140, + "loss_coef": 0.2127659574468085124099303584443987347185611724853515625, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + }, + { + "uid": "243.0.0.14", + "type": "gnpy-network-topology:Fiber", + "type_variety": "SSMF", + "metadata": { + "location": { + "city": "N/A", + "region": "N/A", + "latitude": 0, + "longitude": 0 + } + }, + "params": { + "length": 100, + "loss_coef": 0.29, + "length_units": "gnpy-network-topology:km", + "att_in": 0, + "con_in": 0, + "con_out": 0 + } + } + ], + "connections": [ + { + "from_node": "127.0.0.51", + "to_node": "127.0.0.50" + }, + { + "from_node": "127.0.0.30", + "to_node": "127.0.0.31" + }, + { + "from_node": "127.0.0.10", + "to_node": "243.0.0.1" + }, + { + "from_node": "243.0.0.1", + "to_node": "127.0.0.30" + }, + { + "from_node": "127.0.0.20", + "to_node": "127.0.0.21" + }, + { + "from_node": "127.0.0.20", + "to_node": "243.0.0.2" + }, + { + "from_node": "243.0.0.2", + "to_node": "127.0.0.10" + }, + { + "from_node": "127.0.0.20", + "to_node": "243.0.0.3" + }, + { + "from_node": "243.0.0.3", + "to_node": "127.0.0.50" + }, + { + "from_node": "127.0.0.40", + "to_node": "127.0.0.41" + }, + { + "from_node": "127.0.0.40", + "to_node": "243.0.0.4" + }, + { + "from_node": "243.0.0.4", + "to_node": "127.0.0.30" + }, + { + "from_node": "127.0.0.50", + "to_node": "243.0.0.5" + }, + { + "from_node": "243.0.0.5", + "to_node": "127.0.0.30" + }, + { + "from_node": "127.0.0.31", + "to_node": "127.0.0.30" + }, + { + "from_node": "127.0.0.50", + "to_node": "127.0.0.51" + }, + { + "from_node": "127.0.0.20", + "to_node": "243.0.0.6" + }, + { + "from_node": "243.0.0.6", + "to_node": "127.0.0.30" + }, + { + "from_node": "127.0.0.30", + "to_node": "243.0.0.7" + }, + { + "from_node": "243.0.0.7", + "to_node": "127.0.0.40" + }, + { + "from_node": "127.0.0.11", + "to_node": "127.0.0.10" + }, + { + "from_node": "127.0.0.30", + "to_node": "243.0.0.8" + }, + { + "from_node": "243.0.0.8", + "to_node": "127.0.0.10" + }, + { + "from_node": "127.0.0.40", + "to_node": "243.0.0.9" + }, + { + "from_node": "243.0.0.9", + "to_node": "127.0.0.50" + }, + { + "from_node": "127.0.0.30", + "to_node": "243.0.0.10" + }, + { + "from_node": "243.0.0.10", + "to_node": "127.0.0.50" + }, + { + "from_node": "127.0.0.50", + "to_node": "243.0.0.11" + }, + { + "from_node": "243.0.0.11", + "to_node": "127.0.0.20" + }, + { + "from_node": "127.0.0.50", + "to_node": "243.0.0.12" + }, + { + "from_node": "243.0.0.12", + "to_node": "127.0.0.40" + }, + { + "from_node": "127.0.0.21", + "to_node": "127.0.0.20" + }, + { + "from_node": "127.0.0.41", + "to_node": "127.0.0.40" + }, + { + "from_node": "127.0.0.30", + "to_node": "243.0.0.13" + }, + { + "from_node": "243.0.0.13", + "to_node": "127.0.0.20" + }, + { + "from_node": "127.0.0.10", + "to_node": "127.0.0.11" + }, + { + "from_node": "127.0.0.10", + "to_node": "243.0.0.14" + }, + { + "from_node": "243.0.0.14", + "to_node": "127.0.0.20" + } + ] + }, + "service-file": { + "path-request": [ + { + "request-id": 2, + "bidirectional": false, + "source": "127.0.0.11", + "destination": "127.0.0.41", + "src-tp-id": "c3JjVHBJZA==", + "dst-tp-id": "ZHN0VHBJZA==", + "explicit-route-objects": { + "route-object-include-exclude": [ + { + "explicit-route-usage": "gnpy-path-computation-simplified:route-include-ero", + "index": 0, + "num-unnum-hop": { + "node-id": "127.0.0.20", + "link-tp-id": "1", + "hop-type": "STRICT" + } + }, + { + "explicit-route-usage": "gnpy-path-computation-simplified:route-include-ero", + "index": 1, + "num-unnum-hop": { + "node-id": "127.0.0.30", + "link-tp-id": "1", + "hop-type": "STRICT" + } + } + ] + }, + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "openroadm-beta1", + "trx_mode": "W100G", + "effective-freq-slot": [ + { + "N": 0, + "M": 4 + } + ], + "spacing": 50000000000, + "path_bandwidth": 100 + } + } + } + ] + } + } +} \ No newline at end of file