Merge "Fix functional tests 2.2.1 sequence"
authorGuillaume Lambert <guillaume.lambert@orange.com>
Wed, 10 Nov 2021 19:19:33 +0000 (19:19 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 10 Nov 2021 19:19:33 +0000 (19:19 +0000)
49 files changed:
api/pom.xml
common/pom.xml
dmaap-client/pom.xml
docs/developer-guide.rst
docs/images/TransportPCE-Diagram-Phosphorus.jpg [new file with mode: 0644]
docs/images/TransportPCE-tapi-abstraction.jpg
docs/user-guide.rst
features/odl-transportpce-dmaap-client/pom.xml
features/odl-transportpce-inventory/pom.xml
features/odl-transportpce-nbinotifications/pom.xml
features/odl-transportpce-swagger/pom.xml
features/odl-transportpce-tapi/pom.xml
features/odl-transportpce/pom.xml
features/pom.xml
inventory/pom.xml
karaf/pom.xml
nbinotifications/pom.xml
networkmodel/pom.xml
olm/pom.xml
olm/src/main/java/org/opendaylight/transportpce/olm/service/OlmPowerServiceImpl.java
olm/src/main/java/org/opendaylight/transportpce/olm/util/OlmUtils221.java
ordmodels/common/pom.xml
ordmodels/device/pom.xml
ordmodels/network/pom.xml
ordmodels/pom.xml
ordmodels/service/pom.xml
pce/pom.xml
pom.xml
renderer/pom.xml
servicehandler/pom.xml
tapi/pom.xml
tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImpl.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiFullTopo.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiTopo.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkModelServiceImpl.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImpl.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TopologyUtils.java
tapi/src/main/java/org/opendaylight/transportpce/tapi/utils/TapiContext.java
tapi/src/test/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImplTest.java [new file with mode: 0644]
tapi/src/test/java/org/opendaylight/transportpce/tapi/provider/TapiProviderTest.java [new file with mode: 0644]
tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToFullTapiTopoTest.java [new file with mode: 0644]
tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToTapiTopoTest.java
tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/TapiTopologyImplTest.java
tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiConnectivityDataUtils.java [new file with mode: 0644]
tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiTopologyDataUtils.java
tapimodels/pom.xml
test-common/pom.xml
tests/transportpce_tests/2.2.1/test12_tapi_full_multi_layer.py [new file with mode: 0644]
tests/transportpce_tests/common/test_utils.py

index 5b787459c67c08c91c9cb1e5fa900b6448de5de0..c78d64d889aa2bb91d40b631f4c0ee6834d12544 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index dbc4b9465677c56be6c2a9178079b1a036355bc3..fe5e8b1b404215970da97c59d0178525f441c9a2 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
 
@@ -24,7 +24,7 @@
             <dependency>
                 <groupId>org.opendaylight.netconf</groupId>
                 <artifactId>netconf-artifacts</artifactId>
-                <version>2.0.5</version>
+                <version>2.0.7</version>
                 <scope>import</scope>
                 <type>pom</type>
             </dependency>
index c31de1313f7c37f4689de26e55c30ce0bddbf4c8..57d2e1d616df2916547f6516aeaf63b7cf992f0a 100644 (file)
@@ -9,7 +9,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
     <groupId>org.opendaylight.transportpce</groupId>
index 2e3389c4dcd314057d6a0c1ba9db16db3177a3f8..1e6e5d3080246dde822c36336065e99c14b7d24e 100644 (file)
@@ -28,7 +28,7 @@ equipment\_ and Optical Line Management (OLM) is associated with a generic block
 relying on open models, each of them communicating through published APIs.
 
 
-.. figure:: ./images/TransportPCE-Diagramm-Magnesium.jpg
+.. figure:: ./images/TransportPCE-Diagram-Phosphorus.jpg
    :alt: TransportPCE architecture
 
    TransportPCE architecture
@@ -38,7 +38,7 @@ of WDM transport infrastructure. The WDM layer is built from colorless ROADMs
 and transponders.
 
 The interest of using a controller to provision automatically services strongly
-relies on its ability to handle end to end optical services that spans through
+relies on its ability to handle end to end optical services that span through
 the different network domains, potentially equipped with equipment coming from
 different suppliers. Thus, interoperability in the optical layer is a key
 element to get the benefit of automated control.
@@ -48,17 +48,31 @@ which defines interoperability specifications, consisting of both Optical
 interoperability and Yang data models.
 
 End to end OTN services such as OCH-OTU4, structured ODU4 or 10GE-ODU2e
-services are supported since Magnesium SR2. OTN support will continue to be
+services are supported since Magnesium SR2. OTN support continued to be
 improved in the following releases of Magnesium and Aluminium.
 
-An experimental support of Flexgrid is introduced in Aluminium. Depending on
-OpenROADM device models, optical interfaces can be created according to the
-initial fixed grid (for R1.2.1, 96 channels regularly spaced of 50 GHz), or to
-a flexgrid (for R2.2.1 use of specific number of subsequent frequency slots of
-6.25 GHz depending on one side of ROADMs and transponders capabilities and on
-the other side of the rate of the channel. The full support of Flexgrid,
-including path computation and the creation of B100G (Beyond 100 Gbps) higher
-rate interfaces will be added in the following releases of Aluminium.
+Flexgrid was introduced in Aluminium. Depending on OpenROADM device models,
+optical interfaces can be created according to the initial fixed grid (for
+R1.2.1, 96 channels regularly spaced of 50 GHz), or to a flexgrid (for R2.2.1
+use of specific number of subsequent frequency slots of 6.25 GHz depending on
+one side of ROADMs and transponders capabilities and on the other side of the
+rate of the channel.
+
+Leveraging Flexgrid feature, high rate services are supported since Silicon.
+First implementation allows rendering 400 GE services. This release also brings
+asynchronous service creation and deletion, thanks to northbound notifications
+modules based on a Kafka implementation, allowing interactions with the DMaaP
+Bus of ONAP.
+
+Phosphorus consolidates end to end support for high rate services (ODUC4, OTUC4),
+allowing service creation and deletion from the NBI. The support of path
+computation for high rate services (OTUC4) will be added through the different P
+releases, relying on GNPy for impairment aware path computation. An experimental
+support of T-API is provided allowing service-create/delete from a T-API version
+2.1.1 compliant NBI. A T-API network topology, with different levels of abstraction
+and service context are maintained in the MDSAL. Service state is managed,
+monitoring device port state changes. Associated notifications are handled through
+Kafka and  DMaaP clients.
 
 
 Module description
@@ -67,24 +81,31 @@ Module description
 ServiceHandler
 ^^^^^^^^^^^^^^
 
-Service Handler handles request coming from a higher level controller or an orchestrator
-through the northbound API, as defined in the Open ROADM service model. Current
-implementation addresses the following rpcs: service-create, temp-service-create,
-service–delete, temp-service-delete, service-reroute, and service-restoration. It checks the
-request consistency and trigs path calculation sending rpcs to the PCE. If a valid path is
-returned by the PCE, path configuration is initiated relying on Renderer and OLM. At the
-confirmation of a successful service creation, the Service Handler updates the service-
-list/temp-service-list in the MD-SAL. For service deletion, the Service Handler relies on the
-Renderer and the OLM to delete connections and reset power levels associated with the
-service. The service-list is updated following a successful service deletion. In Neon SR0 is
-added the support for service from ROADM to ROADM, which brings additional flexibility and
-notably allows reserving resources when transponders are not in place at day one.
-Magnesium SR2 fully supports end-to-end OTN services which are part of the OTN infrastructure.
-It concerns the management of OCH-OTU4 (also part of the optical infrastructure) and structured
-HO-ODU4 services. Moreover, once these two kinds of OTN infrastructure service created, it is
-possible to manage some LO-ODU services (for the time being, only 10GE-ODU2e services).
-The full support of OTN services, including 1GE-ODU0 or 100GE, will be introduced along next
-releases (Mg/Al).
+Service Handler handles request coming from a higher level controller or an
+orchestrator through the northbound API, as defined in the Open ROADM service model.
+Current implementation addresses the following rpcs: service-create, temp-service-
+create, service–delete, temp-service-delete, service-reroute, and service-restoration.
+It checks the request consistency and trigs path calculation sending rpcs to the PCE.
+If a valid path is returned by the PCE, path configuration is initiated relying on
+Renderer and OLM. At the confirmation of a successful service creation, the Service
+Handler updates the service-list/temp-service-list in the MD-SAL. For service deletion,
+the Service Handler relies on the Renderer and the OLM to delete connections and reset
+power levels associated with the service. The service-list is updated following a
+successful service deletion. In Neon SR0 is added the support for service from ROADM
+to ROADM, which brings additional flexibility and notably allows reserving resources
+when transponders are not in place at day one. Magnesium SR2 fully supports end-to-end
+OTN services which are part of the OTN infrastructure. It concerns the management of
+OCH-OTU4 (also part of the optical infrastructure) and structured HO-ODU4 services.
+Moreover, once these two kinds of OTN infrastructure service created, it is possible
+to manage some LO-ODU services (1GE-ODU0, 10GE-ODU2e). 100GE services are also
+supported over ODU4 in transponders or switchponders using higher rate network
+interfaces.
+
+In Silicon release, the management of TopologyUpdateNotification coming from the *Topology Management*
+module was implemented. This functionality enables the controller to update the information of existing
+services according to the online status of the network infrastructure. If any service is affected by
+the topology update and the *odl-transportpce-nbi* feature is installed, the Service Handler will send a
+notification to a Kafka server with the service update information.
 
 PCE
 ^^^
@@ -115,7 +136,9 @@ PCE handles the following constraints as hard constraints:
 
 In Magnesium SR0, the interconnection of the PCE with GNPY (Gaussian Noise Python), an
 open-source library developed in the scope of the Telecom Infra Project for building route
-planning and optimizing performance in optical mesh networks, is fully supported.
+planning and optimizing performance in optical mesh networks, is fully supported. Impairment
+aware path computation for service of higher rates (Beyond 100G) is planned across Phoshorus
+releases. It implies to make B100G OpenROADM specifications available in GNPy libraries.
 
 If the OSNR calculated by the PCE is too close to the limit defined in OpenROADM
 specifications, the PCE forwards through a REST interface to GNPY external tool the topology
@@ -124,9 +147,9 @@ Transmission metrics for this path using its own library which includes models f
 The result is sent back to the PCE. If the path is validated, the PCE sends back a response to
 the service handler. In case of invalidation of the path by GNPY, the PCE sends a new request to
 GNPY, including only the constraints expressed in the path-computation-request initiated by the
-Service Handler. GNPy then tries to calculate a path based on these relaxed constraints. The result
-of the path computation is provided to the PCE which translates the path according to the topology
-handled in transportPCE and forwards the results to the Service Handler.
+Service Handler. GNPy then tries to calculate a path based on these relaxed constraints. The
+result of the path computation is provided to the PCE which translates the path according to the
+topology handled in transportPCE and forwards the results to the Service Handler.
 
 GNPy relies on SNR and takes into account the linear and non-linear impairments
 to check feasibility. In the related tests, GNPy module runs externally in a
@@ -152,6 +175,11 @@ It includes several network layers:
    The population of OTN links (OTU4 and ODU4), and the adjustment of the tributary ports/slots
    pool occupancy when OTN services are created is supported since Magnesium SR2.**
 
+Since Silicon release, the Topology Management module process NETCONF event received through an
+event stream (as defined in RFC 5277) between devices and the NETCONF adapter of the controller.
+Current implementation detects device configuration changes and updates the topology datastore accordingly.
+Then, it sends a TopologyUpdateNotification to the *Service Handler* to indicate that a change has been
+detected in the network that may affect some of the already existing services.
 
 Renderer
 ^^^^^^^^
@@ -170,7 +198,9 @@ In Neon (SR0), portmapping module has been enriched to support both openroadm 1.
 device models. The full support of openroadm 2.2.1 device models (both in the topology management
 and the rendering function) has been added in Neon SR1. In Magnesium, portmapping is enriched with
 the supported-interface-capability, OTN supporting-interfaces, and switching-pools (reflecting
-cross-connection capabilities of OTN switch-ponders).
+cross-connection capabilities of OTN switch-ponders). The support for 7.1 devices models is
+introduced in Silicon (no devices of intermediate releases have been proposed and made available
+to the market by equipment manufacturers).
 
 After the path is provided, the renderer first checks what are the existing interfaces on the
 ports of the different nodes that the path crosses. It then creates missing interfaces. After all
@@ -183,8 +213,14 @@ rollback function is called to set the equipment on the path back to their initi
 Magnesium brings the support of OTN services. SR0 supports the creation of OTU4, ODU4, ODU2/ODU2e
 and ODU0 interfaces. The creation of these low-order otn interfaces must be triggered through
 otn-service-path RPC. Magnesium SR2 fully supports end-to-end otn service implementation into devices
-(service-implementation-request /service delete rpc, topology alignement after the service has been created).
+(service-implementation-request /service delete rpc, topology alignement after the service
+has been created).
 
+In Silicon releases, higher rate OTN interfaces (OTUC4) must be triggered through otn-service-
+path RPC. Phosphorus SR0 supports end-to-end otn service implementation into devices
+(service-implementation-request /service delete rpc, topology alignement after the service
+has been created). One shall note that impairment aware path calculation for higher rates will
+be made available across the Phosphorus release train.
 
 OLM
 ^^^
@@ -211,15 +247,15 @@ and the configuration was successfully completed.
 Inventory
 ^^^^^^^^^
 
-TransportPCE Inventory module is responsible to keep track of devices connected in an external MariaDB database.
-Other databases may be used as long as they comply with SQL and are compatible with OpenDaylight (for example MySQL).
-At present, the module supports extracting and persisting inventory of devices OpenROADM MSA version 1.2.1.
-Inventory module changes to support newer device models (2.2.1, etc) and other models (network, service, etc)
-will be progressively included.
+TransportPCE Inventory module is responsible to keep track of devices connected in an external
+MariaDB database. Other databases may be used as long as they comply with SQL and are compatible
+with OpenDaylight (for example MySQL). At present, the module supports extracting and persisting
+inventory of devices OpenROADM MSA version 1.2.1. Inventory module changes to support newer device
+models (2.2.1, etc) and other models (network, service, etc) will be progressively included.
 
 The inventory module can be activated by the associated karaf feature (odl-transporpce-inventory)
-The database properties are supplied in the “opendaylight-release” and “opendaylight-snapshots” profiles.
-Below is the settings.xml with properties included in the distribution.
+The database properties are supplied in the “opendaylight-release” and “opendaylight-snapshots”
+profiles. Below is the settings.xml with properties included in the distribution.
 The module can be rebuild from sources with different parameters.
 
 Sample entry in settings.xml to declare an external inventory database:
@@ -252,11 +288,12 @@ Sample entry in settings.xml to declare an external inventory database:
     </profiles>
 
 
-Once the project built and when karaf is started, the cfg file is generated in etc folder with the corresponding
-properties supplied in settings.xml. When devices with OpenROADM 1.2.1 device model are mounted, the device listener in
-the inventory module loads several device attributes to various tables as per the supplied database.
-The database structure details can be retrieved from the file tests/inventory/initdb.sql inside project sources.
-Installation scripts and a docker file are also provided.
+Once the project built and when karaf is started, the cfg file is generated in etc folder with the
+corresponding properties supplied in settings.xml. When devices with OpenROADM 1.2.1 device model
+are mounted, the device listener in the inventory module loads several device attributes to various
+tables as per the supplied database. The database structure details can be retrieved from the file
+tests/inventory/initdb.sql inside project sources. Installation scripts and a docker file are also
+provided.
 
 Key APIs and Interfaces
 -----------------------
@@ -319,6 +356,7 @@ Internal APIs define REST APIs to interconnect TransportPCE modules :
 -   PCE to Topology Management
 -   Service Handler to Renderer
 -   Renderer to OLM
+-   Network Model to Service Handler
 
 Pce Service
 ^^^^^^^^^^^
@@ -397,7 +435,7 @@ odl-transportpce-stubmodels
 
    -  This feature provides function to be able to stub some of TransportPCE modules, pce and
       renderer (Stubpce and Stubrenderer).
-      Stubs are used for development purposes and can be used for some of the functionnal tests.
+      Stubs are used for development purposes and can be used for some of the functional tests.
 
 Interfaces to external software
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -601,15 +639,17 @@ Creating a service
 ~~~~~~~~~~~~~~~~~~
 
 Use the *service handler* module to create any end-to-end connectivity service on an OpenROADM
-network. Two kind of end-to-end "optical" services are managed by TransportPCE:
-- 100GE service from client port to client port of two transponders (TPDR)
+network. Two different kinds of end-to-end "optical" services are managed by TransportPCE:
+- 100GE/400GE services from client port to client port of two transponders (TPDR)
 - Optical Channel (OC) service from client add/drop port (PP port of SRG) to client add/drop port of
 two ROADMs.
 
 For these services, TransportPCE automatically invokes *renderer* module to create all required
 interfaces and cross-connection on each device supporting the service.
-As an example, the creation of a 100GE service implies among other things, the creation of OCH, OTU4
-and ODU4 interfaces on the Network port of TPDR devices.
+As an example, the creation of a 100GE service implies among other things, the creation of OCH or
+Optical Tributary Signal (OTSi), OTU4 and ODU4 interfaces on the Network port of TPDR devices.
+The creation of a 400GE service implies the creation of OTSi, OTUC4, ODUC4 and ODU4 interfaces on
+the Network port of TPDR devices.
 
 Since Magnesium SR2, the *service handler* module directly manages some end-to-end otn
 connectivity services.
@@ -946,6 +986,131 @@ As for the previous RPC, this RPC invokes the *PCE* module to compute a path ove
 *openroadm-topology* and then invokes *renderer* and *OLM* to implement the end-to-end path into
 the devices.
 
+OTSi-OTUC4 service creation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use the following REST RPC to invoke *service handler* module in order to create over the optical
+infrastructure a bidirectional end-to-end OTUC4 over an optical Optical Tributary Signal
+connectivity service between two optical network ports of OTN Xponder (MUXPDR or SWITCH). Such
+service configure the optical network infrastructure composed of rdm nodes.
+
+**REST API** : *POST /restconf/operations/org-openroadm-service:service-create*
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+        "input": {
+            "sdnc-request-header": {
+                "request-id": "request-1",
+                "rpc-action": "service-create",
+                "request-system-id": "appname"
+            },
+            "service-name": "something",
+            "common-id": "commonId",
+            "connection-type": "infrastructure",
+            "service-a-end": {
+                "service-rate": "400",
+                "node-id": "<xpdr-node-id>",
+                "service-format": "OTU",
+                "otu-service-rate": "org-openroadm-otn-common-types:OTUCn",
+                "clli": "<ccli-name>",
+                "tx-direction": {
+                    "port": {
+                        "port-device-name": "<xpdr-node-id-in-otn-topology>",
+                        "port-type": "fixed",
+                        "port-name": "<xpdr-network-port-in-otn-topology>",
+                        "port-rack": "000000.00",
+                        "port-shelf": "Chassis#1"
+                    },
+                    "lgx": {
+                        "lgx-device-name": "Some lgx-device-name",
+                        "lgx-port-name": "Some lgx-port-name",
+                        "lgx-port-rack": "000000.00",
+                        "lgx-port-shelf": "00"
+                    }
+                },
+                "rx-direction": {
+                    "port": {
+                        "port-device-name": "<xpdr-node-id-in-otn-topology>",
+                        "port-type": "fixed",
+                        "port-name": "<xpdr-network-port-in-otn-topology>",
+                        "port-rack": "000000.00",
+                        "port-shelf": "Chassis#1"
+                    },
+                    "lgx": {
+                        "lgx-device-name": "Some lgx-device-name",
+                        "lgx-port-name": "Some lgx-port-name",
+                        "lgx-port-rack": "000000.00",
+                        "lgx-port-shelf": "00"
+                    }
+                },
+                "optic-type": "gray"
+            },
+            "service-z-end": {
+                "service-rate": "400",
+                "node-id": "<xpdr-node-id>",
+                "service-format": "OTU",
+                "otu-service-rate": "org-openroadm-otn-common-types:OTUCn",
+                "clli": "<ccli-name>",
+                "tx-direction": {
+                    "port": {
+                        "port-device-name": "<xpdr-node-id-in-otn-topology>",
+                        "port-type": "fixed",
+                        "port-name": "<xpdr-network-port-in-otn-topology>",
+                        "port-rack": "000000.00",
+                        "port-shelf": "Chassis#1"
+                    },
+                    "lgx": {
+                        "lgx-device-name": "Some lgx-device-name",
+                        "lgx-port-name": "Some lgx-port-name",
+                        "lgx-port-rack": "000000.00",
+                        "lgx-port-shelf": "00"
+                    }
+                },
+                "rx-direction": {
+                    "port": {
+                        "port-device-name": "<xpdr-node-id-in-otn-topology>",
+                        "port-type": "fixed",
+                        "port-name": "<xpdr-network-port-in-otn-topology>",
+                        "port-rack": "000000.00",
+                        "port-shelf": "Chassis#1"
+                    },
+                    "lgx": {
+                        "lgx-device-name": "Some lgx-device-name",
+                        "lgx-port-name": "Some lgx-port-name",
+                        "lgx-port-rack": "000000.00",
+                        "lgx-port-shelf": "00"
+                    }
+                },
+                "optic-type": "gray"
+            },
+            "due-date": "yyyy-mm-ddT00:00:01Z",
+            "operator-contact": "some-contact-info"
+        }
+    }
+
+As for the previous RPC, this RPC invokes the *PCE* module to compute a path over the
+*openroadm-topology* and then invokes *renderer* and *OLM* to implement the end-to-end path into
+the devices.
+
+One shall note that in Phosphorus SR0, as the OpenROADM 400G specification are not available (neither
+in the GNPy libraries, nor in the *PCE* module), path validation will be performed using the same
+asumptions as we use for 100G. This means the path may be validated whereas optical performances do
+not reach expected levels. This allows testing OpenROADM device implementing B100G rates, but shall
+not be used in operational conditions. The support for higher rate impairment aware path computation
+will be introduced across Phosphorus release train.
+
+ODUC4 service creation
+^^^^^^^^^^^^^^^^^^^^^^
+
+For ODUC4 service creation, the REST RPC to invoke *service handler* module in order to create an
+ODUC4 over the OTSi-OTUC4 has the same format as the RPC used for the creation of this last. Only
+"service-format" needs to be changed to "ODU", and "otu-service-rate" : "org-openroadm-otn-common-
+types:OTUCn" needs to be replaced by: "odu-service-rate" : "org-openroadm-otn-common-types:ODUCn"
+in both service-a-end and service-z-end containers.
+
 OTN HO-ODU4 service creation
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1184,7 +1349,7 @@ invokes *renderer* and *OLM* to implement the end-to-end path into the devices.
     Magnesium SR0). The trib-slot provided corresponds to the first of the used trib-slots.
     complex-trib-slots will be used when the equipment does not support contiguous trib-slot
     allocation. In this case a list of the different trib-slots to be used shall be provided.
-    The support for non contiguous trib-slot allocation is planned for later Magnesium release.
+    The support for non contiguous trib-slot allocation is planned for later release.
 
 Deleting a service
 ~~~~~~~~~~~~~~~~~~
@@ -1345,16 +1510,33 @@ odl-transportpce-tapi
 
 This feature allows TransportPCE application to expose at its northbound interface other APIs than
 those defined by the OpenROADM MSA. With this feature, TransportPCE provides part of the Transport-API
-specified by the Open Networking Foundation. More specifically, part of the Topology Service component
-is implemented, allowing to expose to higher level applications an abstraction of its OpenROADM
-topologies in the form of topologies respecting the T-API modelling. The current version of TransportPCE
-implements the *tapi-topology.yang* model in the revision 2018-12-10 (T-API v2.1.2).
+specified by the Open Networking Foundation. More specifically, the Topology Service and Connectivity
+Service components are implemented, allowing to expose to higher level applications an abstraction of
+its OpenROADM topologies in the form of topologies respecting the T-API modelling, as well as
+creating/deleting connectivity services between the Service Interface Points (SIPs) exposed by the
+T-API topology. The current version of TransportPCE implements the *tapi-topology.yang* and
+*tapi-connectivity.yang* models in the revision 2018-12-10 (T-API v2.1.2).
 
+Additionally, support for the Notification Service component will be added in future releases, which
+will allow higher level applications to create/delete a Notification Subscription Service to receive
+several T-API notifications as defined in the *tapi-notification.yang* model.
 
--  RPC call
+T-API Topology Service
+~~~~~~~~~~~~~~~~~~~~~~
+
+-  RPC calls implemented:
 
    -  get-topology-details
 
+   -  get-node-details
+
+   -  get-node-edge-point-details
+
+   -  get-link-details
+
+   -  get-topology-list
+
+
 As in IETF or OpenROADM topologies, T-API topologies are composed of lists of nodes and links that
 abstract a set of network resources. T-API specifies the *T0 - Multi-layer topology* which is, as
 indicated by its name, a single topology that collapses network logical abstraction for all network
@@ -1375,13 +1557,35 @@ In the same way, a pair of unidirectional OTN links (OTU4, ODU4) present in *otn
 represented by a bidirectional OTN link in TAPI topology, while retaining their available bandwidth
 characteristics.
 
-Two kinds of topologies are currently implemented. The first one is the *"T0 - Multi-layer topology"*
+Phosphorus SR0 extends the T-API topology service implementation by bringing a fully described topology.
+*T0 - Full Multi-layer topology* is derived from the existing *T0 - Multi-layer topology*. But the ROADM
+infrastructure is not abstracted and the higher level application can get more details on the composition
+of the ROADM infrastructure controlled by TransportPCE. Each ROADM node found in the *openroadm-network*
+is converted into a *Photonic Media* node. The details of these T-API nodes are obtained from the
+*openroadm-topology*. Therefore, the external traffic ports of *Degree* and *SRG* nodes are represented
+with a set of Network Edge Points (NEPs) and SIPs belonging to the *Photonic Media* node and a pair of
+roadm-to-roadm links present in *openroadm-topology* is represented by a bidirectional *OMS* link in TAPI
+topology.
+Additionally, T-API topology related information is stored in TransportPCE datastore in the same way as
+OpenROADM topology layers. When a node is connected to the controller through the corresponding *REST API*,
+the T-API topology context gets updated dynamically and stored.
+
+.. note::
+
+    A naming nomenclature is defined to be able to map T-API and OpenROADM data.
+    i.e., T-API_roadm_Name = OpenROADM_roadmID+T-API_layer
+    i.e., T-API_roadm_nep_Name = OpenROADM_roadmID+T-API_layer+OpenROADM_terminationPointID
+
+Three kinds of topologies are currently implemented. The first one is the *"T0 - Multi-layer topology"*
 defined in the reference implementation of T-API. This topology gives an abstraction from data coming
 from openroadm-topology and otn-topology. Such topology may be rather complex since most of devices are
 represented through several nodes and links.
 Another topology, named *"Transponder 100GE"*, is also implemented. That latter provides a higher level
 of abstraction, much simpler, for the specific case of 100GE transponder, in the form of a single
 DSR node.
+Lastly, the *T0 - Full Multi-layer topology* topology was added. This topology collapses the data coming
+from openroadm-network, openroadm-topology and otn-topology. It gives a complete view of the optical
+network as defined in the reference implementation of T-API
 
 The figure below shows an example of TAPI abstractions as performed by TransportPCE starting from Aluminium SR2.
 
@@ -1439,13 +1643,282 @@ be connected together, through a point-to-point 100GE service running over a wav
     port is connected to Add/Drop nodes of the ROADM infrastructure are retrieved in order to
     abstract only relevant information.
 
+This request builds the TAPI *T0 - Full Multi-layer* topology with respect to the information existing in
+the T-API topology context stored in OpenDaylight datastores.
+
+.. code:: json
+
+    {
+      "tapi-topology:input": {
+        "tapi-topology:topology-id-or-name": "T0 - Full Multi-layer topology"
+        }
+    }
+
+**REST API** : *POST /restconf/operations/tapi-topology:get-node-details*
+
+This request returns the information, stored in the Topology Context, of the corresponding T-API node.
+The user can provide, either the Uuid associated to the attribute or its name.
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+      "tapi-topology:input": {
+        "tapi-topology:topology-id-or-name": "T0 - Full Multi-layer topology",
+        "tapi-topology:node-id-or-name": "ROADM-A1+PHOTONINC_MEDIA"
+      }
+    }
+
+**REST API** : *POST /restconf/operations/tapi-topology:get-node-edge-point-details*
+
+This request returns the information, stored in the Topology Context, of the corresponding T-API NEP.
+The user can provide, either the Uuid associated to the attribute or its name.
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+      "tapi-topology:input": {
+        "tapi-topology:topology-id-or-name": "T0 - Full Multi-layer topology",
+        "tapi-topology:node-id-or-name": "ROADM-A1+PHOTONINC_MEDIA",
+        "tapi-topology:ep-id-or-name": "ROADM-A1+PHOTONINC_MEDIA+DEG1-TTP-TXRX"
+      }
+    }
+
+**REST API** : *POST /restconf/operations/tapi-topology:get-link-details*
+
+This request returns the information, stored in the Topology Context, of the corresponding T-API link.
+The user can provide, either the Uuid associated to the attribute or its name.
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+      "tapi-topology:input": {
+        "tapi-topology:topology-id-or-name": "T0 - Full Multi-layer topology",
+        "tapi-topology:link-id-or-name": "ROADM-C1-DEG1-DEG1-TTP-TXRXtoROADM-A1-DEG2-DEG2-TTP-TXRX"
+      }
+    }
+
+T-API Connectivity & Common Services
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Phosphorus SR0 extends the T-API interface support by implementing the T-API connectivity Service.
+This interface enables a higher level controller or an orchestrator to request the creation of
+connectivity services as defined in the *tapi-connectivity* model. As it is necessary to indicate the
+two (or more) SIPs (or endpoints) of the connectivity service, the *tapi-common* model is implemented
+to retrieve from the datastore all the innformation related to the SIPs in the tapi-context.
+Current implementation of the connectivity service maps the *connectivity-request* into the appropriate
+*openroadm-service-create* and relies on the Service Handler to perform path calculation and configuration
+of devices. Results received from the PCE and the Rendererare mapped back into T-API to create the
+corresponding Connection End Points (CEPs) and Connections in the T-API Connectivity Context and store it
+in the datastore.
+
+This first implementation includes the creation of:
+
+-   ROADM-to-ROADM tapi-connectivity service (MC connectivity service)
+-   OTN tapi-connectivity services (OCh/OTU, OTSi/OTU & ODU connectivity services)
+-   Ethernet tapi-connectivity services (DSR connectivity service)
+
+-  RPC calls implemented
+
+   -  create-connectivity-service
+
+   -  get-connectivity-service-details
+
+   -  get-connection-details
+
+   -  delete-connectivity-service
+
+   -  get-connection-end-point-details
+
+   -  get-connectivity-service-list
+
+   -  get-service-interface-point-details
+
+   -  get-service-interface-point-list
+
+Creating a T-API Connectivity service
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use the *tapi* interface to create any end-to-end connectivity service on a T-API based
+network. Two kind of end-to-end "optical" connectivity services are managed by TransportPCE T-API module:
+- 10GE service from client port to client port of two OTN Xponders (MUXPDR or SWITCH)
+- Media Channel (MC) connectivity service from client add/drop port (PP port of SRG) to
+client add/drop port of two ROADMs.
+
+As mentioned earlier, T-API module interfaces with the Service Handler to automatically invoke the
+*renderer* module to create all required tapi connections and cross-connection on each device
+supporting the service.
+
+Before creating a low-order OTN connectivity service (1GE or 10GE services terminating on
+client port of MUXPDR or SWITCH), the user must ensure that a high-order ODU4 container
+exists and has previously been configured (it means structured to support low-order otn services)
+to support low-order OTN containers.
+
+Thus, OTN connectivity service creation implies three steps:
+1. OTSi/OTU connectivity service from network port to network port of two OTN Xponders (MUXPDR or SWITCH in Photonic media layer)
+2. ODU connectivity service from network port to network port of two OTN Xponders (MUXPDR or SWITCH in DSR/ODU layer)
+3. 10GE connectivity service creation from client port to client port of two OTN Xponders (MUXPDR or SWITCH in DSR/ODU layer)
+
+The first step corresponds to the OCH-OTU4 service from network port to network port of OpenROADM.
+The corresponding T-API cross and top connections are created between the CEPs of the T-API nodes
+involved in each request.
+
+Additionally, an *MC connectivity service* could be created between two ROADMs to create an optical
+tunnel and reserve resources in advance. This kind of service corresponds to the OC service creation
+use case described earlier.
+
+The management of other OTN services through T-API (1GE-ODU0, 100GE...) is planned for future releases.
+
+Any-Connectivity service creation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+As for the Service Creation described for OpenROADM, the initial steps are the same:
+
+-   Connect netconf devices to the controller
+-   Create XPDR-RDM links and configure RDM-to-RDM links (in openroadm topologies)
+
+Bidirectional T-API links between xpdr and rdm nodes must be created manually. To that end, use the
+following REST RPCs:
+
+From xpdr <--> rdm:
+^^^^^^^^^^^^^^^^^^^
+
+**REST API** : *POST /restconf/operations/transportpce-tapinetworkutils:init-xpdr-rdm-tapi-link*
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+        "input": {
+            "xpdr-node": "<XPDR_OpenROADM_id>",
+            "network-tp": "<XPDR_TP_OpenROADM_id>",
+            "rdm-node": "<ROADM_OpenROADM_id>",
+            "add-drop-tp": "<ROADM_TP_OpenROADM_id>"
+        }
+    }
+
+Use the following REST RPC to invoke T-API module in order to create a bidirectional connectivity
+service between two devices. The network should be composed of two ROADMs and two Xponders (SWITCH or MUX)
+
+**REST API** : *POST /restconf/operations/tapi-connectivity:create-connectivity-service*
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+        "tapi-connectivity:input": {
+            "tapi-connectivity:end-point": [
+                {
+                    "tapi-connectivity:layer-protocol-name": "<Node_TAPI_Layer>",
+                    "tapi-connectivity:service-interface-point": {
+                        "tapi-connectivity:service-interface-point-uuid": "<SIP_UUID_of_NEP>"
+                    },
+                    "tapi-connectivity:administrative-state": "UNLOCKED",
+                    "tapi-connectivity:operational-state": "ENABLED",
+                    "tapi-connectivity:direction": "BIDIRECTIONAL",
+                    "tapi-connectivity:role": "SYMMETRIC",
+                    "tapi-connectivity:protection-role": "WORK",
+                    "tapi-connectivity:local-id": "<OpenROADM node ID>",
+                    "tapi-connectivity:name": [
+                        {
+                            "tapi-connectivity:value-name": "OpenROADM node id",
+                            "tapi-connectivity:value": "<OpenROADM node ID>"
+                        }
+                    ]
+                },
+                {
+                    "tapi-connectivity:layer-protocol-name": "<Node_TAPI_Layer>",
+                    "tapi-connectivity:service-interface-point": {
+                        "tapi-connectivity:service-interface-point-uuid": "<SIP_UUID_of_NEP>"
+                    },
+                    "tapi-connectivity:administrative-state": "UNLOCKED",
+                    "tapi-connectivity:operational-state": "ENABLED",
+                    "tapi-connectivity:direction": "BIDIRECTIONAL",
+                    "tapi-connectivity:role": "SYMMETRIC",
+                    "tapi-connectivity:protection-role": "WORK",
+                    "tapi-connectivity:local-id": "<OpenROADM node ID>",
+                    "tapi-connectivity:name": [
+                        {
+                            "tapi-connectivity:value-name": "OpenROADM node id",
+                            "tapi-connectivity:value": "<OpenROADM node ID>"
+                        }
+                    ]
+                }
+            ],
+            "tapi-connectivity:connectivity-constraint": {
+                "tapi-connectivity:service-layer": "<TAPI_Service_Layer>",
+                "tapi-connectivity:service-type": "POINT_TO_POINT_CONNECTIVITY",
+                "tapi-connectivity:service-level": "Some service-level",
+                "tapi-connectivity:requested-capacity": {
+                    "tapi-connectivity:total-size": {
+                        "value": "<CAPACITY>",
+                        "unit": "GB"
+                    }
+                }
+            },
+            "tapi-connectivity:state": "Some state"
+        }
+    }
+
+As for the previous RPC, MC and OTSi correspond to PHOTONIC_MEDIA layer services,
+ODU to ODU layer services and 10GE/DSR to DSR layer services. This RPC invokes the
+*Service Handler* module to trigger the *PCE* to compute a path over the
+*otn-topology* that must contains ODU4 links with valid bandwidth parameters. Once the path is computed
+and validated, the T-API CEPs (associated with a NEP), cross connections and top connections will be created
+according to the service request and the topology objects inside the computed path. Then, the *renderer* and
+*OLM* are invoked to implement the end-to-end path into the devices and to update the status of the connections
+and connectivity service.
+
+.. note::
+    Refer to the "Unconstrained E2E Service Provisioning" use cases from T-API Reference Implementation to get
+    more details about the process of connectivity service creation
+
+Deleting a connectivity service
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use the following REST RPC to invoke *TAPI* module in order to delete a given optical
+connectivity service.
+
+**REST API** : *POST /restconf/operations/tapi-connectivity:delete-connectivity-service*
+
+**Sample JSON Data**
+
+.. code:: json
+
+    {
+        "tapi-connectivity:input": {
+            "tapi-connectivity:service-id-or-name": "<Service_UUID_or_Name>"
+        }
+    }
+
+.. note::
+    Deleting OTN connectivity services implies proceeding in the reverse way to their creation. Thus, OTN
+    connectivity service deletion must respect the three following steps:
+    1. delete first all 10GE services supported over any ODU4 to be deleted
+    2. delete ODU4
+    3. delete MC-OTSi supporting the just deleted ODU4
+
+T-API Notification Service
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In future releases, the T-API notification service will be implemented. The objective will be to write and read
+T-API notifications stored in topics of a Kafka server as explained later in the odl-transportpce-nbinotifications
+section, but T-API based.
+
+
 odl-transportpce-dmaap-client
 -----------------------------
 
 This feature allows TransportPCE application to send notifications on ONAP Dmaap Message router
 following service request results.
 This feature listens on NBI notifications and sends the PublishNotificationService content to
-Dmaap on the topic "unauthenticated.TPCE" through a POST request on /events/unauthenticated.TPCE
+Dmaap on the topic "unauthenticated. TPCE" through a POST request on /events/unauthenticated.TPCE
 It uses Jackson to serialize the notification to JSON and jersey client to send the POST request.
 
 odl-transportpce-nbinotifications
@@ -1455,7 +1928,7 @@ This feature allows TransportPCE application to write and read notifications sto
 It is basically composed of two kinds of elements. First are the 'publishers' that are in charge of sending a notification to
 a Kafka server. To protect and only allow specific classes to send notifications, each publisher
 is dedicated to an authorized class.
-Then are the 'subscribers' that are in charge of reading notifications from a Kafka server.
+There are the 'subscribers' that are in charge of reading notifications from a Kafka server.
 So when the feature is called to write notification to a Kafka server, it will serialize the notification
 into JSON format and then will publish it in a topic of the server via a publisher.
 And when the feature is called to read notifications from a Kafka server, it will retrieve it from
diff --git a/docs/images/TransportPCE-Diagram-Phosphorus.jpg b/docs/images/TransportPCE-Diagram-Phosphorus.jpg
new file mode 100644 (file)
index 0000000..e7c2e3d
Binary files /dev/null and b/docs/images/TransportPCE-Diagram-Phosphorus.jpg differ
index 71f5ffeb82f9a3bd919835dff68fd436389c6186..072620ef4cabd70d339510c62b157e6a77548cb0 100644 (file)
Binary files a/docs/images/TransportPCE-tapi-abstraction.jpg and b/docs/images/TransportPCE-tapi-abstraction.jpg differ
index f0d83ce15615e70d131658a219f99021bd8821cd..6567a889ca399e820920a0473b4e503f75bd9e83 100644 (file)
@@ -29,7 +29,7 @@ handler, Renderer responsible for the path configuration through optical
 equipment and Optical Line Management (OLM) is associated with a generic block
 relying on open models, each of them communicating through published APIs.
 
-.. figure:: ./images/TransportPCE-Diagramm-Magnesium.jpg
+.. figure:: ./images/TransportPCE-Diagram-Phosphorus.jpg
    :alt: TransportPCE architecture
 
    TransportPCE architecture
index 1a1e02b79c7a155991d6f1e8212bf8ac6b443172..781e52dc4168ce749348bbd45e5e463788d85226 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>single-feature-parent</artifactId>
-        <version>9.0.6</version>
+        <version>9.0.8</version>
         <relativePath />
     </parent>
     <groupId>org.opendaylight.transportpce</groupId>
index 6f8e952a194c284d713c24d7aa4ae29249513ffc..4449819c4c48da650e9ab036570c6c24bced1d27 100644 (file)
@@ -9,7 +9,7 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>single-feature-parent</artifactId>
-        <version>9.0.6</version>
+        <version>9.0.8</version>
         <relativePath/>
     </parent>
 
index 26499e07108bd3e73934cd4289a465eb1d145114..8e84062afdbf68a8efae467b3d936f94ead82ff0 100644 (file)
@@ -11,7 +11,7 @@
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>single-feature-parent</artifactId>
-        <version>9.0.6</version>
+        <version>9.0.8</version>
         <relativePath />
     </parent>
 
index e4c876f4bc0d3a4cff23591742d6729b3ea2d519..b8409fb39782203fc819b222d5d92b109e7dc14f 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>single-feature-parent</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
@@ -24,7 +24,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <name>OpenDaylight :: transportpce :: swagger</name>
 
   <properties>
-    <netconf.version>2.0.5</netconf.version>
+    <netconf.version>2.0.7</netconf.version>
     <configfile.directory>etc/opendaylight/karaf</configfile.directory>
   </properties>
 
index 76d8a42ccd7493cce67871a6ea73991a7c00790f..a5edc613e9666e1e57dae6e01c2a7d8f79d1f577 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>single-feature-parent</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
index 8f896cd0e6ec4d3bcadb3c5f9de913e11a3928f5..94a51a70149e4909197efc3c0e9f82b208687920 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>single-feature-parent</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
@@ -24,7 +24,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <name>OpenDaylight :: transportpce</name>
 
   <properties>
-    <netconf.version>2.0.5</netconf.version>
+    <netconf.version>2.0.7</netconf.version>
     <configfile.directory>etc/opendaylight/karaf</configfile.directory>
   </properties>
 
index c6157ce200f89c04ced0402e2effe84671a62ff2..3f55cd9aa9bcece0c8ecf55e75f2c4ad5df7b004 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>odlparent-lite</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
index 1fbabde4ef12155d9454fb9662bb183d3435d916..dd88fed09d0d4913f36c23baa9cf0cbfd87e48dc 100644 (file)
@@ -10,7 +10,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
 
index 900d4457fa118c6afc0f5b37fa1c9866f05a96f3..8ed99ad436d894745ee129451847bc9192aa7271 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>karaf4-parent</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
index 654bb5d6cc13bdc8d58b946aa3f2ad342116e54f..4726600364dfc11f864cc8c1acb988ec3d428cc2 100644 (file)
@@ -11,7 +11,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
 
index c257f636df21136012a607aca6e1e1de871c321d..491e3647b1e95a5a44c081c3e415772cd71cce8a 100644 (file)
@@ -13,7 +13,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
     <artifactId>bundle-parent</artifactId>
-    <version>9.0.6</version>
+    <version>9.0.8</version>
     <relativePath/>
   </parent>
 
@@ -27,7 +27,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <dependency>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>mdsal-artifacts</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <scope>import</scope>
         <type>pom</type>
       </dependency>
index 4857dc1ff1d125a0346a0988f7dfffc87de06408..77d4217dec4d5a1d1987a8f564987425366b73fc 100644 (file)
@@ -13,7 +13,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
@@ -38,25 +38,21 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>3.2.4</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-core</artifactId>
-      <version>2.0.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-api-mockito2</artifactId>
-      <version>2.0.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-module-junit4</artifactId>
-      <version>2.0.2</version>
       <scope>test</scope>
     </dependency>
 
index 4db9a6102b6e396fd41c6941b566dc57e040b5d1..6f2431a3473738f933b30d125bdcb096f204ece5 100644 (file)
@@ -527,34 +527,37 @@ public class OlmPowerServiceImpl implements OlmPowerService {
             String sourceTpId = link.getSrcTpId();
             String destNodeId = link.getDestNodeId();
             String destTpId = link.getDestTpid();
-            OtsPmHolder srcOtsPmHoler = getPmMeasurements(sourceNodeId, sourceTpId, "OpticalPowerOutput");
-            if (srcOtsPmHoler == null) {
-                srcOtsPmHoler = getPmMeasurements(sourceNodeId, sourceTpId, "OpticalPowerOutputOSC");
-            }
-            OtsPmHolder destOtsPmHoler = getPmMeasurements(destNodeId, destTpId, "OpticalPowerInput");
-            if (destOtsPmHoler == null) {
-                destOtsPmHoler = getPmMeasurements(destNodeId, destTpId, "OpticalPowerInputOSC");
+            OtsPmHolder srcOtsPmHolder = getPmMeasurements(sourceNodeId, sourceTpId, "OpticalPowerOutput");
+            if (srcOtsPmHolder == null) {
+                srcOtsPmHolder = getPmMeasurements(sourceNodeId, sourceTpId, "OpticalPowerOutputOSC");
+                if (srcOtsPmHolder == null) {
+                    LOG.warn("OTS configuration issue at {} - {}", sourceNodeId, sourceTpId);
+                    continue;
+                }
             }
-
-            if (srcOtsPmHoler.getOtsInterfaceName() == null || destOtsPmHoler.getOtsInterfaceName() == null) {
-                LOG.warn("OTS is not present for the link {}", link);
-                continue;
+            OtsPmHolder destOtsPmHolder = getPmMeasurements(destNodeId, destTpId, "OpticalPowerInput");
+            if (destOtsPmHolder == null) {
+                destOtsPmHolder = getPmMeasurements(destNodeId, destTpId, "OpticalPowerInputOSC");
+                if (destOtsPmHolder == null) {
+                    LOG.warn("OTS configuration issue at {} - {}", destNodeId, destTpId);
+                    continue;
+                }
             }
-            spanLoss = BigDecimal.valueOf(srcOtsPmHoler.getOtsParameterVal() - destOtsPmHoler.getOtsParameterVal())
+            spanLoss = BigDecimal.valueOf(srcOtsPmHolder.getOtsParameterVal() - destOtsPmHolder.getOtsParameterVal())
                 .setScale(1, RoundingMode.HALF_UP);
             LOG.info("Spanloss Calculated as :{}={}-{}",
-                spanLoss, srcOtsPmHoler.getOtsParameterVal(), destOtsPmHoler.getOtsParameterVal());
+                spanLoss, srcOtsPmHolder.getOtsParameterVal(), destOtsPmHolder.getOtsParameterVal());
             if (spanLoss.doubleValue() > 28) {
                 LOG.warn("Span Loss is out of range of OpenROADM specifications");
             }
             if (spanLoss.intValue() <= 0) {
                 spanLoss = BigDecimal.valueOf(0);
             }
-            if (!setSpanLoss(sourceNodeId, srcOtsPmHoler.getOtsInterfaceName(), spanLoss, "TX")) {
+            if (!setSpanLoss(sourceNodeId, srcOtsPmHolder.getOtsInterfaceName(), spanLoss, "TX")) {
                 LOG.info("Setting spanLoss failed for {}", sourceNodeId);
                 return null;
             }
-            if (!setSpanLoss(destNodeId, destOtsPmHoler.getOtsInterfaceName(), spanLoss, "RX")) {
+            if (!setSpanLoss(destNodeId, destOtsPmHolder.getOtsInterfaceName(), spanLoss, "RX")) {
                 LOG.info("Setting spanLoss failed for {}", destNodeId);
                 return null;
             }
index cca27425d5cfb9e2b0f10fb598eed599428fd692..45e0673a38eee7261783ccc0233de8497fa402e3 100644 (file)
@@ -84,6 +84,9 @@ final class OlmUtils221 {
 
         InstanceIdentifier<?> resourceKeyIID =
                 findClassKeyIdentifiers(input.getResourceType(), input.getResourceIdentifier());
+        if (resourceKeyIID == null) {
+            return pmOutputBuilder;
+        }
         CurrentPmEntryKey resourceKey = new CurrentPmEntryKey(resourceKeyIID,
                 convertResourceTypeEnum(input.getResourceType()),"");
         InstanceIdentifier<CurrentPmList> iidCurrentPmList = InstanceIdentifier.create(CurrentPmList.class);
@@ -182,6 +185,10 @@ final class OlmUtils221 {
 
     private static InstanceIdentifier<?> findClassKeyIdentifiers(ResourceTypeEnum wantedResourceType,
             ResourceIdentifier wantedResourceIdentifier) {
+        if (wantedResourceIdentifier.getResourceName() == null) {
+            LOG.debug("resource {} is null", wantedResourceType);
+            return null;
+        }
         switch (wantedResourceType) {
             case Device:
                 return InstanceIdentifier.create(OrgOpenroadmDevice.class);
index 01e8c747828c9ee258f98b5d964305a6ef057df2..de036e1825f1570a51fa6fcd48c647d65dcabc29 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 2b03901969e486b72921735f7f74499ee3587591..cf344f68f4cefcfc675b736e37557382f0aedaad 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
@@ -26,7 +26,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <dependency>
         <groupId>org.opendaylight.netconf</groupId>
         <artifactId>netconf-artifacts</artifactId>
-        <version>2.0.5</version>
+        <version>2.0.7</version>
         <scope>import</scope>
         <type>pom</type>
       </dependency>
index 39dd8fe5e14f2fe5b134813fdfe67af261a15c29..f21f9bcb779b69e60241ab08336c6de3bd95abaa 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 6d3b31ae79c4632a268631ee3c2de4259ba52e9e..3396ae393033c6e11b3bb87d9d824f3e0dcc4ff9 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
@@ -56,7 +56,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.18.1</version>
         <configuration>
           <skipTests>true</skipTests>
         </configuration>
index 5bb08f1fa8a0d05a22b6124f8245326b7a3b4f9c..f318e6c5d245916846e92ae2d21cb125105fbb72 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 617edb4a33760f73c0199952920fcf5f3a9a7e99..273caa99b5f38c61651ac2b009cb144dd690f444 100644 (file)
@@ -14,7 +14,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
 
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>2.25.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.powermock</groupId>
             <artifactId>powermock-core</artifactId>
-            <version>2.0.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.powermock</groupId>
             <artifactId>powermock-api-mockito2</artifactId>
-            <version>2.0.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.powermock</groupId>
             <artifactId>powermock-module-junit4</artifactId>
-            <version>2.0.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
-                <version>2.6</version>
                 <executions>
                     <execution>
                         <goals>
diff --git a/pom.xml b/pom.xml
index d4172a51d08ceefe9061531a4489bc1799d1166c..6a20de91669df4f9dd5cb3ae7667c44cfae620aa 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <parent>
         <groupId>org.opendaylight.odlparent</groupId>
         <artifactId>odlparent</artifactId>
-        <version>9.0.6</version>
+        <version>9.0.8</version>
         <relativePath/>
     </parent>
 
index a7b5186654fb7afe949be9f8982f85855c484bc7..da29abb5f21e63c0fdb1a7634a0fd56a3a5adb65 100644 (file)
@@ -13,7 +13,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 147bf3cd446a49c4e69aac467fae95a840927a40..d42c4459709d1996998995e85c8ba604eca9aa2a 100644 (file)
@@ -15,7 +15,7 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 8804d0017b636cacaabb3bab7dfc04867b5753b0..618fc4cd3b99c1edbde3e905f39974521796d616 100644 (file)
@@ -15,7 +15,7 @@ Author: Martial Coulibaly <martial.coulibaly@gfi.com> on behalf of Orange
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 7011804a85fc278ba46bc87081fd852f69f9bcba..c62645344fa24bc294d9d33607f23921a1328c61 100644 (file)
@@ -8,7 +8,7 @@
 package org.opendaylight.transportpce.tapi.connectivity;
 
 import com.google.common.util.concurrent.ListenableFuture;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -230,7 +230,7 @@ public class TapiConnectivityImpl implements TapiConnectivityService {
     public ListenableFuture<RpcResult<GetConnectivityServiceDetailsOutput>> getConnectivityServiceDetails(
             GetConnectivityServiceDetailsInput input) {
         // TODO Auto-generated method stub
-        Uuid serviceUuid = new Uuid(input.getServiceIdOrName());
+        Uuid serviceUuid = getUuidFromIput(input.getServiceIdOrName());
         ConnectivityService service = this.tapiContext.getConnectivityService(serviceUuid);
         if (service == null) {
             LOG.error("Service {} doesnt exist in tapi context", input.getServiceIdOrName());
@@ -254,8 +254,7 @@ public class TapiConnectivityImpl implements TapiConnectivityService {
     public ListenableFuture<RpcResult<GetConnectionDetailsOutput>> getConnectionDetails(
             GetConnectionDetailsInput input) {
         // TODO Auto-generated method stub
-        Uuid connectionUuid = new Uuid(UUID.nameUUIDFromBytes(input.getConnectionIdOrName()
-            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid connectionUuid = getUuidFromIput(input.getConnectionIdOrName());
         Connection connection = this.tapiContext.getConnection(connectionUuid);
         if (connection == null) {
             LOG.error("Connection {} doesnt exist in tapi context", input.getConnectionIdOrName());
@@ -271,27 +270,36 @@ public class TapiConnectivityImpl implements TapiConnectivityService {
             DeleteConnectivityServiceInput input) {
         //TODO Auto-generated method stub
         // TODO add try
-        Uuid serviceUuid = new Uuid(input.getServiceIdOrName());
-        this.tapiContext.deleteConnectivityService(serviceUuid);
-        ListenableFuture<RpcResult<ServiceDeleteOutput>> output =
-            this.serviceHandler.serviceDelete(new ServiceDeleteInputBuilder()
-                .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
-                    .setServiceName(input.getServiceIdOrName())
-                    .setTailRetention(ServiceDeleteReqInfo.TailRetention.No)
-                    .build())
-                .setSdncRequestHeader(new SdncRequestHeaderBuilder()
-                    .setRequestId("request-1")
-                    .setRpcAction(RpcActions.ServiceDelete)
-                    .setNotificationUrl("notification url")
-                    .setRequestSystemId("appname")
-                    .build())
-                .build());
-        if (output == null) {
-            return RpcResultBuilder.<DeleteConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
-                "Failed to delete Link").buildFuture();
+        if (input.getServiceIdOrName() != null) {
+            try {
+                Uuid serviceUuid = getUuidFromIput(input.getServiceIdOrName());
+                this.tapiContext.deleteConnectivityService(serviceUuid);
+                ListenableFuture<RpcResult<ServiceDeleteOutput>> output =
+                    this.serviceHandler.serviceDelete(new ServiceDeleteInputBuilder()
+                        .setServiceDeleteReqInfo(new ServiceDeleteReqInfoBuilder()
+                            .setServiceName(input.getServiceIdOrName())
+                            .setTailRetention(ServiceDeleteReqInfo.TailRetention.No)
+                            .build())
+                        .setSdncRequestHeader(new SdncRequestHeaderBuilder()
+                            .setRequestId("request-1")
+                            .setRpcAction(RpcActions.ServiceDelete)
+                            .setNotificationUrl("notification url")
+                            .setRequestSystemId("appname")
+                            .build())
+                        .build());
+                RpcResult<ServiceDeleteOutput> rpcResult = output.get();
+                if (!rpcResult.getResult().getConfigurationResponseCommon().getResponseCode()
+                        .equals(ResponseCodes.RESPONSE_FAILED)) {
+                    LOG.info("Service is being deleted and devices are being rolled back");
+                    return RpcResultBuilder.success(new DeleteConnectivityServiceOutputBuilder().build()).buildFuture();
+                }
+                LOG.error("Failed to delete service. Deletion process failed");
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to delete service.", e);
+            }
         }
-        LOG.info("Service is being deleted and devices are being rolled back");
-        return RpcResultBuilder.success(new DeleteConnectivityServiceOutputBuilder().build()).buildFuture();
+        return RpcResultBuilder.<DeleteConnectivityServiceOutput>failed().withError(RpcError.ErrorType.RPC,
+            "Failed to delete Service").buildFuture();
     }
 
     @Override
@@ -320,14 +328,10 @@ public class TapiConnectivityImpl implements TapiConnectivityService {
     public ListenableFuture<RpcResult<GetConnectionEndPointDetailsOutput>> getConnectionEndPointDetails(
             GetConnectionEndPointDetailsInput input) {
         // TODO Auto-generated method stub
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName()
-            .getBytes(Charset.forName("UTF-8"))).toString());
-        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName()
-            .getBytes(Charset.forName("UTF-8"))).toString());
-        Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNepIdOrName()
-            .getBytes(Charset.forName("UTF-8"))).toString());
-        Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getCepIdOrName()
-            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid topoUuid = getUuidFromIput(input.getTopologyIdOrName());
+        Uuid nodeUuid = getUuidFromIput(input.getNodeIdOrName());
+        Uuid nepUuid = getUuidFromIput(input.getNepIdOrName());
+        Uuid cepUuid = getUuidFromIput(input.getCepIdOrName());
         ConnectionEndPoint cep = this.tapiContext.getTapiCEP(topoUuid, nodeUuid, nepUuid, cepUuid);
         if (cep == null) {
             LOG.error("Cep doesnt exist in tapi context");
@@ -337,4 +341,15 @@ public class TapiConnectivityImpl implements TapiConnectivityService {
         return RpcResultBuilder.success(new GetConnectionEndPointDetailsOutputBuilder().setConnectionEndPoint(
             new ConnectionEndPointBuilder(cep).build()).build()).buildFuture();
     }
+
+    private Uuid getUuidFromIput(String serviceIdOrName) {
+        try {
+            UUID.fromString(serviceIdOrName);
+            LOG.info("Given attribute {} is a UUID", serviceIdOrName);
+            return new Uuid(serviceIdOrName);
+        } catch (IllegalArgumentException e) {
+            LOG.info("Given attribute {} is not a UUID", serviceIdOrName);
+            return new Uuid(UUID.nameUUIDFromBytes(serviceIdOrName.getBytes(StandardCharsets.UTF_8)).toString());
+        }
+    }
 }
index c84089fd14f3cbbb07b1ba8dd3e19ee412689f0c..5268055e0302814d8dad6652fd2731e91ed8a446 100644 (file)
@@ -59,6 +59,8 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointKey;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE100GigE;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE10GigELAN;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPEGigE;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU0;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2E;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU4;
@@ -258,7 +260,10 @@ public class ConvertORTopoToTapiFullTopo {
         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
             .Link link : rdmTordmLinkList) {
             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
-                Link tapiLink = createTapiOmsLink(link);
+                Link tapiLink = createTapiOmsLink(link, rdmTordmLinkList.stream()
+                    .filter(l -> l.getLinkId().equals(link.augmentation(org.opendaylight.yang.gen.v1.http
+                        .org.openroadm.common.network.rev200529.Link1.class).getOppositeLink()))
+                    .findAny().orElse(null));
                 linksToNotConvert.add(link
                     .augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
                     .getOppositeLink().getValue());
@@ -268,6 +273,7 @@ public class ConvertORTopoToTapiFullTopo {
     }
 
     public void convertRoadmNode(Node roadm, Network openroadmTopo) {
+        this.ietfNodeId = roadm.getNodeId().getValue();
         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> oneplist = new HashMap<>();
         // 1. Get degree and srg nodes to map TPs into NEPs
         if (openroadmTopo.getNode() == null) {
@@ -279,9 +285,9 @@ public class ConvertORTopoToTapiFullTopo {
         List<Node> nodeList = new ArrayList<Node>(openroadmTopo.getNode().values());
         for (Node node:nodeList) {
             if (node.getSupportingNode().values().stream().noneMatch(sp -> sp.getNodeRef().getValue()
-                .equals(roadm.getNodeId().getValue()))) {
+                .equals(this.ietfNodeId))) {
                 LOG.warn("Abstracted node {} is not part of {}",
-                    node.getNodeId().getValue(), roadm.getNodeId().getValue());
+                    node.getNodeId().getValue(), this.ietfNodeId);
                 continue;
             }
             if (node.augmentation(Node1.class) == null
@@ -312,7 +318,7 @@ public class ConvertORTopoToTapiFullTopo {
                     // Convert TP List in NEPs and put it in onepl
                     LOG.info("Degree port List: {}", degPortList);
                     // TODO: deg port could be sip. e.g. MDONS
-                    oneplist.putAll(populateNepsForRdmNode(roadm.getNodeId().getValue(), degPortList, false));
+                    oneplist.putAll(populateNepsForRdmNode(degPortList, false));
                     // oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), degPortList, false));
                     numNeps += degPortList.size() * 3;
                     break;
@@ -329,7 +335,7 @@ public class ConvertORTopoToTapiFullTopo {
                         .collect(Collectors.toList());
                     // Convert TP List in NEPs and put it in onepl
                     LOG.info("Srg port List: {}", srgPortList);
-                    oneplist.putAll(populateNepsForRdmNode(roadm.getNodeId().getValue(), srgPortList, true));
+                    oneplist.putAll(populateNepsForRdmNode(srgPortList, true));
                     // oneplist.putAll(populateNepsForRdmNode(node.getNodeId().getValue(), srgPortList, true));
                     numNeps += srgPortList.size() * 3;
                     numSips += srgPortList.size();
@@ -781,92 +787,85 @@ public class ConvertORTopoToTapiFullTopo {
         return onepBldr.build();
     }
 
-    private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> populateNepsForRdmNode(String nodeId,
-                                                                                  List<TerminationPoint> tpList,
+    private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> populateNepsForRdmNode(List<TerminationPoint> tpList,
                                                                                   boolean withSip) {
         // create neps for MC and OTSiMC and Photonic Media
         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
-        for (int i = 0; i < tpList.size(); i++) {
+        for (TerminationPoint tp:tpList) {
+            // Admin and oper state common for all tps
+            AdminStates admin = tp.augmentation(TerminationPoint1.class).getAdministrativeState();
+            State oper = tp.augmentation(TerminationPoint1.class).getOperationalState();
             // PHOTONIC MEDIA nep
-            LOG.info("NEP = {}", String.join("+", nodeId, PHTNC_MEDIA, tpList.get(i).getTpId().getValue()));
-            Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, PHTNC_MEDIA,
-                tpList.get(i).getTpId().getValue()))
-                .getBytes(Charset.forName("UTF-8")))
-                .toString());
+            LOG.info("PHOTO NEP = {}", String.join("+", this.ietfNodeId, PHTNC_MEDIA, tp.getTpId().getValue()));
             Name nepName = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
-                .setValue(String.join("+", nodeId, PHTNC_MEDIA, tpList.get(i).getTpId().getValue()))
+                .setValueName(PHTNC_MEDIA + "NodeEdgePoint")
+                .setValue(String.join("+", this.ietfNodeId, PHTNC_MEDIA, tp.getTpId().getValue()))
                 .build();
-            OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
-                .setUuid(nepUuid)
+
+            OwnedNodeEdgePoint onep = new OwnedNodeEdgePointBuilder()
+                .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId, PHTNC_MEDIA,
+                    tp.getTpId().getValue())).getBytes(Charset.forName("UTF-8"))).toString()))
                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
                 .setName(Map.of(nepName.key(), nepName))
                 .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
                 .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
                 .setLinkPortRole(PortRole.SYMMETRIC)
-                .setAdministrativeState(AdministrativeState.UNLOCKED)
-                .setOperationalState(OperationalState.ENABLED)
+                .setAdministrativeState(setTapiAdminState(admin))
+                .setOperationalState(setTapiOperationalState(oper))
                 .setLifecycleState(LifecycleState.INSTALLED)
                 .setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
-                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
-            OwnedNodeEdgePoint onep = onepBldr.build();
+                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
+                .build();
             onepMap.put(onep.key(), onep);
-        }
-        for (int i = 0; i < tpList.size(); i++) {
+
             // MC nep
-            LOG.info("NEP = {}", String.join("+", nodeId, MC, tpList.get(i).getTpId().getValue()));
-            Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, MC,
-                tpList.get(i).getTpId().getValue()))
-                .getBytes(Charset.forName("UTF-8")))
-                .toString());
-            Name nepName = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
-                .setValue(String.join("+", nodeId, MC, tpList.get(i).getTpId().getValue()))
+            LOG.info("MC NEP = {}", String.join("+", this.ietfNodeId, MC, tp.getTpId().getValue()));
+            Name nepName1 = new NameBuilder()
+                .setValueName(MC + "NodeEdgePoint")
+                .setValue(String.join("+", this.ietfNodeId, MC, tp.getTpId().getValue()))
                 .build();
-            OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
-                .setUuid(nepUuid)
+            OwnedNodeEdgePointBuilder onepBldr1 = new OwnedNodeEdgePointBuilder()
+                .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId, MC,
+                    tp.getTpId().getValue())).getBytes(Charset.forName("UTF-8"))).toString()))
                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
-                .setName(Map.of(nepName.key(), nepName))
+                .setName(Map.of(nepName1.key(), nepName1))
                 .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
                 .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
                 .setLinkPortRole(PortRole.SYMMETRIC)
-                .setAdministrativeState(AdministrativeState.UNLOCKED)
-                .setOperationalState(OperationalState.ENABLED)
+                .setAdministrativeState(setTapiAdminState(admin))
+                .setOperationalState(setTapiOperationalState(oper))
                 .setLifecycleState(LifecycleState.INSTALLED)
                 .setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
                 .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
             if (withSip) {
-                onepBldr.setMappedServiceInterfacePoint(createMSIP(1, LayerProtocolName.PHOTONICMEDIA,
-                    tpList.get(i), String.join("+", nodeId, MC)));
+                onepBldr1.setMappedServiceInterfacePoint(createMSIP(1, LayerProtocolName.PHOTONICMEDIA,
+                    tp, String.join("+", this.ietfNodeId, MC)));
             }
-            OwnedNodeEdgePoint onep = onepBldr.build();
-            onepMap.put(onep.key(), onep);
-        }
-        for (int i = 0; i < tpList.size(); i++) {
+            OwnedNodeEdgePoint onep1 = onepBldr1.build();
+            onepMap.put(onep1.key(), onep1);
+
             // OTSiMC nep
-            LOG.info("NEP = {}", String.join("+", nodeId, OTSI_MC, tpList.get(i).getTpId().getValue()));
-            Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, OTSI_MC,
-                tpList.get(i).getTpId().getValue()))
-                .getBytes(Charset.forName("UTF-8")))
-                .toString());
-            Name nepName = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
-                .setValue(String.join("+", nodeId, OTSI_MC, tpList.get(i).getTpId().getValue()))
+            LOG.info("OTSi NEP = {}", String.join("+", this.ietfNodeId, OTSI_MC, tp.getTpId().getValue()));
+            Name nepName2 = new NameBuilder()
+                .setValueName(OTSI_MC + "NodeEdgePoint")
+                .setValue(String.join("+", this.ietfNodeId, OTSI_MC, tp.getTpId().getValue()))
                 .build();
-            OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
-                .setUuid(nepUuid)
+
+            OwnedNodeEdgePoint onep2 = new OwnedNodeEdgePointBuilder()
+                .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", this.ietfNodeId, OTSI_MC,
+                    tp.getTpId().getValue())).getBytes(Charset.forName("UTF-8"))).toString()))
                 .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
-                .setName(Map.of(nepName.key(), nepName))
+                .setName(Map.of(nepName2.key(), nepName2))
                 .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
                 .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
                 .setLinkPortRole(PortRole.SYMMETRIC)
-                .setAdministrativeState(AdministrativeState.UNLOCKED)
-                .setOperationalState(OperationalState.ENABLED)
+                .setAdministrativeState(setTapiAdminState(admin))
+                .setOperationalState(setTapiOperationalState(oper))
                 .setLifecycleState(LifecycleState.INSTALLED)
                 .setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
-                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
-            OwnedNodeEdgePoint onep = onepBldr.build();
-            onepMap.put(onep.key(), onep);
+                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
+                .build();
+            onepMap.put(onep2.key(), onep2);
         }
         return onepMap;
     }
@@ -895,8 +894,8 @@ public class ConvertORTopoToTapiFullTopo {
             .build();
         ruleList.put(rule.key(), rule);
         NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
-            .setUuid(new Uuid(UUID.nameUUIDFromBytes(("rdm infra node rule group").getBytes(Charset.forName("UTF-8")))
-                .toString()))
+            .setUuid(new Uuid(UUID.nameUUIDFromBytes((this.ietfNodeId + " node rule group")
+                .getBytes(Charset.forName("UTF-8"))).toString()))
             .setRule(ruleList)
             .setNodeEdgePoint(nepMap)
             .build();
@@ -935,8 +934,10 @@ public class ConvertORTopoToTapiFullTopo {
             .setUuid(sipUuid)
             .setName(Map.of(sipName.key(), sipName))
             .setLayerProtocolName(layerProtocol)
-            .setAdministrativeState(AdministrativeState.UNLOCKED)
-            .setOperationalState(OperationalState.ENABLED)
+            .setAdministrativeState(setTapiAdminState(
+                tp.augmentation(TerminationPoint1.class).getAdministrativeState()))
+            .setOperationalState(setTapiOperationalState(
+                tp.augmentation(TerminationPoint1.class).getOperationalState()))
             .setLifecycleState(LifecycleState.INSTALLED)
             .setAvailableCapacity(new AvailableCapacityBuilder().build())
             .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().build())
@@ -962,7 +963,14 @@ public class ConvertORTopoToTapiFullTopo {
         for (SupportedInterfaceCapability sic : sicList) {
             switch (lpn.getName()) {
                 case "DSR":
+                case "ODU":
                     switch (sic.getIfCapType().getSimpleName()) {
+                        // TODO: it may be needed to add more cases clauses if the interface capabilities of a
+                        //  port are extended in the config file
+                        case "If1GEODU0":
+                            sclpqSet.add(ODUTYPEODU0.class);
+                            sclpqSet.add(DIGITALSIGNALTYPEGigE.class);
+                            break;
                         case "If10GEODU2e":
                             sclpqSet.add(ODUTYPEODU2E.class);
                             sclpqSet.add(DIGITALSIGNALTYPE10GigELAN.class);
@@ -1181,8 +1189,6 @@ public class ConvertORTopoToTapiFullTopo {
                     .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
                         .setRestorationPolicy(RestorationPolicy.NA)
                         .build())
-                    .setAdministrativeState(AdministrativeState.UNLOCKED)
-                    .setOperationalState(OperationalState.ENABLED)
                     .setLifecycleState(LifecycleState.INSTALLED)
                     .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
                     .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
@@ -1241,8 +1247,6 @@ public class ConvertORTopoToTapiFullTopo {
                     .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
                         .setRestorationPolicy(RestorationPolicy.NA)
                         .build())
-                    .setAdministrativeState(AdministrativeState.UNLOCKED)
-                    .setOperationalState(OperationalState.ENABLED)
                     .setLifecycleState(LifecycleState.INSTALLED)
                     .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
                     .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
@@ -1262,11 +1266,23 @@ public class ConvertORTopoToTapiFullTopo {
     }
 
     private Link createTapiOmsLink(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-                                       .ietf.network.topology.rev180226.networks.network.Link link) {
+                                       .ietf.network.topology.rev180226.networks.network.Link link,
+                                   org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                                       .ietf.network.topology.rev180226.networks.network.Link oppositeLink) {
         String sourceNode = getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue());
         String sourceTp = link.getSource().getSourceTp().getValue();
         String destNode = getIdBasedOnModelVersion(link.getDestination().getDestNode().getValue());
         String destTp = link.getDestination().getDestTp().getValue();
+        AdminStates oppositeLinkAdminState = null;
+        State oppositeLinkOperState = null;
+        if (oppositeLink != null) {
+            oppositeLinkAdminState = oppositeLink.augmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                .getAdministrativeState();
+            oppositeLinkOperState = oppositeLink.augmentation(
+                org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                .getOperationalState();
+        }
         Map<NodeEdgePointKey, NodeEdgePoint> nepList = new HashMap<>();
         Uuid sourceUuidNode = new Uuid(UUID.nameUUIDFromBytes((String.join("+", sourceNode,
             PHTNC_MEDIA)).getBytes(Charset.forName("UTF-8"))).toString());
@@ -1324,8 +1340,14 @@ public class ConvertORTopoToTapiFullTopo {
             .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
                 .setRestorationPolicy(RestorationPolicy.NA)
                 .build())
-            .setAdministrativeState(AdministrativeState.UNLOCKED)
-            .setOperationalState(OperationalState.ENABLED)
+            .setAdministrativeState(setTapiAdminState(link
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                .getAdministrativeState(), oppositeLinkAdminState))
+            .setOperationalState(setTapiOperationalState(link
+                .augmentation(
+                    org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                .getOperationalState(), oppositeLinkOperState))
             .setLifecycleState(LifecycleState.INSTALLED)
             .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize(
                 new TotalSizeBuilder().setUnit(CapacityUnit.GBPS)
@@ -1355,6 +1377,22 @@ public class ConvertORTopoToTapiFullTopo {
         for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
             .ietf.network.topology.rev180226.networks.network.Link link:xpdrRdmLinkList) {
             if (!linksToNotConvert.contains(link.getLinkId().getValue())) {
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                    .ietf.network.topology.rev180226.networks.network.Link oppositeLink = xpdrRdmLinkList.stream()
+                    .filter(l -> l.getLinkId().equals(link.augmentation(org.opendaylight.yang.gen.v1.http
+                        .org.openroadm.common.network.rev200529.Link1.class).getOppositeLink())).findAny().orElse(null);
+
+                AdminStates oppositeLinkAdminState = null;
+                State oppositeLinkOperState = null;
+                if (oppositeLink != null) {
+                    oppositeLinkAdminState = oppositeLink.augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                        .getAdministrativeState();
+                    oppositeLinkOperState = oppositeLink.augmentation(
+                        org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                        .getOperationalState();
+                }
+
                 String sourceNode = (link.getSource().getSourceNode().getValue().contains("ROADM"))
                     ? getIdBasedOnModelVersion(link.getSource().getSourceNode().getValue())
                     : link.getSource().getSourceNode().getValue();
@@ -1425,8 +1463,14 @@ public class ConvertORTopoToTapiFullTopo {
                     .setResilienceType(new ResilienceTypeBuilder().setProtectionType(ProtectionType.NOPROTECTON)
                         .setRestorationPolicy(RestorationPolicy.NA)
                         .build())
-                    .setAdministrativeState(AdministrativeState.UNLOCKED)
-                    .setOperationalState(OperationalState.ENABLED)
+                    .setAdministrativeState(setTapiAdminState(link
+                        .augmentation(
+                            org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                        .getAdministrativeState(), oppositeLinkAdminState))
+                    .setOperationalState(setTapiOperationalState(link
+                        .augmentation(
+                            org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1.class)
+                        .getOperationalState(), oppositeLinkOperState))
                     .setLifecycleState(LifecycleState.INSTALLED)
                     .setTotalPotentialCapacity(new TotalPotentialCapacityBuilder().setTotalSize(
                         new TotalSizeBuilder().setUnit(CapacityUnit.GBPS)
index 0abf75a6adcbb979d9f27a3f91832c75e3ba2093..351315c960c9a4cd436acf840d9c133e33b23482 100644 (file)
@@ -540,11 +540,8 @@ public class ConvertORTopoToTapiTopo {
         OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
             .setUuid(this.uuidMap.get(key))
             .setLayerProtocolName(nepProtocol)
-            .setName(nepNames);
-        if (withSip) {
-            onepBldr.setMappedServiceInterfacePoint(createSIP(this.uuidMap.get(key), 1));
-        }
-        onepBldr.setSupportedCepLayerProtocolQualifier(createSupportedCepLayerProtocolQualifier(oorTp, nodeProtocol))
+            .setName(nepNames)
+            .setSupportedCepLayerProtocolQualifier(createSupportedCepLayerProtocolQualifier(oorTp, nodeProtocol))
             .setLinkPortDirection(PortDirection.BIDIRECTIONAL)
             .setLinkPortRole(PortRole.SYMMETRIC)
             .setAdministrativeState(setTapiAdminState(
@@ -554,6 +551,9 @@ public class ConvertORTopoToTapiTopo {
             .setLifecycleState(LifecycleState.INSTALLED)
             .setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
             .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
+        if (withSip) {
+            onepBldr.setMappedServiceInterfacePoint(createSIP(1, oorTp, keyword));
+        }
         return onepBldr.build();
     }
 
@@ -614,12 +614,13 @@ public class ConvertORTopoToTapiTopo {
         return nodeRuleGroupMap;
     }
 
-    private Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint> createSIP(Uuid nepUuid, int nb) {
+    private Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint> createSIP(int nb, TerminationPoint tp,
+            String nodeId) {
         Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint> msipl = new HashMap<>();
         for (int i = 0; i < nb; i++) {
             MappedServiceInterfacePoint msip = new MappedServiceInterfacePointBuilder()
-                .setServiceInterfacePointUuid(new Uuid(UUID.nameUUIDFromBytes(nepUuid.getValue()
-                    .getBytes(Charset.forName("UTF-8"))).toString()))
+                .setServiceInterfacePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", nodeId,
+                    tp.getTpId().getValue())).getBytes(Charset.forName("UTF-8"))).toString()))
                 .build();
             msipl.put(msip.key(), msip);
         }
index 5de39efb1e95ddf32b75ac41e191428408f1fa74..eee0ba1fbeb8ef921ca1a43f524a6ae21f743f92 100644 (file)
@@ -84,6 +84,8 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev18121
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE100GigE;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE10GigELAN;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPEGigE;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU0;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2E;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU4;
@@ -241,9 +243,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
 
                     // node transformation
                     Map<NodeKey, Node> nodeMap = new HashMap<>(transformXpdrToTapiNode(
-                        nodeId, xpdrClMaps, xpdrNetMaps, mapping.getXponderType(), oorOduSwitchingPool,
-                        mapping.getSupportedInterfaceCapability()));
-
+                        nodeId, xpdrClMaps, xpdrNetMaps, mapping.getXponderType(), oorOduSwitchingPool));
                     // add nodes and sips to tapi context
                     mergeNodeinTopology(nodeMap);
                     mergeSipsinContext(this.sipMap);
@@ -255,9 +255,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
 
     private Map<NodeKey, Node> transformXpdrToTapiNode(String nodeId, List<Mapping> xpdrClMaps,
                                                        List<Mapping> xpdrNetMaps, XpdrNodeTypes xponderType,
-                                                       OduSwitchingPools oorOduSwitchingPool,
-                                                       List<Class<? extends SupportedIfCapability>>
-                                                           supportedInterfaceCapability) {
+                                                       OduSwitchingPools oorOduSwitchingPool) {
         Map<NodeKey, Node> nodeMap = new HashMap<>();
         LOG.info("creation of a DSR/ODU node for {}", nodeId);
         Uuid nodeUuidDsr = new Uuid(UUID.nameUUIDFromBytes((String.join("+", nodeId, DSR))
@@ -268,8 +266,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
             LayerProtocolName.ODU);
         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology
             .Node dsrNode = createTapiXpdrNode(Map.of(nameDsr.key(), nameDsr), dsrLayerProtocols,
-            nodeId, nodeUuidDsr, xpdrClMaps, xpdrNetMaps, xponderType, oorOduSwitchingPool,
-            supportedInterfaceCapability);
+            nodeId, nodeUuidDsr, xpdrClMaps, xpdrNetMaps, xponderType, oorOduSwitchingPool);
 
         nodeMap.put(dsrNode.key(), dsrNode);
 
@@ -282,8 +279,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
         List<LayerProtocolName> otsiLayerProtocols = Arrays.asList(LayerProtocolName.PHOTONICMEDIA);
         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology
             .Node otsiNode = createTapiXpdrNode(Map.of(nameOtsi.key(), nameOtsi), otsiLayerProtocols,
-            nodeId, nodeUuidOtsi, xpdrClMaps, xpdrNetMaps, xponderType, null,
-            supportedInterfaceCapability);
+            nodeId, nodeUuidOtsi, xpdrClMaps, xpdrNetMaps, xponderType, null);
 
         nodeMap.put(otsiNode.key(), otsiNode);
 
@@ -452,8 +448,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
 
     private Node createTapiXpdrNode(Map<NameKey, Name> nameMap, List<LayerProtocolName> layerProtocols,
                                     String nodeId, Uuid nodeUuid, List<Mapping> xpdrClMaps, List<Mapping> xpdrNetMaps,
-                                    XpdrNodeTypes xponderType, OduSwitchingPools oorOduSwitchingPool,
-                                    List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability) {
+                                    XpdrNodeTypes xponderType, OduSwitchingPools oorOduSwitchingPool) {
         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
         Map<NodeRuleGroupKey, NodeRuleGroup> nodeRuleGroupList = new HashMap<>();
         Map<RuleKey, Rule> ruleList = new HashMap<>();
@@ -466,13 +461,13 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
         if (layerProtocols.contains(LayerProtocolName.DSR)) {
             // neps for dsr/odu layer
             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> dsroduNeps =
-                    createXpdrDsrOduNeps(nodeId, xpdrClMaps, xpdrNetMaps, xponderType, supportedInterfaceCapability);
+                    createXpdrDsrOduNeps(nodeId, xpdrClMaps, xpdrNetMaps, xponderType);
             onepl.putAll(dsroduNeps);
             nodeRuleGroupList = createNodeRuleGroupForDsrNode(nodeId, oorOduSwitchingPool, ruleList, onepl);
         } else if (layerProtocols.contains(LayerProtocolName.PHOTONICMEDIA)) {
             // neps for photonic layer
             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> phtmdNeps =
-                    createXpdrPhtnMdNeps(nodeId, xpdrNetMaps, supportedInterfaceCapability);
+                    createXpdrPhtnMdNeps(nodeId, xpdrNetMaps);
             onepl.putAll(phtmdNeps);
             nodeRuleGroupList = createNodeRuleGroupForOtsiNode(nodeId, xpdrNetMaps, ruleList);
         } else {
@@ -513,7 +508,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
     }
 
     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> createXpdrPhtnMdNeps(String nodeId,
-            List<Mapping> xpdrNetMaps, List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability) {
+                                                                                List<Mapping> xpdrNetMaps) {
         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
 
         // iNep creation on otsi node
@@ -528,10 +523,11 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                     .build();
 
             OwnedNodeEdgePoint onep = createNep(nepUuid1, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
-                    true, String.join("+", nodeId, I_OTSI), supportedInterfaceCapability,
-                    transformOperState(xpdrNetMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
+                Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
+                true, String.join("+", nodeId, I_OTSI),
+                xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrNetMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         // eNep creation on otsi node
@@ -545,10 +541,11 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                     .build();
 
             OwnedNodeEdgePoint onep = createNep(nepUuid2, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
-                    false, String.join("+", nodeId, E_OTSI), supportedInterfaceCapability,
-                    transformOperState(xpdrNetMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
+                Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
+                false, String.join("+", nodeId, E_OTSI),
+                xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrNetMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         // Photonic Media Nep creation on otsi node
@@ -562,18 +559,19 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                     .build();
 
             OwnedNodeEdgePoint onep = createNep(nepUuid3, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
-                    false, String.join("+", nodeId, PHTNC_MEDIA), supportedInterfaceCapability,
-                    transformOperState(xpdrNetMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
+                Map.of(onedName.key(), onedName), LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.PHOTONICMEDIA,
+                false, String.join("+", nodeId, PHTNC_MEDIA),
+                xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrNetMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         return onepl;
     }
 
     private Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> createXpdrDsrOduNeps(String nodeId, List<Mapping> xpdrClMaps,
-            List<Mapping> xpdrNetMaps, XpdrNodeTypes xponderType,
-            List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability) {
+                                                                                List<Mapping> xpdrNetMaps,
+                                                                                XpdrNodeTypes xponderType) {
         Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepl = new HashMap<>();
         // client nep creation on DSR node
         for (int i = 0; i < xpdrClMaps.size(); i++) {
@@ -591,10 +589,10 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
             }
 
             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrClMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(name.key(), name), LayerProtocolName.DSR, LayerProtocolName.DSR, true,
-                    String.join("+", nodeId, DSR), supportedInterfaceCapability,
-                    transformOperState(xpdrClMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrClMaps.get(i).getPortAdminState()));
+                Map.of(name.key(), name), LayerProtocolName.DSR, LayerProtocolName.DSR, true,
+                String.join("+", nodeId, DSR), xpdrClMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrClMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrClMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         // network nep creation on I_ODU node
@@ -609,16 +607,17 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                     .build();
 
             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(onedName.key(), onedName),
-                    LayerProtocolName.ODU, LayerProtocolName.DSR, false,
-                    String.join("+", nodeId, I_ODU), supportedInterfaceCapability,
-                    transformOperState(xpdrNetMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
+                Map.of(onedName.key(), onedName),
+                LayerProtocolName.ODU, LayerProtocolName.DSR, false,
+                String.join("+", nodeId, I_ODU), xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrNetMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         // network nep creation on E_ODU node
         for (int i = 0; i < xpdrNetMaps.size(); i++) {
-            LOG.info("eODU NEP = {}", String.join("+", nodeId, E_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()));
+            LOG.info("eODU NEP = {}", String.join("+", nodeId, E_ODU,
+                xpdrNetMaps.get(i).getLogicalConnectionPoint()));
             Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(
                     (String.join("+", nodeId, E_ODU, xpdrNetMaps.get(i).getLogicalConnectionPoint()))
                             .getBytes(Charset.forName("UTF-8"))).toString());
@@ -628,11 +627,11 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                     .build();
 
             OwnedNodeEdgePoint onep = createNep(nepUuid, xpdrNetMaps.get(i).getLogicalConnectionPoint(),
-                    Map.of(onedName.key(), onedName),
-                    LayerProtocolName.ODU, LayerProtocolName.DSR, true,
-                    String.join("+", nodeId, E_ODU), supportedInterfaceCapability,
-                    transformOperState(xpdrNetMaps.get(i).getPortOperState()),
-                    transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
+                Map.of(onedName.key(), onedName),
+                LayerProtocolName.ODU, LayerProtocolName.DSR, true,
+                String.join("+", nodeId, E_ODU), xpdrNetMaps.get(i).getSupportedInterfaceCapability(),
+                transformOperState(xpdrNetMaps.get(i).getPortOperState()),
+                transformAdminState(xpdrNetMaps.get(i).getPortAdminState()));
             onepl.put(onep.key(), onep);
         }
         return onepl;
@@ -681,19 +680,19 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                 .getBytes(Charset.forName("UTF-8")))
                 .toString());
         Name nepName = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
+                .setValueName(PHTNC_MEDIA + "NodeEdgePoint")
                 .setValue(String.join("+", orNodeId, PHTNC_MEDIA, tpId))
                 .build();
-        OwnedNodeEdgePointBuilder onepBldr = new OwnedNodeEdgePointBuilder()
-                .setUuid(nepUuid)
-                .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
-                .setName(Map.of(nepName.key(), nepName))
-                .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
-                .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
-                .setAdministrativeState(adminState).setOperationalState(operState)
-                .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
-                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
-        OwnedNodeEdgePoint onep = onepBldr.build();
+        OwnedNodeEdgePoint onep = new OwnedNodeEdgePointBuilder()
+            .setUuid(nepUuid)
+            .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
+            .setName(Map.of(nepName.key(), nepName))
+            .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
+            .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
+            .setAdministrativeState(adminState).setOperationalState(operState)
+            .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
+            .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
+            .build();
         onepMap.put(onep.key(), onep);
 
         // MC nep
@@ -701,7 +700,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                 .getBytes(Charset.forName("UTF-8")))
                 .toString());
         Name nepName1 = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
+                .setValueName(MC + "NodeEdgePoint")
                 .setValue(String.join("+", orNodeId, MC, tpId))
                 .build();
         OwnedNodeEdgePointBuilder onepBldr1 = new OwnedNodeEdgePointBuilder()
@@ -725,25 +724,26 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                 .getBytes(Charset.forName("UTF-8")))
                 .toString());
         Name nepName2 = new NameBuilder()
-                .setValueName("NodeEdgePoint name")
+                .setValueName(OTSI_MC + "NodeEdgePoint")
                 .setValue(String.join("+", orNodeId, OTSI_MC, tpId))
                 .build();
-        OwnedNodeEdgePointBuilder onepBldr2 = new OwnedNodeEdgePointBuilder()
-                .setUuid(nepUuid2)
-                .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
-                .setName(Map.of(nepName2.key(), nepName2))
-                .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
-                .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
-                .setAdministrativeState(adminState).setOperationalState(operState)
-                .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
-                .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL);
-        OwnedNodeEdgePoint onep2 = onepBldr2.build();
+
+        OwnedNodeEdgePoint onep2 = new OwnedNodeEdgePointBuilder()
+            .setUuid(nepUuid2)
+            .setLayerProtocolName(LayerProtocolName.PHOTONICMEDIA)
+            .setName(Map.of(nepName2.key(), nepName2))
+            .setSupportedCepLayerProtocolQualifier(List.of(PHOTONICLAYERQUALIFIEROMS.class))
+            .setLinkPortDirection(PortDirection.BIDIRECTIONAL).setLinkPortRole(PortRole.SYMMETRIC)
+            .setAdministrativeState(adminState).setOperationalState(operState)
+            .setLifecycleState(LifecycleState.INSTALLED).setTerminationDirection(TerminationDirection.BIDIRECTIONAL)
+            .setTerminationState(TerminationState.TERMINATEDBIDIRECTIONAL)
+            .build();
         onepMap.put(onep2.key(), onep2);
         return onepMap;
     }
 
     private Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint>
-        createMSIP(int nb, LayerProtocolName layerProtocol, String tpid, String nodeid,
+            createMSIP(int nb, LayerProtocolName layerProtocol, String tpid, String nodeid,
                    List<Class<? extends SupportedIfCapability>> supportedInterfaceCapability,
                    OperationalState operState, AdministrativeState adminState) {
         Map<MappedServiceInterfacePointKey, MappedServiceInterfacePoint> msipl = new HashMap<>();
@@ -817,7 +817,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
             .setOperationalState(OperationalState.ENABLED)
             .setLifecycleState(LifecycleState.INSTALLED)
             .setOwnedNodeEdgePoint(oneplist)
-            .setNodeRuleGroup(createNodeRuleGroupForRdmNode(nodeUuid, oneplist.values()))
+            .setNodeRuleGroup(createNodeRuleGroupForRdmNode(orNodeId, nodeUuid, oneplist.values()))
             .setCostCharacteristic(Map.of(costCharacteristic.key(), costCharacteristic))
             .setLatencyCharacteristic(Map.of(latencyCharacteristic.key(), latencyCharacteristic))
             .setErrorCharacteristic("error")
@@ -829,7 +829,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
             .build();
     }
 
-    private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForRdmNode(Uuid nodeUuid,
+    private Map<NodeRuleGroupKey, NodeRuleGroup> createNodeRuleGroupForRdmNode(String orNodeId, Uuid nodeUuid,
                                                                                Collection<OwnedNodeEdgePoint> onepl) {
         Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePointKey,
                 org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint>
@@ -853,7 +853,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                 .build();
         ruleList.put(rule.key(), rule);
         NodeRuleGroup nodeRuleGroup = new NodeRuleGroupBuilder()
-                .setUuid(new Uuid(UUID.nameUUIDFromBytes(("rdm infra node rule group")
+                .setUuid(new Uuid(UUID.nameUUIDFromBytes((orNodeId + " node rule group")
                         .getBytes(Charset.forName("UTF-8"))).toString()))
                 .setRule(ruleList)
                 .setNodeEdgePoint(nepMap)
@@ -1165,6 +1165,12 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
                 case "DSR":
                 case "ODU":
                     switch (sic.getIfCapType().getSimpleName()) {
+                        // TODO: it may be needed to add more cases clauses if the interface capabilities of a
+                        //  port are extended in the config file
+                        case "If1GEODU0":
+                            sclpqList.add(ODUTYPEODU0.class);
+                            sclpqList.add(DIGITALSIGNALTYPEGigE.class);
+                            break;
                         case "If10GEODU2e":
                             sclpqList.add(ODUTYPEODU2E.class);
                             sclpqList.add(DIGITALSIGNALTYPE10GigELAN.class);
@@ -1254,7 +1260,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService {
         } catch (InterruptedException | ExecutionException e) {
             LOG.error("Error populating TAPI topology: ", e);
         }
-        LOG.info("Roadm Node added succesfully.");
+        LOG.info("Node added succesfully.");
     }
 
     private void mergeLinkinTopology(Map<LinkKey, Link> linkMap) {
index aa47df70207c82f6314ca2d6bbf00edc99e7a96d..3e2ed2aec7daad484ee090d12feafe9729d50a7b 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.transportpce.tapi.topology;
 import com.google.common.util.concurrent.FluentFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -127,11 +128,9 @@ public class TapiTopologyImpl implements TapiTopologyService, TapiCommonService
     public ListenableFuture<RpcResult<GetNodeDetailsOutput>> getNodeDetails(GetNodeDetailsInput input) {
         // TODO Auto-generated method stub
         // TODO -> maybe we get errors when having CEPs?
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid topoUuid = getUuidFromIput(input.getTopologyIdOrName());
         // Node id: if roadm -> ROADM+PHOTONIC_MEDIA. if xpdr -> XPDR-XPDR+DSR/OTSi
-        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid nodeUuid = getUuidFromIput(input.getNodeIdOrName());
         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node = this.tapiContext
                 .getTapiNode(topoUuid, nodeUuid);
         if (node == null) {
@@ -309,15 +308,12 @@ public class TapiTopologyImpl implements TapiTopologyService, TapiCommonService
             GetNodeEdgePointDetailsInput input) {
         // TODO Auto-generated method stub
         // TODO -> maybe we get errors when having CEPs?
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid topoUuid = getUuidFromIput(input.getTopologyIdOrName());
         // Node id: if roadm -> ROADMid+PHOTONIC_MEDIA. if xpdr -> XPDRid-XPDRnbr+DSR/OTSi
-        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(input.getNodeIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid nodeUuid = getUuidFromIput(input.getNodeIdOrName());
         // NEP id: if roadm -> ROADMid+PHOTONIC_MEDIA/MC/OTSiMC+TPid.
         // if xpdr -> XPDRid-XPDRnbr+DSR/eODU/iODU/iOTSi/eOTSi/PHOTONIC_MEDIA+TPid
-        Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(input.getEpIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid nepUuid = getUuidFromIput(input.getEpIdOrName());
         OwnedNodeEdgePoint nep = this.tapiContext.getTapiNEP(topoUuid, nodeUuid, nepUuid);
         if (nep == null) {
             LOG.error("Invalid TAPI nep name");
@@ -331,11 +327,9 @@ public class TapiTopologyImpl implements TapiTopologyService, TapiCommonService
     @Override
     public ListenableFuture<RpcResult<GetLinkDetailsOutput>> getLinkDetails(GetLinkDetailsInput input) {
         // TODO Auto-generated method stub
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(input.getTopologyIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid topoUuid = getUuidFromIput(input.getTopologyIdOrName());
         // Link id: same as OR link id
-        Uuid linkUuid = new Uuid(UUID.nameUUIDFromBytes(input.getLinkIdOrName().getBytes(Charset.forName("UTF-8")))
-                .toString());
+        Uuid linkUuid = getUuidFromIput(input.getLinkIdOrName());
         org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link link = this.tapiContext
                 .getTapiLink(topoUuid, linkUuid);
         if (link == null) {
@@ -492,7 +486,7 @@ public class TapiTopologyImpl implements TapiTopologyService, TapiCommonService
     @Override
     public ListenableFuture<RpcResult<GetServiceInterfacePointDetailsOutput>>
             getServiceInterfacePointDetails(GetServiceInterfacePointDetailsInput input) {
-        Uuid sipUuid = new Uuid(input.getSipIdOrName());
+        Uuid sipUuid = getUuidFromIput(input.getSipIdOrName());
         Map<ServiceInterfacePointKey, ServiceInterfacePoint> sips =
             this.tapiContext.getTapiContext().getServiceInterfacePoint();
         if (sips == null || sips.isEmpty()) {
@@ -537,4 +531,15 @@ public class TapiTopologyImpl implements TapiTopologyService, TapiCommonService
         // TODO --> not yet implemented
         return null;
     }
+
+    private Uuid getUuidFromIput(String serviceIdOrName) {
+        try {
+            UUID.fromString(serviceIdOrName);
+            LOG.info("Given attribute {} is a UUID", serviceIdOrName);
+            return new Uuid(serviceIdOrName);
+        } catch (IllegalArgumentException e) {
+            LOG.info("Given attribute {} is not a UUID", serviceIdOrName);
+            return new Uuid(UUID.nameUUIDFromBytes(serviceIdOrName.getBytes(StandardCharsets.UTF_8)).toString());
+        }
+    }
 }
index 27b7e79e1c8583e77d01e307810374559cac1ae8..89d7275f04a50c5c04c140a2b8f4cbe577794cd7 100644 (file)
@@ -101,108 +101,116 @@ public final class TopologyUtils {
     public Topology createFullOtnTopology() throws TapiTopologyException {
         // read openroadm-topology
         Network openroadmTopo = readTopology(InstanceIdentifiers.OVERLAY_NETWORK_II);
-        List<Link> linkList = new ArrayList<>();
-        if (openroadmTopo.augmentation(Network1.class) != null) {
-            linkList.addAll(openroadmTopo.augmentation(Network1.class).getLink().values());
-        }
-        List<Link> xponderOutLinkList = linkList.stream()
-            .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDEROUTPUT))
-            .collect(Collectors.toList());
-        List<Link> xponderInLinkList = linkList.stream()
-            .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDERINPUT))
-            .collect(Collectors.toList());
-        // read otn-topology
-        Network otnTopo = readTopology(InstanceIdentifiers.OTN_NETWORK_II);
-        Map<NodeId, org.opendaylight.yang.gen.v1.urn
-            .ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node> otnNodeMap = otnTopo.nonnullNode()
-            .values().stream().collect(Collectors.toMap(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-                .ietf.network.rev180226.networks.network.Node::getNodeId, node -> node));
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Name name = new NameBuilder().setValue(TopologyUtils.T0_FULL_MULTILAYER).setValueName("TAPI Topology Name")
+            .build();
+        if (openroadmTopo != null) {
+            List<Link> linkList = new ArrayList<>();
+            if (openroadmTopo.augmentation(Network1.class) != null) {
+                linkList.addAll(openroadmTopo.augmentation(Network1.class).getLink().values());
+            }
+            List<Link> xponderOutLinkList = linkList.stream()
+                .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDEROUTPUT))
+                .collect(Collectors.toList());
+            List<Link> xponderInLinkList = linkList.stream()
+                .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDERINPUT))
+                .collect(Collectors.toList());
+            // read otn-topology
+            Network otnTopo = readTopology(InstanceIdentifiers.OTN_NETWORK_II);
+            Map<NodeId, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                .ietf.network.rev180226.networks.network.Node> otnNodeMap = otnTopo.nonnullNode()
+                .values().stream().collect(Collectors.toMap(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                    .ietf.network.rev180226.networks.network.Node::getNodeId, node -> node));
 
-        Map<String, List<String>> networkPortMap = new HashMap<>();
-        Iterator<Map.Entry<NodeId, org.opendaylight.yang.gen.v1.urn
-            .ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node>> itOtnNodeMap = otnNodeMap
-            .entrySet().iterator();
-        while (itOtnNodeMap.hasNext()) {
-            Map.Entry<NodeId, org.opendaylight.yang.gen.v1.urn
-                .ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node> entry = itOtnNodeMap.next();
-            String portMappingNodeId = entry.getValue().getSupportingNode().values().stream()
-                .filter(sn -> sn.getNetworkRef().getValue().equals(NetworkUtils.UNDERLAY_NETWORK_ID))
-                .findFirst()
-                .get().getNodeRef().getValue();
-            List<String> networkPortList = new ArrayList<>();
-            for (TerminationPoint tp: entry.getValue().augmentation(Node1.class).getTerminationPoint().values()) {
-                // TODO -> why are we checking with respect to XPDR links?? Is there a real purpose on doing that?
-                if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)
-                    && checkTp(entry.getKey().getValue(), portMappingNodeId, tp, xponderOutLinkList,
-                    xponderInLinkList)) {
-                    networkPortList.add(tp.getTpId().getValue());
+            Map<String, List<String>> networkPortMap = new HashMap<>();
+            Iterator<Map.Entry<NodeId, org.opendaylight.yang.gen.v1.urn
+                .ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node>> itOtnNodeMap = otnNodeMap
+                .entrySet().iterator();
+            while (itOtnNodeMap.hasNext()) {
+                Map.Entry<NodeId, org.opendaylight.yang.gen.v1.urn
+                    .ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node> entry = itOtnNodeMap.next();
+                String portMappingNodeId = entry.getValue().getSupportingNode().values().stream()
+                    .filter(sn -> sn.getNetworkRef().getValue().equals(NetworkUtils.UNDERLAY_NETWORK_ID))
+                    .findFirst()
+                    .get().getNodeRef().getValue();
+                List<String> networkPortList = new ArrayList<>();
+                for (TerminationPoint tp: entry.getValue().augmentation(Node1.class).getTerminationPoint().values()) {
+                    // TODO -> why are we checking with respect to XPDR links?? Is there a real purpose on doing that?
+                    if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)
+                        && checkTp(entry.getKey().getValue(), portMappingNodeId, tp, xponderOutLinkList,
+                        xponderInLinkList)) {
+                        networkPortList.add(tp.getTpId().getValue());
+                    }
+                }
+                if (!networkPortList.isEmpty()) {
+                    networkPortMap.put(entry.getKey().getValue(), networkPortList);
                 }
             }
-            if (!networkPortList.isEmpty()) {
-                networkPortMap.put(entry.getKey().getValue(), networkPortList);
+            Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node>
+                tapiNodeList = new HashMap<>();
+            Map<LinkKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link>
+                tapiLinkList = new HashMap<>();
+            ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topoUuid);
+            Iterator<Map.Entry<String, List<String>>> it = networkPortMap.entrySet().iterator();
+            while (it.hasNext()) {
+                String nodeId = it.next().getKey();
+                tapiFactory.convertNode(otnNodeMap.get(new NodeId(nodeId)), networkPortMap.get(nodeId));
+                tapiNodeList.putAll(tapiFactory.getTapiNodes());
+                tapiLinkList.putAll(tapiFactory.getTapiLinks());
             }
-        }
-        Map<NodeKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node>
-            tapiNodeList = new HashMap<>();
-        Map<LinkKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link>
-            tapiLinkList = new HashMap<>();
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER
-            .getBytes(Charset.forName("UTF-8"))).toString());
-        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topoUuid);
-        Iterator<Map.Entry<String, List<String>>> it = networkPortMap.entrySet().iterator();
-        while (it.hasNext()) {
-            String nodeId = it.next().getKey();
-            tapiFactory.convertNode(otnNodeMap.get(new NodeId(nodeId)), networkPortMap.get(nodeId));
-            tapiNodeList.putAll(tapiFactory.getTapiNodes());
-            tapiLinkList.putAll(tapiFactory.getTapiLinks());
-        }
-        // roadm infrastructure not abstracted
-        // read openroadm-network
-        Network openroadmNet = readTopology(InstanceIdentifiers.UNDERLAY_NETWORK_II);
-        if (openroadmNet != null && openroadmNet.nonnullNode().values().stream().filter(nt ->
+            // roadm infrastructure not abstracted
+            // read openroadm-network
+            Network openroadmNet = readTopology(InstanceIdentifiers.UNDERLAY_NETWORK_II);
+            if (openroadmNet != null && openroadmNet.nonnullNode().values().stream().filter(nt ->
                 nt.augmentation(org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Node1.class)
-                        .getNodeType().equals(OpenroadmNodeType.ROADM)).count() > 0) {
-            // map roadm nodes
-            for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node
-                    roadm:openroadmNet.nonnullNode().values().stream().filter(
-                            nt -> nt.augmentation(org.opendaylight.yang.gen.v1.http
-                            .org.openroadm.common.network.rev200529.Node1.class)
-                            .getNodeType().equals(OpenroadmNodeType.ROADM))
+                    .getNodeType().equals(OpenroadmNodeType.ROADM)).count() > 0) {
+                // map roadm nodes
+                for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                    .ietf.network.rev180226.networks.network.Node roadm:openroadmNet.nonnullNode().values().stream()
+                    .filter(nt -> nt.augmentation(org.opendaylight.yang.gen.v1.http
+                        .org.openroadm.common.network.rev200529.Node1.class)
+                        .getNodeType().equals(OpenroadmNodeType.ROADM))
                     .collect(Collectors.toList())) {
-                tapiFactory.convertRoadmNode(roadm, openroadmTopo);
-                tapiNodeList.putAll(tapiFactory.getTapiNodes());
+                    tapiFactory.convertRoadmNode(roadm, openroadmTopo);
+                    tapiNodeList.putAll(tapiFactory.getTapiNodes());
+                }
+            } else {
+                LOG.warn("No roadm nodes exist in the network");
             }
-        } else {
-            LOG.warn("No roadm nodes exist in the network");
-        }
-        // map roadm to roadm link
-        List<Link> rdmTordmLinkList = linkList.stream()
+            // map roadm to roadm link
+            List<Link> rdmTordmLinkList = linkList.stream()
                 .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.ROADMTOROADM))
                 .collect(Collectors.toList());
-        tapiFactory.convertRdmToRdmLinks(rdmTordmLinkList);
-        tapiLinkList.putAll(tapiFactory.getTapiLinks());
-        // map xpdr_input to roadm and xpdr_output to roadm links.
-        xponderInLinkList.addAll(xponderOutLinkList);
-        tapiFactory.convertXpdrToRdmLinks(xponderInLinkList);
-        tapiLinkList.putAll(tapiFactory.getTapiLinks());
+            tapiFactory.convertRdmToRdmLinks(rdmTordmLinkList);
+            tapiLinkList.putAll(tapiFactory.getTapiLinks());
+            // map xpdr_input to roadm and xpdr_output to roadm links.
+            xponderInLinkList.addAll(xponderOutLinkList);
+            tapiFactory.convertXpdrToRdmLinks(xponderInLinkList);
+            tapiLinkList.putAll(tapiFactory.getTapiLinks());
 
-        if (otnTopo.augmentation(Network1.class) != null) {
-            Map<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
+            if (otnTopo.augmentation(Network1.class) != null) {
+                Map<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks
                     .network.LinkKey, Link> otnLinkMap = otnTopo.augmentation(Network1.class).getLink();
-            tapiFactory.convertLinks(otnLinkMap);
-            tapiLinkList.putAll(tapiFactory.getTapiLinks());
-        }
-        Name name = new NameBuilder().setValue(TopologyUtils.T0_FULL_MULTILAYER).setValueName("TAPI Topology Name")
-                .build();
-        // Retrieve created sips map in TapiFactory when mapping all the nodes
-        this.tapiSips = tapiFactory.getTapiSips();
-        return new TopologyBuilder()
+                tapiFactory.convertLinks(otnLinkMap);
+                tapiLinkList.putAll(tapiFactory.getTapiLinks());
+            }
+            // Retrieve created sips map in TapiFactory when mapping all the nodes
+            this.tapiSips = tapiFactory.getTapiSips();
+            return new TopologyBuilder()
                 .setName(Map.of(name.key(), name))
                 .setUuid(topoUuid)
                 .setNode(tapiNodeList)
                 .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU,
-                        LayerProtocolName.DSR))
+                    LayerProtocolName.DSR))
                 .setLink(tapiLinkList).build();
+        }
+        return new TopologyBuilder()
+            .setName(Map.of(name.key(), name))
+            .setUuid(topoUuid)
+            .setLayerProtocolName(List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU,
+                LayerProtocolName.DSR))
+            .build();
     }
 
     public Map<ServiceInterfacePointKey, ServiceInterfacePoint> getSipMap() {
@@ -312,5 +320,4 @@ public final class TopologyUtils {
         topologyBuilder.setNode(mapNode);
         return topologyBuilder.build();
     }
-
-}
+}
\ No newline at end of file
index 14fdb46df990f45c6776d470db1309b71c9001bc..045577c1fb29fdcf5c54b28af39fe70bd682456a 100644 (file)
@@ -262,6 +262,8 @@ public class TapiContext {
             }
             // TODO -> Need to remove CEPs from NEPs. If not error from get Topology details output
             Node node = optNode.get();
+            LOG.debug("NEPs of node before creating map to be returned to the getTapiNode function = {}",
+                node.getOwnedNodeEdgePoint().size());
             Map<OwnedNodeEdgePointKey, OwnedNodeEdgePoint> onepMap = new HashMap<>();
             for (OwnedNodeEdgePoint onep: node.getOwnedNodeEdgePoint().values()) {
                 if (onep.augmentation(OwnedNodeEdgePoint1.class) == null) {
@@ -283,8 +285,11 @@ public class TapiContext {
                 if (onep.getMappedServiceInterfacePoint() != null) {
                     newOnepBuilder.setMappedServiceInterfacePoint(onep.getMappedServiceInterfacePoint());
                 }
-                onepMap.put(newOnepBuilder.key(), newOnepBuilder.build());
+                OwnedNodeEdgePoint newOnep = newOnepBuilder.build();
+                onepMap.put(newOnep.key(), newOnep);
             }
+            LOG.debug("NEPs of node after creating map to be returned to the getTapiNode function = {}",
+                onepMap.size());
             return new NodeBuilder(node)
                 .setOwnedNodeEdgePoint(onepMap)
                 .build();
@@ -399,6 +404,7 @@ public class TapiContext {
         try {
             this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID);
             this.networkTransactionService.commit().get();
+            LOG.info("Connectivity service deleted");
         } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to delete Connectivity service", e);
         }
diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImplTest.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImplTest.java
new file mode 100644 (file)
index 0000000..013abb3
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright © 2021 Nokia, 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.tapi.connectivity;
+
+import static org.mockito.ArgumentMatchers.any;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.HashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.transportpce.common.InstanceIdentifiers;
+import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.common.network.RequestProcessor;
+import org.opendaylight.transportpce.pce.service.PathComputationService;
+import org.opendaylight.transportpce.renderer.provisiondevice.RendererServiceOperations;
+import org.opendaylight.transportpce.servicehandler.impl.ServicehandlerImpl;
+import org.opendaylight.transportpce.servicehandler.listeners.NetworkModelListenerImpl;
+import org.opendaylight.transportpce.servicehandler.listeners.PceListenerImpl;
+import org.opendaylight.transportpce.servicehandler.listeners.RendererListenerImpl;
+import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
+import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperationsImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl;
+import org.opendaylight.transportpce.tapi.topology.TopologyUtils;
+import org.opendaylight.transportpce.tapi.utils.TapiConnectivityDataUtils;
+import org.opendaylight.transportpce.tapi.utils.TapiContext;
+import org.opendaylight.transportpce.tapi.utils.TapiInitialORMapping;
+import org.opendaylight.transportpce.tapi.utils.TapiTopologyDataUtils;
+import org.opendaylight.transportpce.test.AbstractTest;
+import org.opendaylight.transportpce.test.utils.TopologyDataUtils;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceOutput;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TapiConnectivityImplTest extends AbstractTest {
+
+    @Mock
+    private PathComputationService pathComputationService;
+
+    @Mock
+    private RendererServiceOperations rendererServiceOperations;
+
+    @Mock
+    private NotificationPublishService notificationPublishService;
+
+    @Mock
+    private TapiPceListenerImpl tapipceListenerImpl;
+
+    @Mock
+    private TapiRendererListenerImpl tapirendererListenerImpl;
+
+    @Mock
+    private TapiServiceHandlerListenerImpl tapiserviceHandlerListenerImpl;
+
+    @Mock
+    private PceListenerImpl pceListenerImpl;
+
+    @Mock
+    private RendererListenerImpl rendererListenerImpl;
+
+    @Mock
+    private NetworkModelListenerImpl networkModelListenerImpl;
+
+    private static final Logger LOG = LoggerFactory.getLogger(TapiConnectivityImplTest.class);
+    public static ServiceDataStoreOperations serviceDataStoreOperations;
+    public static TapiContext tapiContext;
+    public static TopologyUtils topologyUtils;
+    public static ConnectivityUtils connectivityUtils;
+    public static TapiInitialORMapping tapiInitialORMapping;
+    public static NetworkTransactionService networkTransactionService;
+    private ListeningExecutorService executorService;
+    private CountDownLatch endSignal;
+    private static final int NUM_THREADS = 5;
+    private boolean callbackRan;
+
+    @Before
+    public void setUp() throws InterruptedException, ExecutionException {
+        executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(NUM_THREADS));
+        endSignal = new CountDownLatch(1);
+        // Need to have datastore populated to enable the mapping from TAPI to OR
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OPENROADM_TOPOLOGY_FILE, InstanceIdentifiers.OVERLAY_NETWORK_II);
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OPENROADM_NETWORK_FILE, InstanceIdentifiers.UNDERLAY_NETWORK_II);
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OTN_TOPOLOGY_FILE, InstanceIdentifiers.OTN_NETWORK_II);
+        TopologyDataUtils.writePortmappingFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.PORTMAPPING_FILE);
+
+        callbackRan = false;
+        MockitoAnnotations.openMocks(this);
+
+        networkTransactionService = new NetworkTransactionImpl(
+            new RequestProcessor(getDataStoreContextUtil().getDataBroker()));
+        serviceDataStoreOperations = new ServiceDataStoreOperationsImpl(getDataStoreContextUtil().getDataBroker());
+        tapiContext = new TapiContext(networkTransactionService);
+        topologyUtils = new TopologyUtils(networkTransactionService, getDataStoreContextUtil().getDataBroker());
+        connectivityUtils = new ConnectivityUtils(serviceDataStoreOperations, new HashMap<>(), tapiContext);
+        tapiInitialORMapping = new TapiInitialORMapping(topologyUtils, connectivityUtils,
+            tapiContext, serviceDataStoreOperations);
+        tapiInitialORMapping.performTopoInitialMapping();
+        LOG.info("setup done");
+    }
+
+    @Test
+    public void createConnServiceShouldBeFailedWithEmptyInput() throws ExecutionException, InterruptedException {
+        OrgOpenroadmServiceService serviceHandler = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
+            rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
+            networkModelListenerImpl, serviceDataStoreOperations);
+
+        TapiConnectivityImpl tapiConnectivity = new TapiConnectivityImpl(serviceHandler, tapiContext, connectivityUtils,
+            tapipceListenerImpl, tapirendererListenerImpl, tapiserviceHandlerListenerImpl);
+
+        ListenableFuture<RpcResult<CreateConnectivityServiceOutput>> result =
+            tapiConnectivity.createConnectivityService(new CreateConnectivityServiceInputBuilder().build());
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                callbackRan = true;
+                endSignal.countDown();
+            }
+        }, executorService);
+
+        endSignal.await();
+
+        RpcResult<CreateConnectivityServiceOutput> rpcResult = result.get();
+        Assert.assertEquals(
+            RpcError.ErrorType.RPC, rpcResult.getErrors().get(0).getErrorType());
+    }
+
+    @Test
+    public void createConnServiceShouldBeSuccessfulWhenPerformPCESuccessful()
+            throws ExecutionException, InterruptedException {
+        OrgOpenroadmServiceService serviceHandler = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
+            rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
+            networkModelListenerImpl, serviceDataStoreOperations);
+
+        CreateConnectivityServiceInput input = TapiConnectivityDataUtils.buildConnServiceCreateInput();
+        Mockito.when(pathComputationService.pathComputationRequest(any())).thenReturn(Futures.immediateFuture(any()));
+
+        TapiConnectivityImpl tapiConnectivity = new TapiConnectivityImpl(serviceHandler, tapiContext, connectivityUtils,
+            tapipceListenerImpl, tapirendererListenerImpl, tapiserviceHandlerListenerImpl);
+        ListenableFuture<RpcResult<CreateConnectivityServiceOutput>> result =
+            tapiConnectivity.createConnectivityService(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                callbackRan = true;
+                endSignal.countDown();
+            }
+        }, executorService);
+
+        endSignal.await();
+
+        RpcResult<CreateConnectivityServiceOutput> rpcResult = result.get();
+        Assert.assertTrue(rpcResult.isSuccessful());
+    }
+
+    @Test
+    public void deleteConnServiceShouldBeFailedWithEmptyInput() throws ExecutionException, InterruptedException {
+        OrgOpenroadmServiceService serviceHandler = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
+            rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
+            networkModelListenerImpl, serviceDataStoreOperations);
+
+        TapiConnectivityImpl tapiConnectivity = new TapiConnectivityImpl(serviceHandler, tapiContext, connectivityUtils,
+            tapipceListenerImpl, tapirendererListenerImpl, tapiserviceHandlerListenerImpl);
+
+        ListenableFuture<RpcResult<DeleteConnectivityServiceOutput>> result =
+            tapiConnectivity.deleteConnectivityService(new DeleteConnectivityServiceInputBuilder().build());
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                callbackRan = true;
+                endSignal.countDown();
+            }
+        }, executorService);
+
+        endSignal.await();
+
+        RpcResult<DeleteConnectivityServiceOutput> rpcResult = result.get();
+        Assert.assertEquals(
+            RpcError.ErrorType.RPC, rpcResult.getErrors().get(0).getErrorType());
+    }
+
+    @Test
+    public void deleteConnServiceShouldBeFailedWithNonExistService() throws ExecutionException, InterruptedException {
+        DeleteConnectivityServiceInput input = TapiConnectivityDataUtils.buildConnServiceDeleteInput1();
+        OrgOpenroadmServiceService serviceHandler = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
+            rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
+            networkModelListenerImpl, serviceDataStoreOperations);
+
+        TapiConnectivityImpl tapiConnectivity = new TapiConnectivityImpl(serviceHandler, tapiContext, connectivityUtils,
+            tapipceListenerImpl, tapirendererListenerImpl, tapiserviceHandlerListenerImpl);
+        ListenableFuture<RpcResult<DeleteConnectivityServiceOutput>> result =
+            tapiConnectivity.deleteConnectivityService(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                callbackRan = true;
+                endSignal.countDown();
+            }
+        }, executorService);
+
+        endSignal.await();
+
+        RpcResult<DeleteConnectivityServiceOutput> rpcResult = result.get();
+        Assert.assertEquals(
+            RpcError.ErrorType.RPC, rpcResult.getErrors().get(0).getErrorType());
+    }
+
+    @Test
+    public void deleteConnServiceShouldBeSuccessForExistingService() throws ExecutionException, InterruptedException {
+        Mockito.when(rendererServiceOperations.serviceDelete(any(), any())).thenReturn(Futures.immediateFuture(any()));
+
+        OrgOpenroadmServiceService serviceHandler = new ServicehandlerImpl(getNewDataBroker(), pathComputationService,
+            rendererServiceOperations, notificationPublishService, pceListenerImpl, rendererListenerImpl,
+            networkModelListenerImpl, serviceDataStoreOperations);
+
+        TapiConnectivityImpl tapiConnectivity = new TapiConnectivityImpl(serviceHandler, tapiContext, connectivityUtils,
+            tapipceListenerImpl, tapirendererListenerImpl, tapiserviceHandlerListenerImpl);
+
+        ServiceCreateInput createInput = TapiConnectivityDataUtils.buildServiceCreateInput();
+        serviceDataStoreOperations.createService(createInput);
+        tapiContext.updateConnectivityContext(TapiConnectivityDataUtils.createConnService(), new HashMap<>());
+
+        DeleteConnectivityServiceInput input = TapiConnectivityDataUtils.buildConnServiceDeleteInput();
+        ListenableFuture<RpcResult<DeleteConnectivityServiceOutput>> result =
+            tapiConnectivity.deleteConnectivityService(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                callbackRan = true;
+                endSignal.countDown();
+            }
+        }, executorService);
+
+        endSignal.await();
+
+        RpcResult<DeleteConnectivityServiceOutput> rpcResult = result.get();
+        Assert.assertTrue(rpcResult.isSuccessful());
+    }
+}
diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/provider/TapiProviderTest.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/provider/TapiProviderTest.java
new file mode 100644 (file)
index 0000000..878c763
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2021 Nokia, 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.tapi.provider;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+import org.opendaylight.transportpce.common.network.NetworkTransactionImpl;
+import org.opendaylight.transportpce.common.network.NetworkTransactionService;
+import org.opendaylight.transportpce.common.network.RequestProcessor;
+import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
+import org.opendaylight.transportpce.tapi.impl.TapiProvider;
+import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl;
+import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl;
+import org.opendaylight.transportpce.tapi.topology.TapiNetconfTopologyListener;
+import org.opendaylight.transportpce.tapi.topology.TapiPortMappingListener;
+import org.opendaylight.transportpce.tapi.utils.TapiListener;
+import org.opendaylight.transportpce.test.AbstractTest;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.tapinetworkutils.rev210408.TransportpceTapinetworkutilsService;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.OrgOpenroadmServiceService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TapiCommonService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.TapiConnectivityService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.TapiTopologyService;
+
+public class TapiProviderTest extends AbstractTest {
+    public static NetworkTransactionService networkTransactionService;
+
+    @Mock
+    RpcProviderService rpcProviderRegistry;
+
+    @Mock
+    OrgOpenroadmServiceService serviceHandler;
+
+    @Mock
+    ServiceDataStoreOperations serviceDataStoreOperations;
+
+    @Mock
+    TapiListener tapiListener;
+
+    @Mock
+    TransportpceTapinetworkutilsService tapiNetworkUtils;
+
+    @Mock
+    TapiPortMappingListener tapiPortMappingListener;
+
+    @Mock
+    TapiNetconfTopologyListener topologyListener;
+
+    @Mock
+    TapiPceListenerImpl pceListenerImpl;
+
+    @Mock
+    TapiRendererListenerImpl rendererListenerImpl;
+
+    @Mock
+    TapiServiceHandlerListenerImpl serviceHandlerListenerImpl;
+
+    private AutoCloseable closeable;
+
+    @Before
+    public void openMocks() {
+        closeable = MockitoAnnotations.openMocks(this);
+    }
+
+    @BeforeClass
+    public static void setUp() {
+        networkTransactionService = new NetworkTransactionImpl(
+            new RequestProcessor(getDataBroker()));
+    }
+
+    @Test
+    public void testInitRegisterTapiToRpcRegistry() {
+        TapiProvider provider =  new TapiProvider(getDataBroker(), rpcProviderRegistry, serviceHandler,
+            serviceDataStoreOperations, tapiListener, networkTransactionService, topologyListener,
+            tapiPortMappingListener, tapiNetworkUtils, pceListenerImpl, rendererListenerImpl,
+            serviceHandlerListenerImpl, getNotificationService());
+
+        provider.init();
+
+        verify(rpcProviderRegistry, times(1))
+            .registerRpcImplementation(any(), any(TapiConnectivityService.class));
+        verify(rpcProviderRegistry, times(2))
+            .registerRpcImplementation(any(), any(TapiTopologyService.class));
+        verify(rpcProviderRegistry, times(2))
+            .registerRpcImplementation(any(), any(TapiCommonService.class));
+    }
+
+    @After
+    public void releaseMocks() throws Exception {
+        closeable.close();
+    }
+}
diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToFullTapiTopoTest.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/topology/ConvertORTopoToFullTapiTopoTest.java
new file mode 100644 (file)
index 0000000..6e5331e
--- /dev/null
@@ -0,0 +1,1637 @@
+/*
+ * Copyright © 2021 Nokia, 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.tapi.topology;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.either;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import com.google.common.util.concurrent.FluentFuture;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import org.eclipse.jdt.annotation.Nullable;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.transportpce.common.InstanceIdentifiers;
+import org.opendaylight.transportpce.tapi.utils.TapiTopologyDataUtils;
+import org.opendaylight.transportpce.test.AbstractTest;
+import org.opendaylight.transportpce.test.utils.TopologyDataUtils;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.TerminationPoint1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmLinkType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.network.types.rev200529.OpenroadmTpType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NodeId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.Node;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.network.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.LinkId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Network1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.TpId;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.LinkKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.node.TerminationPointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.TerminationState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE100GigE;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.dsr.rev181210.DIGITALSIGNALTYPE10GigELAN;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU2E;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.odu.rev181210.ODUTYPEODU4;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROMS;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.photonic.media.rev181210.PHOTONICLAYERQUALIFIEROTSi;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ForwardingRule;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RuleType;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.Rule;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConvertORTopoToFullTapiTopoTest extends AbstractTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ConvertORTopoToFullTapiTopoTest.class);
+
+    private static Node otnMuxA;
+    private static Node otnMuxC;
+    private static Node otnSwitch;
+    private static Node tpdr100G;
+    private static Node roadmA;
+    private static Node roadmC;
+    private static Network openroadmNet;
+    private static Map<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+        .networks.network.Link> otnLinks;
+    private static Map<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+        .networks.network.Link> ortopoLinks;
+    private static Uuid topologyUuid;
+    private static DataBroker dataBroker = getDataBroker();
+
+    @BeforeClass
+    public static void setUp() throws InterruptedException, ExecutionException {
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OPENROADM_TOPOLOGY_FILE, InstanceIdentifiers.OVERLAY_NETWORK_II);
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OPENROADM_NETWORK_FILE, InstanceIdentifiers.UNDERLAY_NETWORK_II);
+        TopologyDataUtils.writeTopologyFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.OTN_TOPOLOGY_FILE, InstanceIdentifiers.OTN_NETWORK_II);
+        TopologyDataUtils.writePortmappingFromFileToDatastore(getDataStoreContextUtil(),
+            TapiTopologyDataUtils.PORTMAPPING_FILE);
+
+        KeyedInstanceIdentifier<Node, NodeKey> muxAIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("otn-topology")))
+            .child(Node.class, new NodeKey(new NodeId("SPDR-SA1-XPDR1")));
+        FluentFuture<Optional<Node>> muxAFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, muxAIID);
+        otnMuxA = muxAFuture.get().get();
+        KeyedInstanceIdentifier<Node, NodeKey> muxCIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("otn-topology")))
+            .child(Node.class, new NodeKey(new NodeId("SPDR-SC1-XPDR1")));
+        FluentFuture<Optional<Node>> muxCFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, muxCIID);
+        otnMuxC = muxCFuture.get().get();
+        KeyedInstanceIdentifier<Node, NodeKey> switchIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("otn-topology")))
+            .child(Node.class, new NodeKey(new NodeId("SPDR-SA1-XPDR2")));
+        FluentFuture<Optional<Node>> switchFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, switchIID);
+        otnSwitch = switchFuture.get().get();
+        KeyedInstanceIdentifier<Node, NodeKey> roadmaIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("openroadm-network")))
+            .child(Node.class, new NodeKey(new NodeId("ROADM-A1")));
+        FluentFuture<Optional<Node>> roadmaFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, roadmaIID);
+        roadmA = roadmaFuture.get().get();
+        KeyedInstanceIdentifier<Node, NodeKey> roadmcIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("openroadm-network")))
+            .child(Node.class, new NodeKey(new NodeId("ROADM-C1")));
+        FluentFuture<Optional<Node>> roadmcFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, roadmcIID);
+        roadmC = roadmcFuture.get().get();
+
+        KeyedInstanceIdentifier<Node, NodeKey> tpdrIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("otn-topology")))
+            .child(Node.class, new NodeKey(new NodeId("XPDR-A1-XPDR1")));
+        FluentFuture<Optional<Node>> tpdrFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, tpdrIID);
+        tpdr100G = tpdrFuture.get().get();
+
+        InstanceIdentifier<Network1> linksIID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("otn-topology")))
+            .augmentation(Network1.class);
+        FluentFuture<Optional<Network1>> linksFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, linksIID);
+        otnLinks = linksFuture.get().get().getLink();
+
+        InstanceIdentifier<Network1> links1IID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("openroadm-topology")))
+            .augmentation(Network1.class);
+        FluentFuture<Optional<Network1>> links1Future = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, links1IID);
+        ortopoLinks = links1Future.get().get().getLink();
+
+        InstanceIdentifier<Network> ortopo1IID = InstanceIdentifier.create(Networks.class)
+            .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network
+                .class, new NetworkKey(new NetworkId("openroadm-topology")));
+        FluentFuture<Optional<Network>> ortopoFuture = dataBroker.newReadOnlyTransaction()
+            .read(LogicalDatastoreType.CONFIGURATION, ortopo1IID);
+        openroadmNet = ortopoFuture.get().get();
+
+        topologyUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.T0_FULL_MULTILAYER.getBytes(
+            Charset.forName("UTF-8"))).toString());
+        LOG.info("TEST SETUP READY");
+    }
+
+    @Test
+    public void convertNodeWhenNoStates() {
+        Node tpdr = changeTerminationPointState(tpdr100G, "XPDR1-NETWORK1", null, null);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : tpdr100G.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        tapiFactory.convertNode(tpdr, networkPortList);
+
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node dsrNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(dsrNodeUuid));
+        Uuid enetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        Uuid inetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enetworkNepUuid));
+        assertNull("Administrative State should not be present", enepN.getAdministrativeState());
+        assertNull("Operational State should not be present", enepN.getOperationalState());
+
+        OwnedNodeEdgePoint inepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inetworkNepUuid));
+        assertNull("Administrative State should not be present", inepN.getAdministrativeState());
+        assertNull("Operational State should not be present", inepN.getOperationalState());
+
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node otsiNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(otsiNodeUuid));
+        Uuid enepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enepUuid));
+        assertNull("Administrative State should not be present", enep.getAdministrativeState());
+        assertNull("Operational State should not be present", enep.getOperationalState());
+
+        Uuid inepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint inep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inepUuid));
+        assertNull("Administrative State should not be present", inep.getAdministrativeState());
+        assertNull("Operational State should not be present", inep.getOperationalState());
+
+        Uuid photnepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+PHOTONIC_MEDIA+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint photnep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(photnepUuid));
+        assertNull("Administrative State should not be present", photnep.getAdministrativeState());
+        assertNull("Operational State should not be present", photnep.getOperationalState());
+    }
+
+    @Test
+    public void convertNodeWhenBadStates1() {
+        Node tpdr = changeTerminationPointState(tpdr100G, "XPDR1-NETWORK1", AdminStates.OutOfService,
+            State.OutOfService);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : tpdr100G.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        tapiFactory.convertNode(tpdr, networkPortList);
+
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node dsrNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(dsrNodeUuid));
+        Uuid enetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        Uuid inetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enetworkNepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, enepN.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, enepN.getOperationalState());
+
+        OwnedNodeEdgePoint inepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inetworkNepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, inepN.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, inepN.getOperationalState());
+
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node otsiNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(otsiNodeUuid));
+        Uuid enepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, enep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, enep.getOperationalState());
+
+        Uuid inepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint inep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, inep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, inep.getOperationalState());
+
+        Uuid photnepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+PHOTONIC_MEDIA+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint photnep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(photnepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, photnep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, photnep.getOperationalState());
+    }
+
+    @Test
+    public void convertNodeWhenBadStates2() {
+        Node tpdr = changeTerminationPointState(tpdr100G, "XPDR1-NETWORK1", AdminStates.Maintenance,
+            State.Degraded);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : tpdr100G.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        tapiFactory.convertNode(tpdr, networkPortList);
+
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node dsrNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(dsrNodeUuid));
+        Uuid enetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        Uuid inetworkNepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enetworkNepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, enepN.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, enepN.getOperationalState());
+
+        OwnedNodeEdgePoint inepN = dsrNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inetworkNepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, inepN.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, inepN.getOperationalState());
+
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node otsiNode = tapiFactory
+            .getTapiNodes().get(new
+                org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey(otsiNodeUuid));
+        Uuid enepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint enep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(enepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, enep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, enep.getOperationalState());
+
+        Uuid inepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint inep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(inepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, inep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, inep.getOperationalState());
+
+        Uuid photnepUuid = new Uuid(
+            UUID.nameUUIDFromBytes(("XPDR-A1-XPDR1+PHOTONIC_MEDIA+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                .toString());
+        OwnedNodeEdgePoint photnep = otsiNode.nonnullOwnedNodeEdgePoint().get(new OwnedNodeEdgePointKey(photnepUuid));
+        assertEquals("Administrative State should be Locked",
+            AdministrativeState.LOCKED, photnep.getAdministrativeState());
+        assertEquals("Operational State should be Disabled",
+            OperationalState.DISABLED, photnep.getOperationalState());
+    }
+
+    @Test
+    public void convertOtnLinkWhenNoState() {
+        HashMap<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+            .networks.network.Link> otnLinksAlt = new HashMap<>(otnLinks);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
+            link = changeOtnLinkState(otnLinks.get(new LinkKey(
+                new LinkId("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"))), null, null);
+        otnLinksAlt.replace(link.key(), link);
+
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinksAlt);
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        assertNull("Administrative State should not be present", tapiLinks.get(0).getAdministrativeState());
+        assertEquals("Administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, tapiLinks.get(2).getAdministrativeState());
+        assertNull("Operational State should not be present", tapiLinks.get(0).getOperationalState());
+        assertEquals("Operational state should be ENABLED",
+            OperationalState.ENABLED, tapiLinks.get(2).getOperationalState());
+    }
+
+    @Test
+    public void convertOtnLinkWhenNoStateOnOppositeLink() {
+        HashMap<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+            .networks.network.Link> otnLinksAlt = new HashMap<>(otnLinks);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
+            link = changeOtnLinkState(otnLinks.get(new LinkKey(
+                new LinkId("ODTU4-SPDR-SC1-XPDR1-XPDR1-NETWORK1toSPDR-SA1-XPDR1-XPDR1-NETWORK1"))), null, null);
+        otnLinksAlt.replace(link.key(), link);
+
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinksAlt);
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        assertNull("Administrative State should not be present", tapiLinks.get(0).getAdministrativeState());
+        assertEquals("Administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, tapiLinks.get(2).getAdministrativeState());
+        assertNull("Operational State should not be present", tapiLinks.get(0).getOperationalState());
+        assertEquals("Operational state should be ENABLED",
+            OperationalState.ENABLED, tapiLinks.get(2).getOperationalState());
+    }
+
+    @Test
+    public void convertOtnLinkWhenBadState1() {
+        HashMap<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+            .networks.network.Link> otnLinksAlt = new HashMap<>(otnLinks);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
+            link = changeOtnLinkState(otnLinks.get(new LinkKey(
+                new LinkId("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"))),
+            AdminStates.OutOfService, State.OutOfService);
+        otnLinksAlt.replace(link.key(), link);
+
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinksAlt);
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("Administrative state should be LOCKED",
+            AdministrativeState.LOCKED, tapiLinks.get(0).getAdministrativeState());
+        assertEquals("Administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, tapiLinks.get(2).getAdministrativeState());
+        assertEquals("Operational state should be DISABLED",
+            OperationalState.DISABLED, tapiLinks.get(0).getOperationalState());
+        assertEquals("Operational state should be ENABLED",
+            OperationalState.ENABLED, tapiLinks.get(2).getOperationalState());
+    }
+
+    @Test
+    public void convertOtnLinkWhenBadState2() {
+        HashMap<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+            .networks.network.Link> otnLinksAlt = new HashMap<>(otnLinks);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
+            link = changeOtnLinkState(otnLinks.get(new LinkKey(
+                new LinkId("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"))),
+            AdminStates.Maintenance, State.Degraded);
+        otnLinksAlt.replace(link.key(), link);
+
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinksAlt);
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("Administrative state should be LOCKED",
+            AdministrativeState.LOCKED, tapiLinks.get(0).getAdministrativeState());
+        assertEquals("Administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, tapiLinks.get(2).getAdministrativeState());
+        assertEquals("Operational state should be DISABLED",
+            OperationalState.DISABLED, tapiLinks.get(0).getOperationalState());
+        assertEquals("Operational state should be ENABLED",
+            OperationalState.ENABLED, tapiLinks.get(2).getOperationalState());
+    }
+
+    @Test
+    public void convertOtnLinkWhenBadStateOnOppositeLink() {
+        HashMap<LinkKey, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226
+            .networks.network.Link> otnLinksAlt = new HashMap<>(otnLinks);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network.Link
+            link = changeOtnLinkState(otnLinks.get(new LinkKey(
+                new LinkId("ODTU4-SPDR-SC1-XPDR1-XPDR1-NETWORK1toSPDR-SA1-XPDR1-XPDR1-NETWORK1"))),
+            AdminStates.OutOfService, State.OutOfService);
+        otnLinksAlt.replace(link.key(), link);
+
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinksAlt);
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("Administrative state should be LOCKED",
+            AdministrativeState.LOCKED, tapiLinks.get(0).getAdministrativeState());
+        assertEquals("Administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, tapiLinks.get(2).getAdministrativeState());
+        assertEquals("Operational state should be DISABLED",
+            OperationalState.DISABLED, tapiLinks.get(0).getOperationalState());
+        assertEquals("Operational state should be ENABLED",
+            OperationalState.ENABLED, tapiLinks.get(2).getOperationalState());
+    }
+
+    @Test
+    public void convertNodeForTransponder100G() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : tpdr100G.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(tpdr100G, networkPortList);
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream()
+            .sorted((n1, n2) -> n1.getUuid().getValue().compareTo(n2.getUuid().getValue()))
+            .collect(Collectors.toList());
+
+        assertEquals("Node list size should be 2", 2, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be 2", 2, tapiFactory.getTapiLinks().size());
+
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkDsrNode(tapiNodes.get(1), dsrNodeUuid, "tpdr", "XPDR-A1-XPDR1");
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("XPDR-A1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkOtsiNode(tapiNodes.get(0), otsiNodeUuid, "tpdr", "XPDR-A1-XPDR1");
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        checkTransitionalLink(tapiLinks.get(1), dsrNodeUuid, otsiNodeUuid,
+            "XPDR-A1-XPDR1+iODU+XPDR1-NETWORK1", "XPDR-A1-XPDR1+iOTSi+XPDR1-NETWORK1", "XPDR-A1-XPDR1");
+    }
+
+    @Test
+    public void convertNodeForOtnMuxponder() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortList);
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream()
+            .sorted((n1, n2) -> n1.getUuid().getValue().compareTo(n2.getUuid().getValue()))
+            .collect(Collectors.toList());
+
+        assertEquals("Node list size should be 2", 2, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be 1", 1, tapiFactory.getTapiLinks().size());
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkDsrNode(tapiNodes.get(0), dsrNodeUuid, "mux", "SPDR-SA1-XPDR1");
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkOtsiNode(tapiNodes.get(1), otsiNodeUuid, "mux", "SPDR-SA1-XPDR1");
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        checkTransitionalLink(tapiLinks.get(0), dsrNodeUuid, otsiNodeUuid,
+            "SPDR-SA1-XPDR1+iODU+XPDR1-NETWORK1", "SPDR-SA1-XPDR1+iOTSi+XPDR1-NETWORK1", "SPDR-SA1-XPDR1");
+    }
+
+    @Test
+    public void convertNodeForOtnSwitch() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortList = new ArrayList<>();
+        for (TerminationPoint tp : otnSwitch.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortList.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnSwitch, networkPortList);
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream()
+            .sorted((n1, n2) -> n1.getUuid().getValue().compareTo(n2.getUuid().getValue()))
+            .collect(Collectors.toList());
+
+        assertEquals("Node list size should be 2", 2, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be 4", 4, tapiFactory.getTapiLinks().size());
+
+        Uuid dsrNodeUuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR2+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkDsrNode(tapiNodes.get(0), dsrNodeUuid, "switch", "SPDR-SA1-XPDR2");
+        Uuid otsiNodeUuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR2+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        checkOtsiNode(tapiNodes.get(1), otsiNodeUuid, "switch", "SPDR-SA1-XPDR2");
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> tapiLinks
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        checkTransitionalLink(tapiLinks.get(1), dsrNodeUuid, otsiNodeUuid,
+            "SPDR-SA1-XPDR2+iODU+XPDR2-NETWORK4", "SPDR-SA1-XPDR2+iOTSi+XPDR2-NETWORK4", "SPDR-SA1-XPDR2");
+    }
+
+    @Test
+    public void convertOtnLink() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        List<String> networkPortListC = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxC.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListC.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxC, networkPortListC);
+        tapiFactory.convertLinks(otnLinks);
+        assertEquals("Link list size should be 4", 4, tapiFactory.getTapiLinks().size());
+
+        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid node3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid node4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+eODU+XPDR1-NETWORK1"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid tp2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+eODU+XPDR1-NETWORK1"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid tp3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+iOTSi+XPDR1-NETWORK1"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid tp4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+iOTSi+XPDR1-NETWORK1"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid link1Uuid =
+            new Uuid(UUID.nameUUIDFromBytes("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
+                .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid link2Uuid =
+            new Uuid(UUID.nameUUIDFromBytes("OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
+                .getBytes(Charset.forName("UTF-8"))).toString());
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> links
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        checkOtnLink(links.get(0), node1Uuid, node2Uuid, tp1Uuid, tp2Uuid, link1Uuid,
+            "ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1");
+        checkOtnLink(links.get(3), node3Uuid, node4Uuid, tp3Uuid, tp4Uuid, link2Uuid,
+            "OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1");
+    }
+
+    @Test
+    public void convertNodeForRoadmWhenNoOtnMuxAttached() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        tapiFactory.convertRoadmNode(roadmA, openroadmNet);
+
+        assertEquals("Node list size should be 1", 1, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be empty", 0, tapiFactory.getTapiLinks().size());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream().collect(Collectors.toList());
+        Uuid roadmNodeUuid = new Uuid(UUID.nameUUIDFromBytes((roadmA.getNodeId().getValue() + "+PHOTONIC_MEDIA")
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        checkOtsiNode(tapiNodes.get(0), roadmNodeUuid, "roadm", "ROADM-A1");
+    }
+
+    @Test
+    public void convertNodeForRoadmWhenRoadmNeighborAttached() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        tapiFactory.convertRoadmNode(roadmA, openroadmNet);
+        tapiFactory.convertRoadmNode(roadmC, openroadmNet);
+
+        List<Link> rdmTordmLinkList = ortopoLinks.values().stream()
+            .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.ROADMTOROADM))
+            .collect(Collectors.toList());
+        tapiFactory.convertRdmToRdmLinks(rdmTordmLinkList);
+
+        assertEquals("Node list size should be 2", 2, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be 1", 1, tapiFactory.getTapiLinks().size());
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream().collect(Collectors.toList());
+        Uuid roadmaNodeUuid = new Uuid(UUID.nameUUIDFromBytes((roadmA.getNodeId().getValue() + "+PHOTONIC_MEDIA")
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        checkOtsiNode(tapiNodes.get(1), roadmaNodeUuid, "roadm", "ROADM-A1");
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> links
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("ROADM-A1+PHOTONIC_MEDIA".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("ROADM-C1+PHOTONIC_MEDIA".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes("ROADM-A1+PHOTONIC_MEDIA+DEG2-TTP-TXRX"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid tp2Uuid = new Uuid(UUID.nameUUIDFromBytes(("ROADM-C1+PHOTONIC_MEDIA+DEG1-TTP-TXRX")
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid linkUuid =
+            new Uuid(UUID.nameUUIDFromBytes("ROADM-C1-DEG1-DEG1-TTP-TXRXtoROADM-A1-DEG2-DEG2-TTP-TXRX"
+                .getBytes(Charset.forName("UTF-8"))).toString());
+        checkOmsLink(links.get(0), node1Uuid, node2Uuid, tp1Uuid, tp2Uuid, linkUuid,
+            "ROADM-C1-DEG1-DEG1-TTP-TXRXtoROADM-A1-DEG2-DEG2-TTP-TXRX");
+    }
+
+    @Test
+    public void convertNodeForRoadmWhenOtnMuxAttached() {
+        ConvertORTopoToTapiFullTopo tapiFactory = new ConvertORTopoToTapiFullTopo(topologyUuid);
+        List<String> networkPortListA = new ArrayList<>();
+        for (TerminationPoint tp : otnMuxA.augmentation(Node1.class).getTerminationPoint().values()) {
+            if (tp.augmentation(TerminationPoint1.class).getTpType().equals(OpenroadmTpType.XPONDERNETWORK)) {
+                networkPortListA.add(tp.getTpId().getValue());
+            }
+        }
+        tapiFactory.convertNode(otnMuxA, networkPortListA);
+        tapiFactory.convertRoadmNode(roadmA, openroadmNet);
+        List<Link> xponderOutLinkList = ortopoLinks.values().stream()
+            .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDEROUTPUT))
+            .filter(lk1 -> ((lk1.getSource().getSourceNode().equals(otnMuxA.getNodeId())
+                    || lk1.getSource().getSourceNode().getValue().contains(roadmA.getNodeId().getValue()))
+                && (lk1.getDestination().getDestNode().equals(otnMuxA.getNodeId())
+                    || lk1.getDestination().getDestNode().getValue().contains(roadmA.getNodeId().getValue()))))
+            .collect(Collectors.toList());
+        List<Link> xponderInLinkList = ortopoLinks.values().stream()
+            .filter(lk -> lk.augmentation(Link1.class).getLinkType().equals(OpenroadmLinkType.XPONDERINPUT))
+            .filter(lk1 -> ((lk1.getSource().getSourceNode().equals(otnMuxA.getNodeId())
+                    || lk1.getSource().getSourceNode().getValue().contains(roadmA.getNodeId().getValue()))
+                && (lk1.getDestination().getDestNode().equals(otnMuxA.getNodeId())
+                    || lk1.getDestination().getDestNode().getValue().contains(roadmA.getNodeId().getValue()))))
+            .collect(Collectors.toList());
+        xponderInLinkList.addAll(xponderOutLinkList);
+        tapiFactory.convertXpdrToRdmLinks(xponderInLinkList);
+        assertEquals("Node list size should be 3", 3, tapiFactory.getTapiNodes().size());
+        assertEquals("Link list size should be 2", 2, tapiFactory.getTapiLinks().size());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node> tapiNodes
+            = tapiFactory.getTapiNodes().values().stream()
+            .sorted((n1, n2) -> n1.getUuid().getValue().compareTo(n2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        Uuid roadmNodeUuid = new Uuid(UUID.nameUUIDFromBytes((roadmA.getNodeId().getValue() + "+PHOTONIC_MEDIA")
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        checkOtsiNode(tapiNodes.get(1), roadmNodeUuid, "roadm", "ROADM-A1");
+
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link> links
+            = tapiFactory.getTapiLinks().values().stream()
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("ROADM-A1+PHOTONIC_MEDIA".getBytes(Charset.forName("UTF-8")))
+            .toString());
+        Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+PHOTONIC_MEDIA+XPDR1-NETWORK1"
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid tp2Uuid = new Uuid(UUID.nameUUIDFromBytes(("ROADM-A1+PHOTONIC_MEDIA+SRG1-PP2-TXRX")
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid linkUuid =
+            new Uuid(UUID.nameUUIDFromBytes("ROADM-A1-SRG1-SRG1-PP2-TXRXtoSPDR-SA1-XPDR1-XPDR1-NETWORK1"
+                .getBytes(Charset.forName("UTF-8"))).toString());
+        checkXpdrRdmLink(links.get(0), node1Uuid, node2Uuid, tp1Uuid, tp2Uuid, linkUuid,
+            "ROADM-A1-SRG1-SRG1-PP2-TXRXtoSPDR-SA1-XPDR1-XPDR1-NETWORK1");
+    }
+
+    private void checkDsrNode(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node,
+                              Uuid nodeUuid, String dsrNodeType, String nodeId) {
+        assertEquals("incorrect node uuid", nodeUuid, node.getUuid());
+        assertEquals("incorrect node name", nodeId + "+DSR", node.getName().get(
+            new NameKey("dsr/odu node name")).getValue());
+        assertEquals("administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, node.getAdministrativeState());
+        assertEquals("life-cycle state should be INSTALLED", LifecycleState.INSTALLED, node.getLifecycleState());
+        assertEquals("operational state should be ENABLED", OperationalState.ENABLED, node.getOperationalState());
+        assertEquals("value-name should be 'dsr/odu node name'",
+            "dsr/odu node name", node.nonnullName().values().stream().findFirst().get().getValueName());
+        assertEquals("dsr node should manage 2 protocol layers : dsr and odu",
+            2, node.getLayerProtocolName().size());
+        assertThat("dsr node should manage 2 protocol layers : dsr and odu",
+            node.getLayerProtocolName(), hasItems(LayerProtocolName.DSR, LayerProtocolName.ODU));
+        List<OwnedNodeEdgePoint> inepsN = node.nonnullOwnedNodeEdgePoint().values().stream()
+            .filter(n -> n.getName().containsKey(new NameKey("iNodeEdgePoint_N")))
+            .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        List<OwnedNodeEdgePoint> enepsN = node.nonnullOwnedNodeEdgePoint().values().stream()
+            .filter(n -> n.getName().containsKey(new NameKey("eNodeEdgePoint_N")))
+            .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        List<OwnedNodeEdgePoint> nepsC;
+        switch (dsrNodeType) {
+            case "switch":
+                nepsC = node.nonnullOwnedNodeEdgePoint().values().stream()
+                    .filter(n -> n.getName().containsKey(new NameKey("NodeEdgePoint_C")))
+                    .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                assertEquals("Switch-DSR node should have 4 eNEPs network", 4, enepsN.size());
+                assertEquals("Switch-DSR node should have 4 iNEPs network", 4, inepsN.size());
+                assertEquals("Switch-DSR node should have 4 NEPs client", 4, nepsC.size());
+                OwnedNodeEdgePoint nep1 = nepsC.get(2);
+                Uuid client4NepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR2-CLIENT4").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepClient100GSwitch(nep1, client4NepUuid, nodeId + "+DSR+XPDR2-CLIENT4", "NodeEdgePoint_C");
+                OwnedNodeEdgePoint enep2 = enepsN.get(3);
+                OwnedNodeEdgePoint inep2 = inepsN.get(3);
+                Uuid enetworkNepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eODU+XPDR2-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                Uuid inetworkNepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iODU+XPDR2-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepNetworkODU4(enep2, enetworkNepUuid, nodeId + "+eODU+XPDR2-NETWORK1", "eNodeEdgePoint_N", true);
+                checkNepNetworkODU4(inep2, inetworkNepUuid, nodeId + "+iODU+XPDR2-NETWORK1", "iNodeEdgePoint_N", false);
+                List<NodeRuleGroup> nrgList = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForSwitchDSR(nrgList, client4NepUuid, enetworkNepUuid, nodeUuid);
+                break;
+            case "mux":
+                nepsC = node.nonnullOwnedNodeEdgePoint().values().stream()
+                    .filter(n -> n.getName().containsKey(new NameKey("NodeEdgePoint_C")))
+                    .sorted((nep3, nep4) -> nep3.getUuid().getValue().compareTo(nep4.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                assertEquals("Mux-DSR node should have 1 eNEP network", 1, enepsN.size());
+                assertEquals("Mux-DSR node should have 1 iNEP network", 1, inepsN.size());
+                assertEquals("Mux-DSR node should have 4 NEPs client", 4, nepsC.size());
+                OwnedNodeEdgePoint nep3 = nepsC.get(2);
+                Uuid client3NepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-CLIENT3").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepClient10G(nep3, client3NepUuid, nodeId + "+DSR+XPDR1-CLIENT3", "NodeEdgePoint_C");
+
+                OwnedNodeEdgePoint enep4 = enepsN.get(0);
+                OwnedNodeEdgePoint inep4 = inepsN.get(0);
+                Uuid enetworkNepUuid2 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                Uuid inetworkNepUuid2 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepNetworkODU4(enep4, enetworkNepUuid2, nodeId + "+eODU+XPDR1-NETWORK1", "eNodeEdgePoint_N", true);
+                checkNepNetworkODU4(inep4, inetworkNepUuid2, nodeId + "+iODU+XPDR1-NETWORK1", "iNodeEdgePoint_N",
+                    false);
+                List<NodeRuleGroup> nrgList2 = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForMuxDSR(nrgList2, client3NepUuid, enetworkNepUuid2, nodeUuid);
+                break;
+            case "tpdr":
+                nepsC = node.nonnullOwnedNodeEdgePoint().values().stream()
+                    .filter(n -> n.getName().containsKey(new NameKey("100G-tpdr")))
+                    .sorted((nep5, nep6) -> nep5.getUuid().getValue().compareTo(nep6.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                assertEquals("Tpdr-DSR node should have 2 eNEPs network", 2, enepsN.size());
+                assertEquals("Tpdr-DSR node should have 2 iNEPs network", 2, inepsN.size());
+                assertEquals("Tpdr-DSR node should have 2 NEPs client", 2, nepsC.size());
+                OwnedNodeEdgePoint nep5 = nepsC.get(0);
+                Uuid client1NepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-CLIENT1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepClient100GTpdr(nep5, client1NepUuid, nodeId + "+DSR+XPDR1-CLIENT1", "100G-tpdr");
+
+                OwnedNodeEdgePoint enep6 = enepsN.get(0);
+                OwnedNodeEdgePoint inep6 = inepsN.get(1);
+                Uuid enetworkNepUuid3 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                Uuid inetworkNepUuid3 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iODU+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepNetworkODU4(enep6, enetworkNepUuid3, nodeId + "+eODU+XPDR1-NETWORK1", "eNodeEdgePoint_N", true);
+                checkNepNetworkODU4(inep6, inetworkNepUuid3, nodeId + "+iODU+XPDR1-NETWORK1", "iNodeEdgePoint_N",
+                    false);
+                List<NodeRuleGroup> nrgList3 = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForTpdrDSR(nrgList3, client1NepUuid, enetworkNepUuid3, nodeUuid);
+                break;
+            default:
+                fail();
+                break;
+        }
+    }
+
+    private void checkOtsiNode(
+            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node,
+            Uuid nodeUuid, String otsiNodeType, String nodeId) {
+        assertEquals("incorrect node uuid", nodeUuid, node.getUuid());
+        List<OwnedNodeEdgePoint> nepsI = null;
+        List<OwnedNodeEdgePoint> nepsE = null;
+        List<OwnedNodeEdgePoint> nepsP = null;
+        List<OwnedNodeEdgePoint> nepsMc = null;
+        List<OwnedNodeEdgePoint> nepsOtsimc = null;
+        List<OwnedNodeEdgePoint> nepsPhot = null;
+        if (!otsiNodeType.equals("roadm")) {
+            assertEquals("incorrect node name", nodeId + "+OTSi", node.getName().get(
+                new NameKey("otsi node name")).getValue());
+            assertEquals("value-name should be 'dsr/odu node name'",
+                "otsi node name", node.nonnullName().values().stream().findFirst().get().getValueName());
+            nepsI = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("iNodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+            nepsE = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("eNodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+            nepsP = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("PhotMedNodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+        } else {
+            assertEquals("incorrect node name", nodeId + "+PHOTONIC_MEDIA", node.getName().get(
+                new NameKey("roadm node name")).getValue());
+            assertEquals("value-name should be 'dsr/odu node name'",
+                "roadm node name", node.nonnullName().values().stream().findFirst().get().getValueName());
+            nepsMc = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("MEDIA_CHANNELNodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+            nepsOtsimc = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("OTSi_MEDIA_CHANNELNodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+            nepsPhot = node.nonnullOwnedNodeEdgePoint().values().stream()
+                .filter(n -> n.getName().containsKey(new NameKey("PHOTONIC_MEDIANodeEdgePoint")))
+                .sorted((nep1, nep2) -> nep1.getUuid().getValue().compareTo(nep2.getUuid().getValue()))
+                .collect(Collectors.toList());
+        }
+        assertEquals("administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, node.getAdministrativeState());
+        assertEquals("life-cycle state should be INSTALLED", LifecycleState.INSTALLED, node.getLifecycleState());
+        assertEquals("operational state should be ENABLED", OperationalState.ENABLED, node.getOperationalState());
+        assertEquals("otsi node should manage a single protocol layer : PHOTONIC_MEDIA",
+            1, node.getLayerProtocolName().size());
+        assertEquals("otsi node should manage a single protocol layer : PHOTONIC_MEDIA",
+            LayerProtocolName.PHOTONICMEDIA, node.getLayerProtocolName().get(0));
+
+        switch (otsiNodeType) {
+            case "switch":
+                assertEquals("Switch-OTSi node should have 4 eNEPs", 4, nepsE.size());
+                assertEquals("Switch-OTSi node should have 4 iNEPs", 4, nepsI.size());
+                assertEquals("Switch-OTSi node should have 4 photNEPs", 4, nepsP.size());
+                OwnedNodeEdgePoint nep1 = nepsI.get(1);
+                Uuid inepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR2-NETWORK2").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep1, inepUuid, nodeId + "+iOTSi+XPDR2-NETWORK2", "iNodeEdgePoint", true);
+                OwnedNodeEdgePoint nep2 = nepsE.get(0);
+                Uuid enepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR2-NETWORK2").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep2, enepUuid, nodeId + "+eOTSi+XPDR2-NETWORK2", "eNodeEdgePoint", false);
+                OwnedNodeEdgePoint photNep = nepsP.get(1);
+                Uuid pnepUuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+PHOTONIC_MEDIA+XPDR2-NETWORK2")
+                        .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiNode(photNep, pnepUuid, nodeId + "+PHOTONIC_MEDIA+XPDR2-NETWORK2", "PhotMedNodeEdgePoint",
+                    false);
+                List<NodeRuleGroup> nrgList = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForSwitchOTSi(nrgList, enepUuid, inepUuid, nodeUuid);
+                break;
+            case "mux":
+                assertEquals("Mux-OTSi node should have 1 eNEP", 1, nepsE.size());
+                assertEquals("Mux-OTSi node should have 1 iNEPs", 1, nepsI.size());
+                assertEquals("Mux-OTSi node should have 1 photNEPs", 1, nepsP.size());
+                OwnedNodeEdgePoint nep3 = nepsE.get(0);
+                Uuid enepUuid2 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep3, enepUuid2, nodeId + "+eOTSi+XPDR1-NETWORK1", "eNodeEdgePoint", false);
+                OwnedNodeEdgePoint nep4 = nepsI.get(0);
+                Uuid inepUuid2 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep4, inepUuid2, nodeId + "+iOTSi+XPDR1-NETWORK1", "iNodeEdgePoint", true);
+                OwnedNodeEdgePoint photNep1 = nepsP.get(0);
+                Uuid pnep1Uuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+PHOTONIC_MEDIA+XPDR1-NETWORK1")
+                        .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiNode(photNep1, pnep1Uuid, nodeId + "+PHOTONIC_MEDIA+XPDR1-NETWORK1", "PhotMedNodeEdgePoint",
+                    false);
+                List<NodeRuleGroup> nrgList2 = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForMuxOTSi(nrgList2, enepUuid2, inepUuid2, nodeUuid);
+                break;
+            case "tpdr":
+                assertEquals("Tpdr-OTSi node should have 2 eNEPs", 2, nepsE.size());
+                assertEquals("Tpdr-OTSi node should have 2 iNEPs", 2, nepsI.size());
+                assertEquals("Tpdr-OTSi node should have 2 photNEPs", 2, nepsP.size());
+                OwnedNodeEdgePoint nep5 = nepsE.get(0);
+                Uuid enepUuid3 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep5, enepUuid3, nodeId + "+eOTSi+XPDR1-NETWORK1", "eNodeEdgePoint", false);
+                OwnedNodeEdgePoint nep6 = nepsI.get(0);
+                Uuid inepUuid3 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiNode(nep6, inepUuid3, nodeId + "+iOTSi+XPDR1-NETWORK1", "iNodeEdgePoint", true);
+                OwnedNodeEdgePoint photNep2 = nepsP.get(0);
+                Uuid pnep2Uuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+PHOTONIC_MEDIA+XPDR1-NETWORK1")
+                        .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiNode(photNep2, pnep2Uuid, nodeId + "+PHOTONIC_MEDIA+XPDR1-NETWORK1", "PhotMedNodeEdgePoint",
+                    false);
+                List<NodeRuleGroup> nrgList3 = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForTpdrOTSi(nrgList3, enepUuid3, inepUuid3, nodeUuid);
+                break;
+            case "roadm":
+                assertEquals("Roadm node should have 10 MC NEPs", 10, nepsMc.size());
+                assertEquals("Roadm node should have 10 OTSiMC NEPs", 10, nepsOtsimc.size());
+                assertEquals("Roadm node should have 10 PHOT_MEDIA NEPs", 10, nepsPhot.size());
+                // For Degree node
+                OwnedNodeEdgePoint nep7 = nepsMc.get(6);
+                Uuid mcnepUuid3 = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+MEDIA_CHANNEL+DEG1-TTP-TXRX").getBytes(Charset.forName("UTF-8")))
+                        .toString());
+                checkNepOtsiRdmNode(nep7, mcnepUuid3, nodeId + "+MEDIA_CHANNEL+DEG1-TTP-TXRX",
+                    "MEDIA_CHANNELNodeEdgePoint", false);
+                OwnedNodeEdgePoint nep8 = nepsOtsimc.get(0);
+                Uuid otmcnepUuid3 = new Uuid(UUID.nameUUIDFromBytes((nodeId + "+OTSi_MEDIA_CHANNEL+DEG1-TTP-TXRX")
+                    .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiRdmNode(nep8, otmcnepUuid3, nodeId + "+OTSi_MEDIA_CHANNEL+DEG1-TTP-TXRX",
+                    "OTSi_MEDIA_CHANNELNodeEdgePoint", false);
+                OwnedNodeEdgePoint photNep3 = nepsPhot.get(3);
+                Uuid pnep3Uuid = new Uuid(
+                    UUID.nameUUIDFromBytes((nodeId + "+PHOTONIC_MEDIA+DEG1-TTP-TXRX")
+                        .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiRdmNode(photNep3, pnep3Uuid, nodeId + "+PHOTONIC_MEDIA+DEG1-TTP-TXRX",
+                    "PHOTONIC_MEDIANodeEdgePoint", false);
+                // For srg node
+                OwnedNodeEdgePoint nep9 = nepsMc.get(0);
+                Uuid mcnepUuid4 = new Uuid(UUID.nameUUIDFromBytes((nodeId + "+MEDIA_CHANNEL+SRG1-PP1-TXRX")
+                    .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiRdmNode(nep9, mcnepUuid4, nodeId + "+MEDIA_CHANNEL+SRG1-PP1-TXRX",
+                    "MEDIA_CHANNELNodeEdgePoint", true);
+                OwnedNodeEdgePoint nep10 = nepsOtsimc.get(9);
+                Uuid otmcnepUuid4 = new Uuid(UUID.nameUUIDFromBytes((nodeId + "+OTSi_MEDIA_CHANNEL+SRG1-PP1-TXRX")
+                    .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiRdmNode(nep10, otmcnepUuid4, nodeId + "+OTSi_MEDIA_CHANNEL+SRG1-PP1-TXRX",
+                    "OTSi_MEDIA_CHANNELNodeEdgePoint", false);
+                OwnedNodeEdgePoint photNep4 = nepsPhot.get(4);
+                Uuid pnep4Uuid = new Uuid(UUID.nameUUIDFromBytes((nodeId + "+PHOTONIC_MEDIA+SRG1-PP1-TXRX")
+                    .getBytes(Charset.forName("UTF-8"))).toString());
+                checkNepOtsiRdmNode(photNep4, pnep4Uuid, nodeId + "+PHOTONIC_MEDIA+SRG1-PP1-TXRX",
+                    "PHOTONIC_MEDIANodeEdgePoint", false);
+                List<NodeRuleGroup> nrgList4 = node.nonnullNodeRuleGroup().values().stream()
+                    .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
+                    .collect(Collectors.toList());
+                checkNodeRuleGroupForRdm(nrgList4, 30);
+                break;
+            default:
+                fail();
+                break;
+        }
+    }
+
+    private void checkNepClient10G(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        Name name = nameList.get(0);
+        assertEquals("value of client nep should be '" + portName + "'",
+            portName, name.getValue());
+        assertEquals("value-name of client nep for '" + portName + "' should be '" + nepName + "'",
+            nepName, name.getValueName());
+        assertEquals("Client nep should support 3 kind of cep",
+            3, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("client nep should support 3 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItems(ODUTYPEODU2.class, ODUTYPEODU2E.class, DIGITALSIGNALTYPE10GigELAN.class));
+        assertEquals("client nep should be of DSR protocol type", LayerProtocolName.DSR, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, false);
+    }
+
+    private void checkNepNetworkODU4(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+                                     boolean withSip) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        Name name = nameList.get(0);
+        assertEquals("value of network nep should be '" + portName + "'",
+            portName, name.getValue());
+        assertEquals("value-name of network nep for '" + portName + "' should be '" + nepName + "'",
+            nepName, name.getValueName());
+        assertEquals("Network nep should support 1 kind of cep",
+            1, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("network nep should support 1 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItem(ODUTYPEODU4.class));
+        assertEquals("network nep should be of ODU protocol type", LayerProtocolName.ODU, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, withSip);
+    }
+
+    private void checkNodeRuleGroupForTpdrDSR(List<NodeRuleGroup> nrgList, Uuid clientNepUuid, Uuid networkNepUuid,
+                                              Uuid nodeUuid) {
+        assertEquals("transponder DSR should contain 2 node rule group", 2, nrgList.size());
+        for (NodeRuleGroup nodeRuleGroup : nrgList) {
+            assertEquals("each node-rule-group should contain 2 NEP for transponder DSR",
+                2, nodeRuleGroup.getNodeEdgePoint().size());
+        }
+        List<NodeEdgePoint> nodeEdgePointList = new ArrayList<>(nrgList.get(0).nonnullNodeEdgePoint().values());
+        assertThat("node-rule-group nb 1 should be between nep-client1 and nep-network1",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(networkNepUuid.getValue())).or(containsString(clientNepUuid.getValue())));
+        assertThat("node-rule-group nb 1 should be between nep-client1 and nep-network1",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(networkNepUuid.getValue())).or(containsString(clientNepUuid.getValue())));
+        assertEquals("node-rule-group nb 1 should be between nep-client1 and nep-network1 of the same node",
+            nodeEdgePointList.get(0).getNodeUuid(), nodeUuid);
+        assertEquals("node-rule-group nb 1 should be between nep-client1 and nep-network1 of the same node",
+            nodeEdgePointList.get(1).getNodeUuid(), nodeUuid);
+        List<Rule> rule = new ArrayList<>(nrgList.get(1).nonnullRule().values());
+        assertEquals("node-rule-group nb 1 should contain a single rule", 1, rule.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", rule.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, rule.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, rule.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForMuxDSR(List<NodeRuleGroup> nrgList, Uuid clientNepUuid, Uuid networkNepUuid,
+                                             Uuid nodeUuid) {
+        assertEquals("muxponder DSR should contain 4 node rule group", 4, nrgList.size());
+        for (NodeRuleGroup nodeRuleGroup : nrgList) {
+            assertEquals("each node-rule-group should contain 2 NEP for muxponder DSR",
+                2, nodeRuleGroup.getNodeEdgePoint().size());
+        }
+        List<NodeEdgePoint> nodeEdgePointList = new ArrayList<>(nrgList.get(0).nonnullNodeEdgePoint().values());
+        assertThat("node-rule-group nb 2 should be between nep-client4 and nep-network1",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(networkNepUuid.getValue())).or(containsString(clientNepUuid.getValue())));
+        assertThat("node-rule-group nb 2 should be between nep-client4 and nep-network1",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(networkNepUuid.getValue())).or(containsString(clientNepUuid.getValue())));
+        assertEquals("node-rule-group nb 2 should be between nep-client4 and nep-network1 of the same node",
+            nodeEdgePointList.get(0).getNodeUuid(), nodeUuid);
+        assertEquals("node-rule-group nb 2 should be between nep-client4 and nep-network1 of the same node",
+            nodeEdgePointList.get(1).getNodeUuid(), nodeUuid);
+        List<Rule> rule = new ArrayList<>(nrgList.get(1).nonnullRule().values());
+        assertEquals("node-rule-group nb 2 should contain a single rule", 1, rule.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", rule.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, rule.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, rule.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForSwitchDSR(List<NodeRuleGroup> nrgList, Uuid clientNepUuid, Uuid networkNepUuid,
+                                                Uuid nodeUuid) {
+        assertEquals("Switch-DSR should contain a single node rule group", 1, nrgList.size());
+        assertEquals("Switch-DSR node-rule-group should contain 8 NEP", 8, nrgList.get(0).getNodeEdgePoint().size());
+        List<NodeEdgePoint> nrg = nrgList.get(0).nonnullNodeEdgePoint().values().stream()
+            .sorted((nrg1, nrg2) -> nrg1.getNodeEdgePointUuid().getValue()
+                .compareTo(nrg2.getNodeEdgePointUuid().getValue()))
+            .collect(Collectors.toList());
+        assertEquals("in the sorted node-rule-group, nep number 7 should be XPDR2-NETWORK1",
+            networkNepUuid, nrg.get(7).getNodeEdgePointUuid());
+        assertEquals("in the sorted node-rule-group, nep number 4 should be XPDR2-CLIENT4",
+            clientNepUuid, nrg.get(4).getNodeEdgePointUuid());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nrg.get(4).getNodeUuid());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nrg.get(3).getNodeUuid());
+        @Nullable
+        List<Rule> ruleList = new ArrayList<>(nrgList.get(0).nonnullRule().values());
+        assertEquals("node-rule-group should contain a single rule", 1, ruleList.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", ruleList.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, ruleList.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, ruleList.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForRdm(List<NodeRuleGroup> nrgList, int nbNeps) {
+        assertEquals("RDM infra node - OTSi should contain a single node rule groups", 1, nrgList.size());
+        if (nbNeps > 0) {
+            List<NodeEdgePoint> nodeEdgePointList = new ArrayList<>(nrgList.get(0).getNodeEdgePoint().values());
+            assertEquals("RDM infra node -rule-group should contain " + nbNeps + " NEP",
+                nbNeps, nodeEdgePointList.size());
+        } else {
+            assertNull("RDM infra node -rule-group should contain no NEP", nrgList.get(0).getNodeEdgePoint());
+        }
+        List<Rule> ruleList = new ArrayList<>(nrgList.get(0).nonnullRule().values());
+        assertEquals("node-rule-group should contain a single rule", 1, ruleList.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", ruleList.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, ruleList.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, ruleList.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForTpdrOTSi(List<NodeRuleGroup> nrgList, Uuid enepUuid, Uuid inepUuid,
+                                               Uuid nodeUuid) {
+        assertEquals("Tpdr-OTSi should contain two node rule groups", 2, nrgList.size());
+        List<NodeEdgePoint> nodeEdgePointList = new ArrayList<>(nrgList.get(0).getNodeEdgePoint().values());
+        assertEquals("Tpdr-OTSi node-rule-group should contain 2 NEP", 2, nodeEdgePointList.size());
+        assertThat("Tpdr-OTSi node-rule-group should be between eNEP and iNEP of XPDR1-NETWORK1",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        assertThat("Tpdr-OTSi node-rule-group should be between eNEP and iNEP of XPDR1-NETWORK1",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList.get(0).getNodeUuid());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList.get(1).getNodeUuid());
+        List<Rule> ruleList = new ArrayList<>(nrgList.get(0).nonnullRule().values());
+        assertEquals("node-rule-group should contain a single rule", 1, ruleList.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", ruleList.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, ruleList.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, ruleList.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForMuxOTSi(List<NodeRuleGroup> nrgList, Uuid enepUuid, Uuid inepUuid,
+                                              Uuid nodeUuid) {
+        assertEquals("Mux-OTSi should contain a single node rule group", 1, nrgList.size());
+        List<NodeEdgePoint> nodeEdgePointList = new ArrayList<>(nrgList.get(0).getNodeEdgePoint().values());
+        assertEquals("Mux-OTSi node-rule-group should contain 2 NEP", 2, nodeEdgePointList.size());
+        assertThat("Mux-OTSi node-rule-group should be between eNEP and iNEP of XPDR1-NETWORK1",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        assertThat("Mux-OTSi node-rule-group should be between eNEP and iNEP of XPDR1-NETWORK1",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList.get(0).getNodeUuid());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList.get(1).getNodeUuid());
+        List<Rule> ruleList = new ArrayList<>(nrgList.get(0).nonnullRule().values());
+        assertEquals("node-rule-group should contain a single rule", 1, ruleList.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", ruleList.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, ruleList.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, ruleList.get(0).getRuleType());
+    }
+
+    private void checkNodeRuleGroupForSwitchOTSi(List<NodeRuleGroup> nrgList, Uuid enepUuid, Uuid inepUuid,
+                                                 Uuid nodeUuid) {
+        assertEquals("Switch-OTSi should contain 4 node rule group", 4, nrgList.size());
+        for (NodeRuleGroup nodeRuleGroup : nrgList) {
+            assertEquals("each node-rule-group should contain 2 NEP for Switch-OTSi",
+                2, nodeRuleGroup.getNodeEdgePoint().size());
+        }
+        List<NodeEdgePoint> nodeEdgePointList1 = new ArrayList<>(nrgList.get(3).nonnullNodeEdgePoint().values());
+        assertThat("Switch-OTSi node-rule-group nb 4 should be between eNEP and iNEP of XPDR2-NETWORK2",
+            nodeEdgePointList1.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        assertThat("Switch-OTSi node-rule-group nb 4 should be between eNEP and iNEP of XPDR2-NETWORK2",
+            nodeEdgePointList1.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(enepUuid.getValue())).or(containsString(inepUuid.getValue())));
+        List<NodeEdgePoint> nodeEdgePointList0 = new ArrayList<>(nrgList.get(0).getNodeEdgePoint().values());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList0.get(0).getNodeUuid());
+        assertEquals("any item of the node-rule-group should have the same nodeUuid",
+            nodeUuid, nodeEdgePointList0.get(1).getNodeUuid());
+        List<Rule> ruleList0 = new ArrayList<>(nrgList.get(0).nonnullRule().values());
+        assertEquals("node-rule-group should contain a single rule", 1, ruleList0.size());
+        assertEquals("local-id of the rule should be 'forward'",
+            "forward", ruleList0.get(0).getLocalId());
+        assertEquals("the forwarding rule should be 'MAYFORWARDACROSSGROUP'",
+            ForwardingRule.MAYFORWARDACROSSGROUP, ruleList0.get(0).getForwardingRule());
+        assertEquals("the rule type should be 'FORWARDING'",
+            RuleType.FORWARDING, ruleList0.get(0).getRuleType());
+    }
+
+    private void checkNepClient100GSwitch(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        assertEquals("value of client nep should be '" + portName + "'",
+            portName, nameList.get(0).getValue());
+        assertEquals("value-name of client nep for '" + portName + "' should be '" + nepName + "'",
+            nepName, nameList.get(0).getValueName());
+        assertEquals("Client nep should support 2 kind of cep",
+            2, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("client nep should support 2 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItems(ODUTYPEODU4.class, DIGITALSIGNALTYPE100GigE.class));
+        assertEquals("client nep should be of DSR protocol type", LayerProtocolName.DSR, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, false);
+    }
+
+    private void checkNepClient100GTpdr(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        assertEquals("value of client nep should be '" + portName + "'",
+            portName, nameList.get(0).getValue());
+        assertEquals("value-name of client nep for '" + portName + "' should be 100G-tpdr'",
+            nepName, nameList.get(0).getValueName());
+        assertEquals("Client nep should support 1 kind of cep",
+            1, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("client nep should support 2 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItems(DIGITALSIGNALTYPE100GigE.class));
+        assertEquals("client nep should be of DSR protocol type", LayerProtocolName.DSR, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, false);
+    }
+
+    private void checkNepOtsiNode(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+                                  boolean withSip) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        assertEquals("value of OTSi nep should be '" + portName + "'",
+            portName, nameList.get(0).getValue());
+        assertEquals("value-name of OTSi nep should be '" + nepName + "'",
+            nepName, nameList.get(0).getValueName());
+        assertEquals("OTSi nep should support 2 kind of cep",
+            2, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("OTSi nep should support 2 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItems(PHOTONICLAYERQUALIFIEROMS.class, PHOTONICLAYERQUALIFIEROTSi.class));
+        assertEquals("OTSi nep should be of PHOTONIC_MEDIA protocol type",
+            LayerProtocolName.PHOTONICMEDIA, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, withSip);
+    }
+
+    private void checkNepOtsiRdmNode(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+                                     boolean withSip) {
+        assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
+        List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
+        assertEquals("value of OTSi nep should be '" + portName + "'",
+            portName, nameList.get(0).getValue());
+        assertEquals("value-name of OTSi nep should be '" + nepName + "'",
+            nepName, nameList.get(0).getValueName());
+        assertEquals("OTSi nep of RDM infra node should support only 1 kind of cep",
+            1, nep.getSupportedCepLayerProtocolQualifier().size());
+        assertThat("OTSi nep should support 2 kind of cep",
+            nep.getSupportedCepLayerProtocolQualifier(),
+            hasItems(PHOTONICLAYERQUALIFIEROMS.class));
+        assertEquals("OTSi nep should be of PHOTONIC_MEDIA protocol type",
+            LayerProtocolName.PHOTONICMEDIA, nep.getLayerProtocolName());
+        checkCommonPartOfNep(nep, withSip);
+    }
+
+    private void checkCommonPartOfNep(OwnedNodeEdgePoint nep, boolean withSip) {
+        assertEquals("link port direction should be DIRECTIONAL",
+            PortDirection.BIDIRECTIONAL, nep.getLinkPortDirection());
+        assertEquals("administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, nep.getAdministrativeState());
+        assertEquals("termination state should be TERMINATED BIDIRECTIONAL",
+            TerminationState.TERMINATEDBIDIRECTIONAL, nep.getTerminationState());
+        assertEquals("life-cycle state should be INSTALLED", LifecycleState.INSTALLED, nep.getLifecycleState());
+        if (withSip) {
+            assertEquals("Given nep should support 1 SIP", 1, nep.getMappedServiceInterfacePoint().size());
+        }
+        assertEquals("termination direction should be BIDIRECTIONAL",
+            TerminationDirection.BIDIRECTIONAL, nep.getTerminationDirection());
+        assertEquals("operational state of client nep should be ENABLED",
+            OperationalState.ENABLED, nep.getOperationalState());
+        assertEquals("link-port-role of client nep should be SYMMETRIC",
+            PortRole.SYMMETRIC, nep.getLinkPortRole());
+    }
+
+    private void checkTransitionalLink(org.opendaylight.yang.gen.v1
+                                           .urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link link,
+                                       Uuid node1Uuid, Uuid node2Uuid, String tp1, String tp2, String ietfNodeId) {
+        Uuid linkUuid = new Uuid(UUID.nameUUIDFromBytes((ietfNodeId + "--" + tp1 + "--" + tp2)
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        assertEquals("bad uuid for link between DSR node " + tp1 + " and iOTSI port " + tp2, linkUuid, link.getUuid());
+        assertEquals("Available capacity unit should be GBPS",
+            CapacityUnit.GBPS, link.getAvailableCapacity().getTotalSize().getUnit());
+        assertEquals("Available capacity -total size value should be 100",
+            Uint64.valueOf(100), link.getAvailableCapacity().getTotalSize().getValue());
+        assertEquals("transitional link should be between 2 nodes of protocol layers ODU and PHOTONIC_MEDIA",
+            2, link.getTransitionedLayerProtocolName().size());
+        assertThat("transitional link should be between 2 nodes of protocol layers ODU and PHOTONIC_MEDIA",
+            link.getTransitionedLayerProtocolName(),
+            hasItems(LayerProtocolName.ODU.getName(), LayerProtocolName.PHOTONICMEDIA.getName()));
+        assertEquals("transitional link should be BIDIRECTIONAL",
+            ForwardingDirection.BIDIRECTIONAL, link.getDirection());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
+            .link.NodeEdgePoint> nodeEdgePointList = new ArrayList<>(link.nonnullNodeEdgePoint().values());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(0).getTopologyUuid());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(1).getTopologyUuid());
+        assertThat("transitional links should terminate on DSR node and Photonic node",
+            nodeEdgePointList.get(0).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("transitional links should terminate on DSR node and Photonic node",
+            nodeEdgePointList.get(1).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        Uuid nep1Uuid = new Uuid(UUID.nameUUIDFromBytes(tp1.getBytes(Charset.forName("UTF-8"))).toString());
+        Uuid nep2Uuid = new Uuid(UUID.nameUUIDFromBytes(tp2.getBytes(Charset.forName("UTF-8"))).toString());
+        assertThat("transitional links should terminate on " + tp1 + " and " + tp2 + " neps",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(nep1Uuid.getValue())).or(containsString(nep2Uuid.getValue())));
+        assertThat("transitional links should terminate on DSR node and Photonic node",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(nep1Uuid.getValue())).or(containsString(nep2Uuid.getValue())));
+    }
+
+    private void checkOtnLink(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link link,
+                              Uuid node1Uuid, Uuid node2Uuid, Uuid tp1Uuid, Uuid tp2Uuid, Uuid linkUuid,
+                              String linkName) {
+        assertEquals("bad name for the link", linkName, link.getName().get(
+            new NameKey("otn link name")).getValue());
+        assertEquals("bad uuid for link", linkUuid, link.getUuid());
+        assertEquals("Available capacity unit should be MBPS",
+            CapacityUnit.MBPS, link.getAvailableCapacity().getTotalSize().getUnit());
+        String prefix = linkName.split("-")[0];
+        if ("OTU4".equals(prefix)) {
+            assertEquals("Available capacity -total size value should be 0",
+                Uint64.valueOf(0), link.getAvailableCapacity().getTotalSize().getValue());
+        } else if ("ODU4".equals(prefix)) {
+            assertEquals("Available capacity -total size value should be 100 000",
+                Uint64.valueOf(100000), link.getAvailableCapacity().getTotalSize().getValue());
+        }
+        assertEquals("Total capacity unit should be GBPS",
+            CapacityUnit.GBPS, link.getTotalPotentialCapacity().getTotalSize().getUnit());
+        assertEquals("Total capacity -total size value should be 100",
+            Uint64.valueOf(100), link.getTotalPotentialCapacity().getTotalSize().getValue());
+        if ("OTU4".equals(prefix)) {
+            assertEquals("otn link should be between 2 nodes of protocol layers PHOTONIC_MEDIA",
+                LayerProtocolName.PHOTONICMEDIA.getName(), link.getLayerProtocolName().get(0).getName());
+        } else if ("ODU4".equals(prefix)) {
+            assertEquals("otn link should be between 2 nodes of protocol layers ODU",
+                LayerProtocolName.ODU.getName(), link.getLayerProtocolName().get(0).getName());
+        }
+        assertEquals("otn tapi link should be BIDIRECTIONAL",
+            ForwardingDirection.BIDIRECTIONAL, link.getDirection());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
+            .link.NodeEdgePoint> nodeEdgePointList = new ArrayList<>(link.nonnullNodeEdgePoint().values());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(0).getTopologyUuid());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(1).getTopologyUuid());
+        assertThat("otn links should terminate on two distinct nodes",
+            nodeEdgePointList.get(0).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("otn links should terminate on two distinct nodes",
+            nodeEdgePointList.get(1).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("otn links should terminate on two distinct tps",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+        assertThat("otn links should terminate on two distinct tps",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+        assertEquals("operational state should be ENABLED",
+            OperationalState.ENABLED, link.getOperationalState());
+        assertEquals("administrative state should be UNLOCKED",
+            AdministrativeState.UNLOCKED, link.getAdministrativeState());
+    }
+
+    private void checkOmsLink(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link link,
+                              Uuid node1Uuid, Uuid node2Uuid, Uuid tp1Uuid, Uuid tp2Uuid, Uuid linkUuid,
+                              String linkName) {
+        assertEquals("bad name for the link", linkName, link.getName().get(
+            new NameKey("OMS link name")).getValue());
+        assertEquals("bad uuid for link", linkUuid, link.getUuid());
+        assertEquals("oms link should be between 2 nodes of protocol layers PHOTONIC_MEDIA",
+            LayerProtocolName.PHOTONICMEDIA.getName(), link.getLayerProtocolName().get(0).getName());
+        assertEquals("otn tapi link should be BIDIRECTIONAL",
+            ForwardingDirection.BIDIRECTIONAL, link.getDirection());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
+            .link.NodeEdgePoint> nodeEdgePointList = new ArrayList<>(link.nonnullNodeEdgePoint().values());
+        assertEquals("oms link should be between 2 neps",2 , nodeEdgePointList.size());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(0).getTopologyUuid());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(1).getTopologyUuid());
+        assertThat("oms links should terminate on two distinct nodes",
+            nodeEdgePointList.get(0).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct nodes",
+            nodeEdgePointList.get(1).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct tps",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct tps",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+    }
+
+    private void checkXpdrRdmLink(org.opendaylight.yang.gen.v1.urn
+                                      .onf.otcc.yang.tapi.topology.rev181210.topology.Link link,
+                              Uuid node1Uuid, Uuid node2Uuid, Uuid tp1Uuid, Uuid tp2Uuid, Uuid linkUuid,
+                              String linkName) {
+        assertEquals("bad name for the link", linkName, link.getName().get(
+            new NameKey("XPDR-RDM link name")).getValue());
+        assertEquals("bad uuid for link", linkUuid, link.getUuid());
+        assertEquals("oms link should be between 2 nodes of protocol layers PHOTONIC_MEDIA",
+            LayerProtocolName.PHOTONICMEDIA.getName(), link.getLayerProtocolName().get(0).getName());
+        assertEquals("otn tapi link should be BIDIRECTIONAL",
+            ForwardingDirection.BIDIRECTIONAL, link.getDirection());
+        List<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210
+            .link.NodeEdgePoint> nodeEdgePointList = new ArrayList<>(link.nonnullNodeEdgePoint().values());
+        assertEquals("oms link should be between 2 neps",2 , nodeEdgePointList.size());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(0).getTopologyUuid());
+        assertEquals("topology uuid should be the same for the two termination point of the link",
+            topologyUuid, nodeEdgePointList.get(1).getTopologyUuid());
+        assertThat("oms links should terminate on two distinct nodes",
+            nodeEdgePointList.get(0).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct nodes",
+            nodeEdgePointList.get(1).getNodeUuid().getValue(),
+            either(containsString(node1Uuid.getValue())).or(containsString(node2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct tps",
+            nodeEdgePointList.get(0).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+        assertThat("oms links should terminate on two distinct tps",
+            nodeEdgePointList.get(1).getNodeEdgePointUuid().getValue(),
+            either(containsString(tp1Uuid.getValue())).or(containsString(tp2Uuid.getValue())));
+    }
+
+    private Node changeTerminationPointState(Node initialNode, String tpid, AdminStates admin, State oper) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder tpdr1Bldr
+            = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.Node1Builder(
+                initialNode.augmentation(Node1.class));
+        Map<TerminationPointKey, TerminationPoint> tps = new HashMap<>(tpdr1Bldr.getTerminationPoint());
+        TerminationPointBuilder tpBldr = new TerminationPointBuilder(
+            tps.get(new TerminationPointKey(new TpId(tpid))));
+        tpBldr.addAugmentation(new TerminationPoint1Builder(tpBldr.augmentation(TerminationPoint1.class))
+            .setAdministrativeState(admin)
+            .setOperationalState(oper)
+            .build());
+        tps.replace(tpBldr.key(), tpBldr.build());
+        tpdr1Bldr.setTerminationPoint(tps);
+        return new NodeBuilder(initialNode).addAugmentation(tpdr1Bldr.build()).build();
+    }
+
+    private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.network.topology.rev180226.networks.network.Link changeOtnLinkState(
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .Link initiallink, AdminStates admin, State oper) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+            .LinkBuilder linkBldr = new
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev180226.networks.network
+                .LinkBuilder(initiallink);
+        linkBldr.addAugmentation(new Link1Builder(linkBldr.augmentation(Link1.class))
+            .setAdministrativeState(admin)
+            .setOperationalState(oper)
+            .build());
+        return linkBldr.build();
+    }
+}
index 56225bcbb44ef43c2bba25553c94d7e7810ba9c5..d7d3a467a407cd71e0f9d7732f55d9947d6ad9c8 100644 (file)
@@ -83,6 +83,7 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Ru
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroup;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePointKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.edge.point.MappedServiceInterfacePointKey;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.Rule;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
@@ -103,6 +104,9 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
         .networks.network.Link> otnLinks;
     private static Uuid topologyUuid;
     private static DataBroker dataBroker = getDataBroker();
+    private static final String E_OTSI = "eOTSi";
+    private static final String I_OTSI = "iOTSi";
+    private static final String DSR = "DSR";
 
     @BeforeClass
     public static void setUp() throws InterruptedException, ExecutionException {
@@ -729,12 +733,14 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid client4NepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR2-CLIENT4").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepClient100GSwitch(nep1, client4NepUuid, "XPDR2-CLIENT4", "NodeEdgePoint_C");
+                checkNepClient100GSwitch(nep1, client4NepUuid, "XPDR2-CLIENT4", "NodeEdgePoint_C",
+                    otnSwitch.getNodeId().getValue(), DSR);
                 OwnedNodeEdgePoint nep2 = nepsN.get(1);
                 Uuid networkNepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR2-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepNetworkODU4(nep2, networkNepUuid, "XPDR2-NETWORK1", "NodeEdgePoint_N");
+                checkNepNetworkODU4(nep2, networkNepUuid, "XPDR2-NETWORK1", "NodeEdgePoint_N",
+                    otnSwitch.getNodeId().getValue(), DSR);
                 List<NodeRuleGroup> nrgList = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -751,13 +757,15 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid client3NepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-CLIENT3").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepClient10G(nep3, client3NepUuid, "XPDR1-CLIENT3", "NodeEdgePoint_C");
+                checkNepClient10G(nep3, client3NepUuid, "XPDR1-CLIENT3", "NodeEdgePoint_C",
+                    otnMuxA.getNodeId().getValue(), DSR);
 
                 OwnedNodeEdgePoint nep4 = nepsN.get(0);
                 Uuid networkNepUuid2 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepNetworkODU4(nep4, networkNepUuid2, "XPDR1-NETWORK1", "NodeEdgePoint_N");
+                checkNepNetworkODU4(nep4, networkNepUuid2, "XPDR1-NETWORK1", "NodeEdgePoint_N",
+                    otnMuxA.getNodeId().getValue(), DSR);
                 List<NodeRuleGroup> nrgList2 = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -774,13 +782,15 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid client1NepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-CLIENT1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepClient100GTpdr(nep5, client1NepUuid, "XPDR1-CLIENT1", "100G-tpdr");
+                checkNepClient100GTpdr(nep5, client1NepUuid, "XPDR1-CLIENT1", "100G-tpdr",
+                    tpdr100G.getNodeId().getValue(), DSR);
 
                 OwnedNodeEdgePoint nep6 = nepsN.get(0);
                 Uuid networkNepUuid3 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+DSR+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepNetworkODU4(nep6, networkNepUuid3, "XPDR1-NETWORK1", "NodeEdgePoint_N");
+                checkNepNetworkODU4(nep6, networkNepUuid3, "XPDR1-NETWORK1", "NodeEdgePoint_N",
+                    tpdr100G.getNodeId().getValue(), DSR);
                 List<NodeRuleGroup> nrgList3 = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -823,12 +833,14 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid inepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR2-NETWORK2").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep1, inepUuid, "XPDR2-NETWORK2", "iNodeEdgePoint");
+                checkNepOtsiNode(nep1, inepUuid, "XPDR2-NETWORK2", "iNodeEdgePoint", otnSwitch.getNodeId().getValue(),
+                    I_OTSI);
                 OwnedNodeEdgePoint nep2 = nepsE.get(0);
                 Uuid enepUuid = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR2-NETWORK2").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep2, enepUuid, "XPDR2-NETWORK2", "eNodeEdgePoint");
+                checkNepOtsiNode(nep2, enepUuid, "XPDR2-NETWORK2", "eNodeEdgePoint", otnSwitch.getNodeId().getValue(),
+                    E_OTSI);
                 List<NodeRuleGroup> nrgList = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -841,12 +853,14 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid enepUuid2 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep3, enepUuid2, "XPDR1-NETWORK1", "eNodeEdgePoint");
+                checkNepOtsiNode(nep3, enepUuid2, "XPDR1-NETWORK1", "eNodeEdgePoint", otnMuxA.getNodeId().getValue(),
+                    E_OTSI);
                 OwnedNodeEdgePoint nep4 = nepsI.get(0);
                 Uuid inepUuid2 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep4, inepUuid2, "XPDR1-NETWORK1", "iNodeEdgePoint");
+                checkNepOtsiNode(nep4, inepUuid2, "XPDR1-NETWORK1", "iNodeEdgePoint", otnMuxA.getNodeId().getValue(),
+                    I_OTSI);
                 List<NodeRuleGroup> nrgList2 = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -859,12 +873,14 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
                 Uuid enepUuid3 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+eOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep5, enepUuid3, "XPDR1-NETWORK1", "eNodeEdgePoint");
+                checkNepOtsiNode(nep5, enepUuid3, "XPDR1-NETWORK1", "eNodeEdgePoint", tpdr100G.getNodeId().getValue(),
+                    E_OTSI);
                 OwnedNodeEdgePoint nep6 = nepsI.get(0);
                 Uuid inepUuid3 = new Uuid(
                         UUID.nameUUIDFromBytes((nodeId + "+iOTSi+XPDR1-NETWORK1").getBytes(Charset.forName("UTF-8")))
                         .toString());
-                checkNepOtsiNode(nep6, inepUuid3, "XPDR1-NETWORK1", "iNodeEdgePoint");
+                checkNepOtsiNode(nep6, inepUuid3, "XPDR1-NETWORK1", "iNodeEdgePoint", tpdr100G.getNodeId().getValue(),
+                    I_OTSI);
                 List<NodeRuleGroup> nrgList3 = node.nonnullNodeRuleGroup().values().stream()
                     .sorted((nrg1, nrg2) -> nrg1.getUuid().getValue().compareTo(nrg2.getUuid().getValue()))
                     .collect(Collectors.toList());
@@ -890,7 +906,8 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
         }
     }
 
-    private void checkNepClient10G(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+    private void checkNepClient10G(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+            String nodeId, String extension) {
         assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
         List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
         Name name = nameList.get(0);
@@ -905,9 +922,11 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             hasItems(ODUTYPEODU2.class, ODUTYPEODU2E.class, DIGITALSIGNALTYPE10GigELAN.class));
         assertEquals("client nep should be of ETH protocol type", LayerProtocolName.ETH, nep.getLayerProtocolName());
         checkCommonPartOfNep(nep, false);
+        checkSIP(nep, portName, nodeId, extension);
     }
 
-    private void checkNepNetworkODU4(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+    private void checkNepNetworkODU4(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+            String nodeId, String extension) {
         assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
         List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
         Name name = nameList.get(0);
@@ -922,6 +941,7 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             hasItem(ODUTYPEODU4.class));
         assertEquals("network nep should be of ODU protocol type", LayerProtocolName.ODU, nep.getLayerProtocolName());
         checkCommonPartOfNep(nep, false);
+        checkSIP(nep, portName, nodeId, extension);
     }
 
     private void checkNodeRuleGroupForTpdrDSR(List<NodeRuleGroup> nrgList, Uuid clientNepUuid, Uuid networkNepUuid,
@@ -1105,7 +1125,8 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             RuleType.FORWARDING, ruleList0.get(0).getRuleType());
     }
 
-    private void checkNepClient100GSwitch(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+    private void checkNepClient100GSwitch(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+            String nodeId, String extension) {
         assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
         List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
         assertEquals("value of client nep should be '" + portName + "'",
@@ -1119,9 +1140,11 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             hasItems(ODUTYPEODU4.class, DIGITALSIGNALTYPE100GigE.class));
         assertEquals("client nep should be of ETH protocol type", LayerProtocolName.ETH, nep.getLayerProtocolName());
         checkCommonPartOfNep(nep, false);
+        checkSIP(nep, portName, nodeId, extension);
     }
 
-    private void checkNepClient100GTpdr(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+    private void checkNepClient100GTpdr(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+            String nodeId, String extension) {
         assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
         List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
         assertEquals("value of client nep should be '" + portName + "'",
@@ -1135,9 +1158,11 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             hasItems(DIGITALSIGNALTYPE100GigE.class));
         assertEquals("client nep should be of ETH protocol type", LayerProtocolName.ETH, nep.getLayerProtocolName());
         checkCommonPartOfNep(nep, false);
+        checkSIP(nep, portName, nodeId, extension);
     }
 
-    private void checkNepOtsiNode(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
+    private void checkNepOtsiNode(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName,
+            String nodeId, String extension) {
         assertEquals("bad uuid for " + portName, nepUuid, nep.getUuid());
         List<Name> nameList = new ArrayList<>(nep.nonnullName().values());
         assertEquals("value of OTSi nep should be '" + portName + "'",
@@ -1153,6 +1178,15 @@ public class ConvertORTopoToTapiTopoTest extends AbstractTest {
             LayerProtocolName.PHOTONICMEDIA, nep.getLayerProtocolName());
         assertEquals("OTSi nep should support one SIP", 1, nep.getMappedServiceInterfacePoint().size());
         checkCommonPartOfNep(nep, false);
+        checkSIP(nep, portName, nodeId, extension);
+    }
+
+    private void checkSIP(OwnedNodeEdgePoint nep, String portName, String nodeId, String extension) {
+        Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", nodeId, extension, portName))
+            .getBytes(Charset.forName("UTF-8"))).toString());
+        assertEquals("service-interface-point-uuid of network nep for '" + portName + "' should be '"
+            + String.join("+", "SIP", nodeId, portName) + "'", sipUuid, nep.getMappedServiceInterfacePoint()
+                .get(new MappedServiceInterfacePointKey(sipUuid)).getServiceInterfacePointUuid());
     }
 
     private void checkNepOtsiRdmNode(OwnedNodeEdgePoint nep, Uuid nepUuid, String portName, String nepName) {
index 96d709e016c774980fe982df14841e048c5f7249..94ff0c67f21e9b2ceba3e5faba468cc14c9287b7 100644 (file)
@@ -16,10 +16,11 @@ import static org.junit.Assert.assertNotNull;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -43,17 +44,31 @@ import org.opendaylight.transportpce.test.utils.TopologyDataUtils;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointListInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointListOutput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.get.service._interface.point.list.output.Sip;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.get.service._interface.point.list.output.SipKey;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameKey;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.ForwardingRule;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsOutput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsOutput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Node;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.RuleType;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.topology.details.output.Topology;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.NodeRuleGroup;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.OwnedNodeEdgePoint;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.NodeEdgePoint;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.node.rule.group.Rule;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Link;
@@ -116,14 +131,14 @@ public class TapiTopologyImplTest extends AbstractTest {
         @Nullable
         Topology topology = rpcResult.getResult().getTopology();
         assertNotNull("Topology should not be null", topology);
-        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.TPDR_100G.getBytes(Charset.forName("UTF-8")))
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TopologyUtils.TPDR_100G.getBytes(StandardCharsets.UTF_8))
             .toString());
         assertEquals("incorrect topology uuid", topoUuid, topology.getUuid());
         assertEquals("Node list size should be 1", 1, topology.getNode().size());
         Name nodeName = topology.getNode().values().stream().findFirst().get().getName()
             .get(new NameKey("Tpdr100g node name"));
         assertEquals("Node name should be 'Tpdr100g over WDM node'", "Tpdr100g over WDM node", nodeName.getValue());
-        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeName.getValue().getBytes(Charset.forName("UTF-8")))
+        Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeName.getValue().getBytes(StandardCharsets.UTF_8))
             .toString());
         assertEquals("incorrect node uuid", nodeUuid, topology.getNode().values().stream().findFirst().get().getUuid());
         long nb = topology.getNode().values().stream().findFirst().get().getOwnedNodeEdgePoint().size();
@@ -146,7 +161,7 @@ public class TapiTopologyImplTest extends AbstractTest {
 
     @Test
     public void getTopologyDetailsForOtnTopologyWithOtnLinksWhenSuccessful()
-        throws ExecutionException, InterruptedException {
+            throws ExecutionException, InterruptedException {
         GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(TopologyUtils.T0_MULTILAYER);
         TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils);
         ListenableFuture<RpcResult<GetTopologyDetailsOutput>> result = tapiTopoImpl.getTopologyDetails(input);
@@ -220,28 +235,28 @@ public class TapiTopologyImplTest extends AbstractTest {
         assertEquals("Link list should contain 8 transitional links", 8, nbOmsLinks);
         assertEquals("Link list should contain 2 OTN links", 2, nbOtnLinks);
 
-        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR".getBytes(StandardCharsets.UTF_8))
             .toString());
-        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+DSR".getBytes(Charset.forName("UTF-8")))
+        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+DSR".getBytes(StandardCharsets.UTF_8))
             .toString());
-        Uuid node3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+        Uuid node3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(StandardCharsets.UTF_8))
             .toString());
-        Uuid node4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+OTSi".getBytes(Charset.forName("UTF-8")))
+        Uuid node4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+OTSi".getBytes(StandardCharsets.UTF_8))
             .toString());
         Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR+XPDR1-NETWORK1"
-            .getBytes(Charset.forName("UTF-8"))).toString());
+            .getBytes(StandardCharsets.UTF_8)).toString());
         Uuid tp2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+DSR+XPDR1-NETWORK1"
-            .getBytes(Charset.forName("UTF-8"))).toString());
+            .getBytes(StandardCharsets.UTF_8)).toString());
         Uuid tp3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+iOTSi+XPDR1-NETWORK1"
-            .getBytes(Charset.forName("UTF-8"))).toString());
+            .getBytes(StandardCharsets.UTF_8)).toString());
         Uuid tp4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+iOTSi+XPDR1-NETWORK1"
-            .getBytes(Charset.forName("UTF-8"))).toString());
+            .getBytes(StandardCharsets.UTF_8)).toString());
         Uuid link1Uuid =
             new Uuid(UUID.nameUUIDFromBytes("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
-                .getBytes(Charset.forName("UTF-8"))).toString());
+                .getBytes(StandardCharsets.UTF_8)).toString());
         Uuid link2Uuid =
             new Uuid(UUID.nameUUIDFromBytes("OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
-                .getBytes(Charset.forName("UTF-8"))).toString());
+                .getBytes(StandardCharsets.UTF_8)).toString());
 
         List<Link> links = topology.nonnullLink().values().stream()
             .filter(l -> l.getName().containsKey(new NameKey("otn link name")))
@@ -253,8 +268,371 @@ public class TapiTopologyImplTest extends AbstractTest {
             "OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1");
     }
 
+    @Test
+    public void getTopologyDetailsForFullTapiTopologyWithLinksWhenSuccessful()
+            throws ExecutionException, InterruptedException {
+        GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(
+            TopologyUtils.T0_FULL_MULTILAYER);
+        TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils);
+        ListenableFuture<RpcResult<GetTopologyDetailsOutput>> result = tapiTopoImpl.getTopologyDetails(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                endSignal.countDown();
+            }
+        }, executorService);
+        endSignal.await();
+        RpcResult<GetTopologyDetailsOutput> rpcResult = result.get();
+        @Nullable
+        Topology topology = rpcResult.getResult().getTopology();
+        assertNotNull("Topology should not be null", topology);
+        // 2 Nodes per Xpdr/Spdr node (DSR-ODU & PHOT) + 1 Node per Roadm
+        assertEquals("Node list size should be 18", 18, topology.getNode().size());
+        long nb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("100G-tpdr"))))
+            .count();
+        // 2 client ports in configuration -> removed the checkTp so we have 2 NEPs
+        assertEquals("XPDR-A1-XPDR1+DSR should only have two client neps", 2, nb1);
+        long inb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint_N"))))
+            .count();
+        assertEquals("XPDR-A1-XPDR1+DSR should only have two internal network neps", 2, inb1);
+        long enb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint_N"))))
+            .count();
+        assertEquals("XPDR-A1-XPDR1+DSR should only have two external network neps", 2, enb1);
+        long nb2 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("NodeEdgePoint_C"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+DSR (mux) should have 4 client neps", 4, nb2);
+        long inb3 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint_N"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+DSR (mux) should have a single internal network nep", 1, inb3);
+        long enb3 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint_N"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+DSR (mux) should have a single external network nep", 1, enb3);
+        long nb4 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("NodeEdgePoint_C"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+DSR (switch) should have 4 client neps", 4, nb4);
+        long inb5 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint_N"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+DSR (switch) should have 4 internal network neps", 4, inb5);
+        long enb5 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.DSR))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+DSR"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint_N"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+DSR (switch) should have 4 external network neps", 4, enb5);
+
+        // Now lets check for the Photonic media nodes (same nodes as for DSR + 1 Roadm node)
+        nb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint"))))
+            .count();
+        // 2 client ports in configuration -> removed the checkTp so we have 2 NEPs
+        assertEquals("XPDR-A1-XPDR1+OTSi should only have two internal network neps", 2, nb1);
+        inb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint"))))
+            .count();
+        assertEquals("XPDR-A1-XPDR1+OTSi should only have two external network neps", 2, inb1);
+        enb1 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("XPDR-A1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("PhotMedNodeEdgePoint"))))
+            .count();
+        assertEquals("XPDR-A1-XPDR1+OTSi should only have two photonic network neps", 2, enb1);
+        nb2 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+OTSi (mux) should have a single internal network nep", 1, nb2);
+        inb3 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+OTSi (mux) should have a single external network nep", 1, inb3);
+        enb3 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR1+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("PhotMedNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR1+OTSi (mux) should have a single photonic network nep", 1, enb3);
+        nb4 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("iNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+OTSi (switch) should have 4 internal network neps", 4, nb4);
+        inb5 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("eNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+OTSi (switch) should have 4 external network neps", 4, inb5);
+        enb5 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals("SPDR-SA1-XPDR2+OTSi"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().containsKey(new NameKey("PhotMedNodeEdgePoint"))))
+            .count();
+        assertEquals("SPDR-SA1-XPDR2+OTSi (switch) should have 4 photonic network neps", 4, enb5);
+        // We should have 3 neps per DEGREE-TTP port and 3 neps per SRG-PP port
+        long inb6 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals(
+                "ROADM-A1+PHOTONIC_MEDIA"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().values().stream().findFirst().get().getValue().contains("DEG")))
+            .count();
+        assertEquals("ROADM-A1+PHOTONIC_MEDIA (DEGREE) should have 6 network neps", 6, inb6);
+        long enb6 = topology.getNode().values().stream()
+            .filter(node -> node.getLayerProtocolName().contains(LayerProtocolName.PHOTONICMEDIA))
+            .filter(node -> node.getName().values().stream().findFirst().get().getValue().equals(
+                "ROADM-A1+PHOTONIC_MEDIA"))
+            .flatMap(node -> node.getOwnedNodeEdgePoint().values().stream()
+                .filter(nep -> nep.getName().values().stream().findFirst().get().getValue().contains("SRG")))
+            .count();
+        assertEquals("ROADM-A1+PHOTONIC_MEDIA (SRG) should have 24 network neps", 24, enb6);
+
+        // Links in openroadm topology which include Roadm-to-Roadm and Xpdr-to-Roadm (ortopo / 2)
+        // + transitional links -> 1 per network port of Xpdr + OTN links / 2
+        assertEquals("Link list size should be 27", 27, topology.getLink().size());
+        Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes("T0 - Full Multi-layer topology".getBytes()).toString());
+        assertEquals("incorrect topology uuid", topoUuid, topology.getUuid());
+        assertEquals("topology name should be T0 - Full Multi-layer topology",
+            "T0 - Full Multi-layer topology",
+            topology.nonnullName().values().stream().findFirst().get().getValue());
+
+        long nbDsrOduNodes = topology.nonnullNode().values().stream()
+            .filter(n -> n.getName().containsKey(new NameKey("dsr/odu node name"))).count();
+        long nbPhotonicNodes = topology.nonnullNode().values().stream()
+            .filter(n -> n.getName().containsKey(new NameKey("otsi node name"))).count();
+        // In DSR/ODU we create one node per Xpdr (no filtering out)
+        assertEquals("Node list should contain 8 DSR-ODU nodes", 8, nbDsrOduNodes);
+        // We need to add the Roadms as Photonic nodes. Instead of 1 node as roadm infra we have 2 roadm nodes
+        assertEquals("Node list should contain 8 Photonics nodes", 8, nbPhotonicNodes);
+        long nbTransititionalLinks = topology.getLink().values().stream()
+            .filter(l -> l.getName().containsKey(new NameKey("transitional link name"))).count();
+        // Roadm-to-Roadm
+        long nbOmsLinks = topology.getLink().values().stream()
+            .filter(l -> l.getName().containsKey(new NameKey("OMS link name"))).count();
+        // Xpdr-to-Roadm
+        long nbOmsLinks1 = topology.getLink().values().stream()
+            .filter(l -> l.getName().containsKey(new NameKey("XPDR-RDM link name"))).count();
+        long nbOtnLinks = topology.getLink().values().stream()
+            .filter(l -> l.getName().containsKey(new NameKey("otn link name"))).count();
+        // 1 transitional link per NETWORK port
+        assertEquals("Link list should contain 16 transitional links", 16, nbTransititionalLinks);
+        // 1 OMS per ROADM-to-ROADM link + Existing XPDR-tp-ROADM link in openroadm topology
+        assertEquals("Link list should contain 9 OMS links", 9, nbOmsLinks + nbOmsLinks1);
+        // Should we consider OTN links as links or connections??
+        assertEquals("Link list should contain 2 OTN links", 2, nbOtnLinks);
+
+        Uuid node1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+DSR".getBytes(StandardCharsets.UTF_8))
+            .toString());
+        Uuid node2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+DSR".getBytes(StandardCharsets.UTF_8))
+            .toString());
+        Uuid node3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+OTSi".getBytes(StandardCharsets.UTF_8))
+            .toString());
+        Uuid node4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+OTSi".getBytes(StandardCharsets.UTF_8))
+            .toString());
+        Uuid tp1Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+eODU+XPDR1-NETWORK1"
+            .getBytes(StandardCharsets.UTF_8)).toString());
+        Uuid tp2Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+eODU+XPDR1-NETWORK1"
+            .getBytes(StandardCharsets.UTF_8)).toString());
+        Uuid tp3Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SA1-XPDR1+iOTSi+XPDR1-NETWORK1"
+            .getBytes(StandardCharsets.UTF_8)).toString());
+        Uuid tp4Uuid = new Uuid(UUID.nameUUIDFromBytes("SPDR-SC1-XPDR1+iOTSi+XPDR1-NETWORK1"
+            .getBytes(StandardCharsets.UTF_8)).toString());
+        Uuid link1Uuid =
+            new Uuid(UUID.nameUUIDFromBytes("ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
+                .getBytes(StandardCharsets.UTF_8)).toString());
+        Uuid link2Uuid =
+            new Uuid(UUID.nameUUIDFromBytes("OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1"
+                .getBytes(StandardCharsets.UTF_8)).toString());
+
+        List<Link> links = topology.nonnullLink().values().stream()
+            .filter(l -> l.getName().containsKey(new NameKey("otn link name")))
+            .sorted((l1, l2) -> l1.getUuid().getValue().compareTo(l2.getUuid().getValue()))
+            .collect(Collectors.toList());
+        checkOtnLink(links.get(0), topoUuid, node1Uuid, node2Uuid, tp1Uuid, tp2Uuid, link1Uuid,
+            "ODTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1");
+        checkOtnLink(links.get(1), topoUuid, node3Uuid, node4Uuid, tp3Uuid, tp4Uuid, link2Uuid,
+            "OTU4-SPDR-SA1-XPDR1-XPDR1-NETWORK1toSPDR-SC1-XPDR1-XPDR1-NETWORK1");
+    }
+
+    @Test
+    public void getNodeAndNepsDetailsWhenSuccessful()
+            throws ExecutionException, InterruptedException {
+        GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(
+            TopologyUtils.T0_FULL_MULTILAYER);
+        TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils);
+        ListenableFuture<RpcResult<GetTopologyDetailsOutput>> result = tapiTopoImpl.getTopologyDetails(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                endSignal.countDown();
+            }
+        }, executorService);
+        endSignal.await();
+        RpcResult<GetTopologyDetailsOutput> rpcResult = result.get();
+        @Nullable
+        Topology topology = rpcResult.getResult().getTopology();
+        for (Node node:topology.getNode().values()) {
+            String nodeName = node.getName().values().stream().findFirst().get().getValue();
+            GetNodeDetailsInput input1 = TapiTopologyDataUtils.buildGetNodeDetailsInput(
+                TopologyUtils.T0_FULL_MULTILAYER, nodeName);
+            ListenableFuture<RpcResult<GetNodeDetailsOutput>> result1 = tapiTopoImpl.getNodeDetails(input1);
+            result.addListener(new Runnable() {
+                @Override
+                public void run() {
+                    endSignal.countDown();
+                }
+            }, executorService);
+            endSignal.await();
+            RpcResult<GetNodeDetailsOutput> rpcResult1 = result1.get();
+            @Nullable
+            Node node1 = rpcResult1.getResult().getNode();
+            assertNotNull("Node should not be null", node1);
+            for (OwnedNodeEdgePoint onep:node1.getOwnedNodeEdgePoint().values()) {
+                String onepName = onep.getName().values().stream().findFirst().get().getValue();
+                GetNodeEdgePointDetailsInput input2 = TapiTopologyDataUtils.buildGetNodeEdgePointDetailsInput(
+                    TopologyUtils.T0_FULL_MULTILAYER, nodeName, onepName);
+                ListenableFuture<RpcResult<GetNodeEdgePointDetailsOutput>> result2
+                    = tapiTopoImpl.getNodeEdgePointDetails(input2);
+                result.addListener(new Runnable() {
+                    @Override
+                    public void run() {
+                        endSignal.countDown();
+                    }
+                }, executorService);
+                endSignal.await();
+                RpcResult<GetNodeEdgePointDetailsOutput> rpcResult2 = result2.get();
+                org.opendaylight.yang.gen.v1
+                    .urn.onf.otcc.yang.tapi.topology.rev181210.get.node.edge.point.details.output.NodeEdgePoint
+                        onep1 = rpcResult2.getResult().getNodeEdgePoint();
+                assertNotNull("Node Edge Point should not be null", onep1);
+            }
+        }
+    }
+
+    @Test
+    public void getLinkDetailsWhenSuccessful()
+            throws ExecutionException, InterruptedException {
+        GetTopologyDetailsInput input = TapiTopologyDataUtils.buildGetTopologyDetailsInput(
+            TopologyUtils.T0_FULL_MULTILAYER);
+        TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils);
+        ListenableFuture<RpcResult<GetTopologyDetailsOutput>> result = tapiTopoImpl.getTopologyDetails(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                endSignal.countDown();
+            }
+        }, executorService);
+        endSignal.await();
+        RpcResult<GetTopologyDetailsOutput> rpcResult = result.get();
+        @Nullable
+        Topology topology = rpcResult.getResult().getTopology();
+        for (Link link:topology.getLink().values()) {
+            String linkName = link.getName().values().stream().findFirst().get().getValue();
+            GetLinkDetailsInput input1 = TapiTopologyDataUtils.buildGetLinkDetailsInput(
+                TopologyUtils.T0_FULL_MULTILAYER, linkName);
+            ListenableFuture<RpcResult<GetLinkDetailsOutput>> result1 = tapiTopoImpl.getLinkDetails(input1);
+            result.addListener(new Runnable() {
+                @Override
+                public void run() {
+                    endSignal.countDown();
+                }
+            }, executorService);
+            endSignal.await();
+            RpcResult<GetLinkDetailsOutput> rpcResult1 = result1.get();
+            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.get.link.details.output.Link link1
+                = rpcResult1.getResult().getLink();
+            assertNotNull("Link should not be null", link1);
+        }
+    }
+
+    @Test
+    public void getSipDetailsWhenSuccessful()
+            throws ExecutionException, InterruptedException {
+        GetServiceInterfacePointListInput input = TapiTopologyDataUtils.buildServiceInterfacePointListInput();
+        TapiTopologyImpl tapiTopoImpl = new TapiTopologyImpl(getDataBroker(), tapiContext, topologyUtils);
+        ListenableFuture<RpcResult<GetServiceInterfacePointListOutput>> result = tapiTopoImpl
+            .getServiceInterfacePointList(input);
+        result.addListener(new Runnable() {
+            @Override
+            public void run() {
+                endSignal.countDown();
+            }
+        }, executorService);
+        endSignal.await();
+        RpcResult<GetServiceInterfacePointListOutput> rpcResult = result.get();
+        Map<SipKey, Sip> sipMap = rpcResult.getResult().getSip();
+        for (Sip sip:sipMap.values()) {
+            Uuid sipUuid = sip.getUuid();
+            GetServiceInterfacePointDetailsInput input1 = TapiTopologyDataUtils
+                .buildGetServiceInterfacePointDetailsInput(sipUuid);
+            ListenableFuture<RpcResult<GetServiceInterfacePointDetailsOutput>> result1
+                = tapiTopoImpl.getServiceInterfacePointDetails(input1);
+            result.addListener(new Runnable() {
+                @Override
+                public void run() {
+                    endSignal.countDown();
+                }
+            }, executorService);
+            endSignal.await();
+            RpcResult<GetServiceInterfacePointDetailsOutput> rpcResult1 = result1.get();
+            org.opendaylight.yang.gen.v1
+                .urn.onf.otcc.yang.tapi.common.rev181210.get.service._interface.point.details.output.Sip sip1
+                    = rpcResult1.getResult().getSip();
+            assertNotNull("Sip should not be null", sip1);
+        }
+    }
+
     private void checkOtnLink(Link link, Uuid topoUuid, Uuid node1Uuid, Uuid node2Uuid, Uuid tp1Uuid, Uuid tp2Uuid,
-        Uuid linkUuid, String linkName) {
+            Uuid linkUuid, String linkName) {
         assertEquals("bad name for the link", linkName, link.getName().get(new NameKey("otn link name")).getValue());
         assertEquals("bad uuid for link", linkUuid, link.getUuid());
         assertEquals("Available capacity unit should be MBPS",
diff --git a/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiConnectivityDataUtils.java b/tapi/src/test/java/org/opendaylight/transportpce/tapi/utils/TapiConnectivityDataUtils.java
new file mode 100644 (file)
index 0000000..0384dcf
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2021 Nokia, 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.tapi.utils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev181130.NodeIdType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ConnectionType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.RpcActions;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.sdnc.request.header.SdncRequestHeaderBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.RxDirection;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.RxDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.TxDirection;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.TxDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.lgx.LgxBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.port.PortBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceCreateInputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.create.input.ServiceAEndBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.create.input.ServiceZEndBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.AdministrativeState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.CapacityUnit;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.ForwardingDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LayerProtocolName;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.LifecycleState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.OperationalState;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortDirection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.PortRole;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.capacity.TotalSizeBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.Name;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.local._class.NameBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.CreateConnectivityServiceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.DeleteConnectivityServiceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ProtectionRole;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ServiceType;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.constraint.RequestedCapacityBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityService;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectivityServiceKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.Connection;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.ConnectionKey;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.end.point.ServiceInterfacePointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.ConnectivityConstraintBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPoint;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.create.connectivity.service.input.EndPointKey;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+
+public final class TapiConnectivityDataUtils {
+    public static CreateConnectivityServiceInput buildConnServiceCreateInput() {
+
+        EndPoint endPoint1 = getEndPoint1Builder().build();
+        EndPoint endPoint2 = getEndPoint2Builder().build();
+        Map<EndPointKey, EndPoint> endPointMap = new HashMap<>();
+        endPointMap.put(endPoint1.key(), endPoint1);
+        endPointMap.put(endPoint2.key(), endPoint2);
+
+        return new CreateConnectivityServiceInputBuilder()
+            .setEndPoint(endPointMap)
+            .setConnectivityConstraint(new ConnectivityConstraintBuilder().setServiceLayer(LayerProtocolName.DSR)
+                .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY).setServiceLevel("some service-level")
+                .setRequestedCapacity(new RequestedCapacityBuilder()
+                    .setTotalSize(new TotalSizeBuilder().setUnit(CapacityUnit.GBPS)
+                        .setValue(Uint64.valueOf(10)).build()).build()).build())
+            .setState("some state")
+            .build();
+    }
+
+    public static DeleteConnectivityServiceInput buildConnServiceDeleteInput() {
+        return new DeleteConnectivityServiceInputBuilder()
+            .setServiceIdOrName(UUID.nameUUIDFromBytes("service 1".getBytes(StandardCharsets.UTF_8)).toString())
+            .build();
+    }
+
+    private static EndPointBuilder getEndPoint2Builder() {
+        Name name = new NameBuilder().setValueName("OpenROADM node id").setValue("SPDR-SC1-XPDR1").build();
+        return new EndPointBuilder().setLayerProtocolName(LayerProtocolName.DSR)
+            .setAdministrativeState(AdministrativeState.UNLOCKED)
+            .setOperationalState(OperationalState.ENABLED)
+            .setDirection(PortDirection.BIDIRECTIONAL)
+            .setRole(PortRole.SYMMETRIC)
+            .setProtectionRole(ProtectionRole.NA)
+            .setLocalId("SPDR-SC1-XPDR1")
+            .setName(Map.of(name.key(), name))
+            .setServiceInterfacePoint(new ServiceInterfacePointBuilder().setServiceInterfacePointUuid(
+                new Uuid("25812ef2-625d-3bf8-af55-5e93946d1c22")).build());
+    }
+
+    private static EndPointBuilder getEndPoint1Builder() {
+        Name name = new NameBuilder().setValueName("OpenROADM node id").setValue("SPDR-SA1-XPDR1").build();
+        return new EndPointBuilder().setLayerProtocolName(LayerProtocolName.DSR)
+            .setAdministrativeState(AdministrativeState.UNLOCKED)
+            .setOperationalState(OperationalState.ENABLED)
+            .setDirection(PortDirection.BIDIRECTIONAL)
+            .setRole(PortRole.SYMMETRIC)
+            .setProtectionRole(ProtectionRole.NA)
+            .setLocalId("SPDR-SA1-XPDR1")
+            .setName(Map.of(name.key(), name))
+            .setServiceInterfacePoint(new ServiceInterfacePointBuilder().setServiceInterfacePointUuid(
+                new Uuid("c14797a0-adcc-3875-a1fe-df8949d1a2d7")).build());
+    }
+
+    public static ServiceCreateInput buildServiceCreateInput() {
+
+        return new ServiceCreateInputBuilder()
+            .setCommonId("commonId")
+            .setConnectionType(ConnectionType.Service)
+            .setCustomer("Customer")
+            .setServiceName(UUID.nameUUIDFromBytes("service 1".getBytes(StandardCharsets.UTF_8)).toString())
+            .setServiceAEnd(getServiceAEndBuild().build())
+            .setServiceZEnd(getServiceZEndBuild().build())
+            .setSdncRequestHeader(new SdncRequestHeaderBuilder().setRequestId("request 1")
+                .setRpcAction(RpcActions.ServiceCreate).setNotificationUrl("notification url").build())
+            .build();
+    }
+
+    public static ServiceAEndBuilder getServiceAEndBuild() {
+        return new ServiceAEndBuilder()
+            .setClli("NodeSA").setServiceFormat(ServiceFormat.Ethernet).setServiceRate(Uint32.valueOf(10))
+            .setNodeId(new NodeIdType("SPDR-SA1"))
+            .setTxDirection(getTxDirection())
+            .setRxDirection(getRxDirection());
+    }
+
+    public static ServiceZEndBuilder getServiceZEndBuild() {
+        return new ServiceZEndBuilder()
+            .setClli("NodeSC").setServiceFormat(ServiceFormat.Ethernet).setServiceRate(Uint32.valueOf(10))
+            .setNodeId(new NodeIdType("SPDR-SC1"))
+            .setTxDirection(getTxDirection())
+            .setRxDirection(getRxDirection());
+    }
+
+    private static TxDirection getTxDirection() {
+        return new TxDirectionBuilder().setPort(new PortBuilder().setPortDeviceName("device name")
+            .setPortName("port name").setPortRack("port rack").setPortShelf("port shelf")
+            .setPortSlot("port slot").setPortSubSlot("port subslot").setPortType("port type").build())
+            .setLgx(new LgxBuilder().setLgxDeviceName("lgx device name").setLgxPortName("lgx port name")
+                .setLgxPortRack("lgx port rack").setLgxPortShelf("lgx port shelf").build())
+            .build();
+    }
+
+    private static RxDirection getRxDirection() {
+        return new RxDirectionBuilder()
+            .setPort(new PortBuilder().setPortDeviceName("device name").setPortName("port name")
+                .setPortRack("port rack").setPortShelf("port shelf").setPortSlot("port slot")
+                .setPortSubSlot("port subslot").setPortType("port type").build())
+            .setLgx(new LgxBuilder().setLgxDeviceName("lgx device name")
+                .setLgxPortName("lgx port name").setLgxPortRack("lgx port rack")
+                .setLgxPortShelf("lgx port shelf").build())
+            .build();
+    }
+
+    public static Map<ConnectivityServiceKey, ConnectivityService> createConnService() {
+        EndPoint endPoint1 = getEndPoint1Builder().build();
+        EndPoint endPoint2 = getEndPoint2Builder().build();
+
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint
+            endPoint11 = new org.opendaylight.yang.gen.v1.urn
+                .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointBuilder(endPoint1).build();
+
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint
+            endPoint12 = new org.opendaylight.yang.gen.v1.urn
+                .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointBuilder(endPoint2).build();
+
+        Map<org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey,
+            org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPoint>
+                endPointMap = new HashMap<>();
+        endPointMap.put(endPoint11.key(), endPoint11);
+        endPointMap.put(endPoint12.key(), endPoint12);
+
+        Map<ConnectionKey, Connection> connectionMap = new HashMap<>();
+        Connection connection = new ConnectionBuilder().setConnectionUuid(new Uuid(UUID.randomUUID().toString()))
+            .build();
+        connectionMap.put(connection.key(), connection);
+
+        org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.Name name =
+            new org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.global._class.NameBuilder()
+                .setValueName("Connectivity Service Name").setValue("service 1")
+                .build();
+        ConnectivityService connServ = new ConnectivityServiceBuilder()
+            .setAdministrativeState(AdministrativeState.LOCKED)
+            .setOperationalState(OperationalState.DISABLED)
+            .setLifecycleState(LifecycleState.PLANNED)
+            .setUuid(new Uuid(UUID.nameUUIDFromBytes("service 1".getBytes(StandardCharsets.UTF_8)).toString()))
+            .setServiceLayer(LayerProtocolName.DSR)
+            .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY)
+            .setConnectivityDirection(ForwardingDirection.BIDIRECTIONAL)
+            .setName(Map.of(name.key(), name))
+            .setConnection(connectionMap)
+            .setEndPoint(endPointMap)
+            .build();
+        Map<ConnectivityServiceKey, ConnectivityService> connMap = new HashMap<>();
+        connMap.put(connServ.key(), connServ);
+        return connMap;
+    }
+
+    public static DeleteConnectivityServiceInput buildConnServiceDeleteInput1() {
+        return new DeleteConnectivityServiceInputBuilder()
+            .setServiceIdOrName("random-service").build();
+    }
+
+    private TapiConnectivityDataUtils() {
+    }
+}
index 7448329d328b7443be02d33ab350a5e1da2b00f3..32cbbf19ed9acf8bcda4db2331f854b94fa0bef3 100644 (file)
@@ -8,6 +8,17 @@
 
 package org.opendaylight.transportpce.tapi.utils;
 
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointDetailsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointListInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.GetServiceInterfacePointListInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.Uuid;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetLinkDetailsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeDetailsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsInput;
+import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetNodeEdgePointDetailsInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsInput;
 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.GetTopologyDetailsInputBuilder;
 
@@ -23,7 +34,39 @@ public final class TapiTopologyDataUtils {
         return builtInput.build();
     }
 
-    private TapiTopologyDataUtils() {
+    public static GetNodeDetailsInput buildGetNodeDetailsInput(String topoName, String nodeName) {
+        GetNodeDetailsInputBuilder builtInput = new GetNodeDetailsInputBuilder();
+        builtInput.setTopologyIdOrName(topoName);
+        builtInput.setNodeIdOrName(nodeName);
+        return builtInput.build();
+    }
+
+    public static GetLinkDetailsInput buildGetLinkDetailsInput(String topoName, String linkName) {
+        GetLinkDetailsInputBuilder builtInput = new GetLinkDetailsInputBuilder();
+        builtInput.setTopologyIdOrName(topoName);
+        builtInput.setLinkIdOrName(linkName);
+        return builtInput.build();
+    }
+
+    public static GetServiceInterfacePointListInput buildServiceInterfacePointListInput() {
+        return new GetServiceInterfacePointListInputBuilder().build();
     }
 
+    public static GetServiceInterfacePointDetailsInput buildGetServiceInterfacePointDetailsInput(Uuid sipUuid) {
+        GetServiceInterfacePointDetailsInputBuilder builtInput = new GetServiceInterfacePointDetailsInputBuilder();
+        builtInput.setSipIdOrName(sipUuid.getValue());
+        return builtInput.build();
+    }
+
+    public static GetNodeEdgePointDetailsInput buildGetNodeEdgePointDetailsInput(String topoName,
+                                                                                 String nodeName, String onepName) {
+        GetNodeEdgePointDetailsInputBuilder builtInput = new GetNodeEdgePointDetailsInputBuilder();
+        builtInput.setTopologyIdOrName(topoName);
+        builtInput.setNodeIdOrName(nodeName);
+        builtInput.setEpIdOrName(onepName);
+        return builtInput.build();
+    }
+
+    private TapiTopologyDataUtils() {
+    }
 }
index fe2510a805392160c5c23fa5398d83eba720fc9f..cf73cfa15159f2ca0799c8c89e8a7f4f9242312a 100644 (file)
@@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <parent>
     <groupId>org.opendaylight.mdsal</groupId>
     <artifactId>binding-parent</artifactId>
-    <version>8.0.5</version>
+    <version>8.0.7</version>
     <relativePath/>
   </parent>
 
index 5d2da04d6c183ca71d68552db946ee551c750ce8..b04d0fbee7d910dbfd81d31fd387d0bfd7d9cfba 100644 (file)
@@ -12,7 +12,7 @@
     <parent>
         <groupId>org.opendaylight.mdsal</groupId>
         <artifactId>binding-parent</artifactId>
-        <version>8.0.5</version>
+        <version>8.0.7</version>
         <relativePath />
     </parent>
 
@@ -25,7 +25,7 @@
             <dependency>
                 <groupId>org.opendaylight.netconf</groupId>
                 <artifactId>netconf-artifacts</artifactId>
-                <version>2.0.5</version>
+                <version>2.0.7</version>
                 <scope>import</scope>
                 <type>pom</type>
             </dependency>
diff --git a/tests/transportpce_tests/2.2.1/test12_tapi_full_multi_layer.py b/tests/transportpce_tests/2.2.1/test12_tapi_full_multi_layer.py
new file mode 100644 (file)
index 0000000..15af6f3
--- /dev/null
@@ -0,0 +1,482 @@
+#!/usr/bin/env python
+
+##############################################################################
+# Copyright (c) 2021 Orange, Inc. and others.  All rights reserved.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+# pylint: disable=no-member
+# pylint: disable=too-many-public-methods
+
+import os
+import unittest
+import time
+import requests
+import sys
+sys.path.append('transportpce_tests/common/')
+import test_utils
+
+
+class TransportPCEtesting(unittest.TestCase):
+
+    processes = None
+    WAITING = 20  # nominal value is 300
+    NODE_VERSION = '2.2.1'
+
+    cr_serv_sample_data = {
+        "input": {
+            "end-point": [
+                {
+                    "layer-protocol-name": "PHOTONIC_MEDIA",
+                    "service-interface-point": {
+                        "service-interface-point-uuid": "b1a0d883-32b8-3b0b-93d6-7ed074f6f107"
+                },
+                    "administrative-state": "UNLOCKED",
+                    "operational-state": "ENABLED",
+                    "direction": "BIDIRECTIONAL",
+                    "role": "SYMMETRIC",
+                    "protection-role": "WORK",
+                    "local-id": "SPDR-SA1-XPDR1",
+                    "name": [
+                        {
+                            "value-name": "OpenROADM node id",
+                            "value": "SPDR-SA1-XPDR1"
+                        }
+                    ]
+                },
+                {
+                    "layer-protocol-name": "PHOTONIC_MEDIA",
+                    "service-interface-point": {
+                        "service-interface-point-uuid": "d1d6305e-179b-346f-b02d-8260aebe1ce8"
+                },
+                    "administrative-state": "UNLOCKED",
+                    "operational-state": "ENABLED",
+                    "direction": "BIDIRECTIONAL",
+                    "role": "SYMMETRIC",
+                    "protection-role": "WORK",
+                    "local-id": "SPDR-SC1-XPDR1",
+                    "name": [
+                        {
+                            "value-name": "OpenROADM node id",
+                            "value": "SPDR-SC1-XPDR1"
+                        }
+                    ]
+                }
+            ],
+            "connectivity-constraint": {
+                "service-layer": "PHOTONIC_MEDIA",
+                "service-type": "POINT_TO_POINT_CONNECTIVITY",
+                "service-level": "Some service-level",
+                "requested-capacity": {
+                    "total-size": {
+                        "value": "100",
+                        "unit": "GB"
+                    }
+                }
+            },
+            "state": "Some state"}}
+
+    @classmethod
+    def setUpClass(cls):
+        cls.init_failed = False
+        os.environ['JAVA_MIN_MEM'] = '1024M'
+        os.environ['JAVA_MAX_MEM'] = '4096M'
+        cls.processes = test_utils.start_tpce()
+        # TAPI feature is not installed by default in Karaf
+        if "USE_LIGHTY" not in os.environ or os.environ['USE_LIGHTY'] != 'True':
+            print("installing tapi feature...")
+            result = test_utils.install_karaf_feature("odl-transportpce-tapi")
+            if result.returncode != 0:
+                cls.init_failed = True
+            print("Restarting OpenDaylight...")
+            test_utils.shutdown_process(cls.processes[0])
+            cls.processes[0] = test_utils.start_karaf()
+            test_utils.process_list[0] = cls.processes[0]
+            cls.init_failed = not test_utils.wait_until_log_contains(
+                test_utils.KARAF_LOG, test_utils.KARAF_OK_START_MSG, time_to_wait=60)
+        if cls.init_failed:
+            print("tapi installation feature failed...")
+            test_utils.shutdown_process(cls.processes[0])
+            sys.exit(2)
+        cls.processes = test_utils.start_sims([('spdra', cls.NODE_VERSION),
+                                               ('roadma', cls.NODE_VERSION),
+                                               ('roadmc', cls.NODE_VERSION),
+                                               ('spdrc', cls.NODE_VERSION)])
+
+    @classmethod
+    def tearDownClass(cls):
+        # pylint: disable=not-an-iterable
+        for process in cls.processes:
+            test_utils.shutdown_process(process)
+        print("all processes killed")
+
+    def setUp(self):
+        time.sleep(5)
+
+    def test_01_connect_spdrA(self):
+        response = test_utils.mount_device("SPDR-SA1", ('spdra', self.NODE_VERSION))
+        self.assertEqual(response.status_code,
+                         requests.codes.created, test_utils.CODE_SHOULD_BE_201)
+
+    def test_02_connect_spdrC(self):
+        response = test_utils.mount_device("SPDR-SC1", ('spdrc', self.NODE_VERSION))
+        self.assertEqual(response.status_code,
+                         requests.codes.created, test_utils.CODE_SHOULD_BE_201)
+
+    def test_03_connect_rdmA(self):
+        response = test_utils.mount_device("ROADM-A1", ('roadma', self.NODE_VERSION))
+        self.assertEqual(response.status_code,
+                         requests.codes.created, test_utils.CODE_SHOULD_BE_201)
+
+    def test_04_connect_rdmC(self):
+        response = test_utils.mount_device("ROADM-C1", ('roadmc', self.NODE_VERSION))
+        self.assertEqual(response.status_code,
+                         requests.codes.created, test_utils.CODE_SHOULD_BE_201)
+
+    def test_05_connect_sprdA_1_N1_to_roadmA_PP1(self):
+        response = test_utils.connect_xpdr_to_rdm_request("SPDR-SA1", "1", "1",
+                                                          "ROADM-A1", "1", "SRG1-PP1-TXRX")
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Xponder Roadm Link created successfully',
+                      res["output"]["result"])
+        time.sleep(2)
+
+    def test_06_connect_roadmA_PP1_to_spdrA_1_N1(self):
+        response = test_utils.connect_rdm_to_xpdr_request("SPDR-SA1", "1", "1",
+                                                          "ROADM-A1", "1", "SRG1-PP1-TXRX")
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Roadm Xponder links created successfully',
+                      res["output"]["result"])
+        time.sleep(2)
+
+    def test_07_connect_sprdC_1_N1_to_roadmC_PP1(self):
+        response = test_utils.connect_xpdr_to_rdm_request("SPDR-SC1", "1", "1",
+                                                          "ROADM-C1", "1", "SRG1-PP1-TXRX")
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Xponder Roadm Link created successfully',
+                      res["output"]["result"])
+        time.sleep(2)
+
+    def test_08_connect_roadmC_PP1_to_spdrC_1_N1(self):
+        response = test_utils.connect_rdm_to_xpdr_request("SPDR-SC1", "1", "1",
+                                                          "ROADM-C1", "1", "SRG1-PP1-TXRX")
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertIn('Roadm Xponder links created successfully',
+                      res["output"]["result"])
+        time.sleep(2)
+
+    def test_09_add_omsAttributes_ROADMA_ROADMC(self):
+        # Config ROADMA-ROADMC oms-attributes
+        data = {"span": {
+            "auto-spanloss": "true",
+            "spanloss-base": 11.4,
+            "spanloss-current": 12,
+            "engineered-spanloss": 12.2,
+            "link-concatenation": [{
+                "SRLG-Id": 0,
+                "fiber-type": "smf",
+                "SRLG-length": 100000,
+                "pmd": 0.5}]}}
+        response = test_utils.add_oms_attr_request(
+            "ROADM-A1-DEG2-DEG2-TTP-TXRXtoROADM-C1-DEG1-DEG1-TTP-TXRX", data)
+        self.assertEqual(response.status_code, requests.codes.created)
+        time.sleep(2)
+
+    def test_10_add_omsAttributes_ROADMC_ROADMA(self):
+        # Config ROADMC-ROADMA oms-attributes
+        data = {"span": {
+            "auto-spanloss": "true",
+            "spanloss-base": 11.4,
+            "spanloss-current": 12,
+            "engineered-spanloss": 12.2,
+            "link-concatenation": [{
+                "SRLG-Id": 0,
+                "fiber-type": "smf",
+                "SRLG-length": 100000,
+                "pmd": 0.5}]}}
+        response = test_utils.add_oms_attr_request(
+            "ROADM-C1-DEG1-DEG1-TTP-TXRXtoROADM-A1-DEG2-DEG2-TTP-TXRX", data)
+        self.assertEqual(response.status_code, requests.codes.created)
+        time.sleep(2)
+
+    def test_11_check_otn_topology(self):
+        response = test_utils.get_otn_topo_request()
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        nbNode = len(res['network'][0]['node'])
+        self.assertEqual(nbNode, 6, 'There should be 6 otn nodes')
+        self.assertNotIn('ietf-network-topology:link', res['network'][0])
+        time.sleep(2)
+
+    def test_12_check_openroadm_topology(self):
+        response = test_utils.get_ordm_topo_request("")
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        nbNode = len(res['network'][0]['node'])
+        nbLink = len(res['network'][0]['ietf-network-topology:link'])
+        self.assertEqual(nbNode, 13, 'There should be 13 openroadm nodes')
+        self.assertEqual(nbLink, 22, 'There should be 22 openroadm links')
+        time.sleep(2)
+
+    def test_13_get_tapi_topology_details(self):
+        response = test_utils.tapi_get_topology_details_request(
+            "T0 - Full Multi-layer topology")
+        time.sleep(2)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        nbNode = len(res['output']['topology']['node'])
+        nbLink = len(res['output']['topology']['link'])
+        self.assertEqual(nbNode, 14, 'There should be 14 TAPI nodes')
+        self.assertEqual(nbLink, 13, 'There should be 13 TAPI links')
+        time.sleep(2)
+
+    def test_14_check_sip_details(self):
+        response = test_utils.tapi_get_sip_details_request()
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        nbSip = len(res['output']['sip'])
+        self.assertEqual(nbSip, 60, 'There should be 60 service interface point')
+        time.sleep(2)
+
+# test create connectivity service from spdrA to spdrC for Photonic_media
+    def test_15_create_connectivity_service_PhotonicMedia(self):
+        response = test_utils.tapi_create_connectivity_request(self.cr_serv_sample_data)
+        time.sleep(self.WAITING)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        global service_pm_uuid
+        service_pm_uuid = res['output']['service']['uuid']
+        print("photonic media service uuid : {}".format(res['output']['service']['uuid']))
+
+        input_dict_1 = {'administrative-state': 'LOCKED',
+            'lifecycle-state': 'PLANNED',
+            'operational-state': 'DISABLED',
+            'service-type': 'POINT_TO_POINT_CONNECTIVITY',
+            'service-layer': 'PHOTONIC_MEDIA',
+            'connectivity-direction': 'BIDIRECTIONAL'
+                        }
+        input_dict_2 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SC1-XPDR1'}
+        input_dict_3 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SA1-XPDR1'}
+
+        self.assertDictEqual(dict(input_dict_1, **res['output']['service']),
+                             res['output']['service'])
+        self.assertDictEqual(dict(input_dict_2, **res['output']['service']['end-point'][0]['name'][0]),
+                             res['output']['service']['end-point'][0]['name'][0])
+        self.assertDictEqual(dict(input_dict_3, **res['output']['service']['end-point'][1]['name'][0]),
+                             res['output']['service']['end-point'][1]['name'][0])
+        time.sleep(self.WAITING)
+
+    def test_16_get_service_PhotonicMedia(self):
+        response = test_utils.get_service_list_request(
+            "services/"+ str(service_pm_uuid))
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertEqual(
+            res['services'][0]['administrative-state'], 'inService')
+        self.assertEqual(
+            res['services'][0]['service-name'], service_pm_uuid)
+        self.assertEqual(
+            res['services'][0]['connection-type'], 'infrastructure')
+        self.assertEqual(
+            res['services'][0]['lifecycle-state'], 'planned')
+        time.sleep(2)
+
+# test create connectivity service from spdrA to spdrC for odu
+    def test_17_create_connectivity_service_ODU(self):
+        self.cr_serv_sample_data["input"]["end-point"][0]["layer-protocol-name"] = "ODU"
+        self.cr_serv_sample_data["input"]["end-point"][0]["service-interface-point"]["service-interface-point-uuid"] = "eecbfa6e-57ab-3651-9606-c22c8ce73f18"
+        self.cr_serv_sample_data["input"]["end-point"][1]["layer-protocol-name"] = "ODU"
+        self.cr_serv_sample_data["input"]["end-point"][1]["service-interface-point"]["service-interface-point-uuid"] = "31f83b1f-29b2-3a8e-af9b-6423dbc5aa22"
+        self.cr_serv_sample_data["input"]["connectivity-constraint"]["service-layer"] = "ODU"
+
+        response = test_utils.tapi_create_connectivity_request(self.cr_serv_sample_data)
+        time.sleep(self.WAITING)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        global service_odu_uuid
+        service_odu_uuid = res['output']['service']['uuid']
+        print("odu service uuid : {}".format(res['output']['service']['uuid']))
+
+        input_dict_1 = {'administrative-state': 'LOCKED',
+            'lifecycle-state': 'PLANNED',
+            'operational-state': 'DISABLED',
+            'service-type': 'POINT_TO_POINT_CONNECTIVITY',
+            'service-layer': 'ODU',
+            'connectivity-direction': 'BIDIRECTIONAL'
+                        }
+        input_dict_2 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SC1-XPDR1'}
+        input_dict_3 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SA1-XPDR1'}
+
+        self.assertDictEqual(dict(input_dict_1, **res['output']['service']),
+                             res['output']['service'])
+        self.assertDictEqual(dict(input_dict_2, **res['output']['service']['end-point'][0]['name'][0]),
+                             res['output']['service']['end-point'][0]['name'][0])
+        self.assertDictEqual(dict(input_dict_3, **res['output']['service']['end-point'][1]['name'][0]),
+                             res['output']['service']['end-point'][1]['name'][0])
+        time.sleep(self.WAITING)
+
+    def test_18_get_service_ODU(self):
+        response = test_utils.get_service_list_request(
+            "services/"+ str(service_odu_uuid))
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertEqual(
+            res['services'][0]['administrative-state'], 'inService')
+        self.assertEqual(
+            res['services'][0]['service-name'], service_odu_uuid)
+        self.assertEqual(
+            res['services'][0]['connection-type'], 'infrastructure')
+        self.assertEqual(
+            res['services'][0]['lifecycle-state'], 'planned')
+        time.sleep(2)
+
+# test create connectivity service from spdrA to spdrC for dsr
+    def test_19_create_connectivity_service_DSR(self):
+        self.cr_serv_sample_data["input"]["end-point"][0]["layer-protocol-name"] = "DSR"
+        self.cr_serv_sample_data["input"]["end-point"][0]["service-interface-point"]["service-interface-point-uuid"] = "c14797a0-adcc-3875-a1fe-df8949d1a2d7"
+        self.cr_serv_sample_data["input"]["end-point"][1]["layer-protocol-name"] = "DSR"
+        self.cr_serv_sample_data["input"]["end-point"][1]["service-interface-point"]["service-interface-point-uuid"] = "25812ef2-625d-3bf8-af55-5e93946d1c22"
+        self.cr_serv_sample_data["input"]["connectivity-constraint"]["service-layer"] = "DSR"
+        self.cr_serv_sample_data["input"]["connectivity-constraint"]["requested-capacity"]["total-size"]["value"] = "10"
+
+        response = test_utils.tapi_create_connectivity_request(self.cr_serv_sample_data)
+        time.sleep(self.WAITING)
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        global service_dsr_uuid
+        service_dsr_uuid = res['output']['service']['uuid']
+        print("dsr service uuid : {}".format(res['output']['service']['uuid']))
+
+        input_dict_1 = {'administrative-state': 'LOCKED',
+            'lifecycle-state': 'PLANNED',
+            'operational-state': 'DISABLED',
+            'service-type': 'POINT_TO_POINT_CONNECTIVITY',
+            'service-layer': 'DSR',
+            'connectivity-direction': 'BIDIRECTIONAL'
+                        }
+        input_dict_2 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SC1-XPDR1'}
+        input_dict_3 = {'value-name': 'OpenROADM node id',
+                        'value': 'SPDR-SA1-XPDR1'}
+
+        self.assertDictEqual(dict(input_dict_1,
+                                  **res['output']['service']),
+                             res['output']['service'])
+        self.assertDictEqual(dict(input_dict_2,
+                                  **res['output']['service']['end-point'][0]['name'][0]),
+                             res['output']['service']['end-point'][0]['name'][0])
+        self.assertDictEqual(dict(input_dict_3,
+                                  **res['output']['service']['end-point'][1]['name'][0]),
+                             res['output']['service']['end-point'][1]['name'][0])
+        time.sleep(self.WAITING)
+
+    def test_20_get_service_DSR(self):
+        response = test_utils.get_service_list_request(
+            "services/"+ str(service_dsr_uuid))
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        self.assertEqual(
+            res['services'][0]['administrative-state'], 'inService')
+        self.assertEqual(
+            res['services'][0]['service-name'], service_dsr_uuid)
+        self.assertEqual(
+            res['services'][0]['connection-type'], 'service')
+        self.assertEqual(
+            res['services'][0]['lifecycle-state'], 'planned')
+        time.sleep(2)
+
+    def test_21_get_connectivity_service_list(self):
+        response = test_utils.tapi_get_service_list_request()
+        self.assertEqual(response.status_code, requests.codes.ok)
+        res = response.json()
+        liste_service = res['output']['service']
+        for ele in liste_service:
+            if ele['uuid'] == service_pm_uuid:
+                self.assertEqual(ele['operational-state'], 'ENABLED')
+                self.assertEqual(ele['service-layer'], 'PHOTONIC_MEDIA')
+                nbconnection = len(ele['connection'])
+                self.assertEqual(nbconnection, 9, 'There should be 9 connections')
+            elif ele['uuid'] == service_odu_uuid:
+                self.assertEqual(ele['operational-state'], 'ENABLED')
+                self.assertEqual(ele['service-layer'], 'ODU')
+                nbconnection = len(ele['connection'])
+                self.assertEqual(nbconnection, 3, 'There should be 3 connections')
+            elif ele['uuid'] == service_dsr_uuid:
+                self.assertEqual(ele['operational-state'], 'ENABLED')
+                self.assertEqual(ele['service-layer'], 'DSR')
+                nbconnection = len(ele['connection'])
+                self.assertEqual(nbconnection, 1, 'There should be 1 connection')
+            else:
+                self.fail("get connectivity service failed")
+        time.sleep(2)
+
+    def test_22_delete_connectivity_service_DSR(self):
+       response = test_utils.tapi_delete_connectivity_request(service_dsr_uuid)
+       self.assertEqual(response.status_code, requests.codes.no_content)
+       time.sleep(self.WAITING)
+
+    def test_23_delete_connectivity_service_ODU(self):
+        response = test_utils.tapi_delete_connectivity_request(service_odu_uuid)
+        self.assertEqual(response.status_code, requests.codes.no_content)
+        time.sleep(self.WAITING)
+
+    def test_24_delete_connectivity_service_PhotonicMedia(self):
+        response = test_utils.tapi_delete_connectivity_request(service_pm_uuid)
+        self.assertEqual(response.status_code, requests.codes.no_content)
+        time.sleep(self.WAITING)
+
+    def test_25_get_no_tapi_services(self):
+        response = test_utils.tapi_get_service_list_request()
+        res = response.json()
+        self.assertIn(
+            {"error-type": "rpc", "error-tag": "operation-failed",
+             "error-message": "No services exist in datastore",
+             "error-info": "<severity>error</severity>"},
+            res['errors']['error'])
+        time.sleep(2)
+
+    def test_26_get_no_openroadm_services(self):
+        response = test_utils.get_service_list_request("")
+        self.assertEqual(response.status_code, requests.codes.conflict)
+        res = response.json()
+        self.assertIn(
+            {"error-type": "application", "error-tag": "data-missing",
+             "error-message": "Request could not be completed because the relevant data model content does not exist"},
+            res['errors']['error'])
+        time.sleep(2)
+
+    def test_27_disconnect_spdrA(self):
+        response = test_utils.unmount_device("SPDR-SA1")
+        self.assertEqual(response.status_code, requests.codes.ok,
+                         test_utils.CODE_SHOULD_BE_200)
+
+    def test_28_disconnect_spdrC(self):
+        response = test_utils.unmount_device("SPDR-SC1")
+        self.assertEqual(response.status_code, requests.codes.ok,
+                         test_utils.CODE_SHOULD_BE_200)
+
+    def test_29_disconnect_roadmA(self):
+        response = test_utils.unmount_device("ROADM-A1")
+        self.assertEqual(response.status_code, requests.codes.ok,
+                         test_utils.CODE_SHOULD_BE_200)
+
+    def test_30_disconnect_roadmC(self):
+        response = test_utils.unmount_device("ROADM-C1")
+        self.assertEqual(response.status_code, requests.codes.ok,
+                         test_utils.CODE_SHOULD_BE_200)
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
index 136991f444e90232cc44efba8cb782dad34d9cf0..46bf27a676ddb1b9a0e1978c9b7b4a3dbb0cd2ce 100644 (file)
@@ -48,9 +48,15 @@ URL_SERV_CREATE = "{}/operations/org-openroadm-service:service-create"
 URL_SERV_DELETE = "{}/operations/org-openroadm-service:service-delete"
 URL_SERVICE_PATH = "{}/operations/transportpce-device-renderer:service-path"
 URL_OTN_SERVICE_PATH = "{}/operations/transportpce-device-renderer:otn-service-path"
+URL_TAPI_CREATE_CONNECTIVITY = "{}/operations/tapi-connectivity:create-connectivity-service"
+URL_TAPI_DELETE_CONNECTIVITY = "{}/operations/tapi-connectivity:delete-connectivity-service"
 URL_CREATE_OTS_OMS = "{}/operations/transportpce-device-renderer:create-ots-oms"
 URL_PATH_COMPUTATION_REQUEST = "{}/operations/transportpce-pce:path-computation-request"
 URL_FULL_PORTMAPPING = "{}/config/transportpce-portmapping:network"
+URL_TAPI_TOPOLOGY_DETAILS = "{}/operations/tapi-topology:get-topology-details"
+URL_TAPI_NODE_DETAILS = "{}/operations/tapi-topology:get-node-details"
+URL_TAPI_SIP_LIST = "{}/operations/tapi-common:get-service-interface-point-list"
+URL_TAPI_SERVICE_LIST = "{}/operations/tapi-connectivity:get-connectivity-service-list"
 
 TYPE_APPLICATION_JSON = {'Content-Type': 'application/json', 'Accept': 'application/json'}
 TYPE_APPLICATION_XML = {'Content-Type': 'application/xml', 'Accept': 'application/xml'}
@@ -387,7 +393,6 @@ def service_delete_request(servicename: str,
             "tail-retention": "no"}}}
     return post_request(URL_SERV_DELETE, attr)
 
-
 def service_path_request(operation: str, servicename: str, wavenumber: str, nodes, centerfreq: str,
                          slotwidth: int, minfreq: float, maxfreq: float, lowerslotnumber: int,
                          higherslotnumber: int):
@@ -441,6 +446,33 @@ def path_computation_request(requestid: str, servicename: str, serviceaend, serv
         attr.update(other_attr)
     return post_request(URL_PATH_COMPUTATION_REQUEST, {"input": attr})
 
+def tapi_create_connectivity_request(topologyidorname):
+    return post_request(URL_TAPI_CREATE_CONNECTIVITY, topologyidorname)
+
+def tapi_delete_connectivity_request(serviceidorname):
+    attr = {
+        "input": {
+            "service-id-or-name": serviceidorname}}
+    return post_request(URL_TAPI_DELETE_CONNECTIVITY , attr)
+
+def tapi_get_topology_details_request(topologyidorname):
+    attr = {
+        "input": {
+            "topology-id-or-name": topologyidorname}}
+    return post_request(URL_TAPI_TOPOLOGY_DETAILS , attr)
+
+def tapi_get_node_details_request(topologyidorname, nodeidorname):
+    attr = {
+        "input": {
+            "topology-id-or-name": topologyidorname,
+            "node-id-or-name": nodeidorname}}
+    return post_request(URL_TAPI_NODE_DETAILS, attr)
+
+def tapi_get_sip_details_request():
+    return post_request(URL_TAPI_SIP_LIST, "")
+
+def tapi_get_service_list_request():
+    return post_request(URL_TAPI_SERVICE_LIST, "")
 
 def shutdown_process(process):
     if process is not None: