From 98ba9741bc45b3770f82465e241d64b536bf7341 Mon Sep 17 00:00:00 2001 From: Javier Errea Date: Mon, 2 Aug 2021 14:27:01 +0200 Subject: [PATCH] Update TAPI Connectivity Service on port change - Update TAPI connections & connectivity service on topology update notification - Update TAPI supported connectivity services (infrastructure) - Update CEPs of connections - Add tapiNetworkModelListener to TapiProvider class - Refactor TAPI connection creation to include lower connections - Add method for sending a notification on a TAPI topology update - Refactor differentiation between SWITCH and MUXPDR connectivity service creation - Refactor connectivity service creation when there is more than 1 ROADM between end points of the service JIRA: TRNSPRTPCE-466 Change-Id: I95f7dfba0d9d01c48e60538b215890265d48cf19 Signed-off-by: errea --- .../tpce/module/TransportPCEImpl.java | 26 +- .../tapi/TapiStringConstants.java | 2 + .../tapi/connectivity/ConnectivityUtils.java | 388 ++++++++------ .../connectivity/TapiConnectivityImpl.java | 1 + .../transportpce/tapi/impl/TapiProvider.java | 10 +- .../TapiNetworkModelListenerImpl.java | 483 ++++++++++++++++++ .../tapi/listeners/TapiPceListenerImpl.java | 386 ++++++++------ .../topology/TapiNetworkModelServiceImpl.java | 64 ++- .../OSGI-INF/blueprint/tapi-blueprint.xml | 9 + .../tapi/provider/TapiProviderTest.java | 6 +- 10 files changed, 1033 insertions(+), 342 deletions(-) create mode 100644 tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiNetworkModelListenerImpl.java diff --git a/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java b/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java index ef88bf77e..37a766d4f 100644 --- a/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java +++ b/lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java @@ -80,6 +80,7 @@ import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOper import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperationsImpl; import org.opendaylight.transportpce.tapi.R2RTapiLinkDiscovery; import org.opendaylight.transportpce.tapi.impl.TapiProvider; +import org.opendaylight.transportpce.tapi.listeners.TapiNetworkModelListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl; @@ -212,26 +213,29 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP LOG.info("Creating tapi beans ..."); TapiLink tapiLink = new TapiLink(networkTransaction); R2RTapiLinkDiscovery tapilinkDiscoveryImpl = new R2RTapiLinkDiscovery(networkTransaction, - deviceTransactionManager, tapiLink); + deviceTransactionManager, tapiLink); TapiRendererListenerImpl tapiRendererListenerImpl = new TapiRendererListenerImpl(lightyServices .getBindingDataBroker()); TapiPceListenerImpl tapiPceListenerImpl = new TapiPceListenerImpl(lightyServices.getBindingDataBroker()); - TapiServiceHandlerListenerImpl tapiServiceHandlerListener = new TapiServiceHandlerListenerImpl(lightyServices - .getBindingDataBroker()); + TapiServiceHandlerListenerImpl tapiServiceHandlerListener = new TapiServiceHandlerListenerImpl( + lightyServices.getBindingDataBroker()); TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl = new TapiNetworkUtilsImpl( networkTransaction, tapiLink); TapiNetworkModelService tapiNetworkModelService = new TapiNetworkModelServiceImpl( - tapilinkDiscoveryImpl, networkTransaction, tapiLink); + tapilinkDiscoveryImpl, networkTransaction, tapiLink, + lightyServices.getBindingNotificationPublishService()); TapiNetconfTopologyListener tapiNetConfTopologyListener = new TapiNetconfTopologyListener(tapiNetworkModelService); TapiOrLinkListener orLinkListener = new TapiOrLinkListener(tapiLink, networkTransaction); TapiPortMappingListener tapiPortMappingListener = - new TapiPortMappingListener(tapiNetworkModelService); + new TapiPortMappingListener(tapiNetworkModelService); + TapiNetworkModelListenerImpl tapiNetworkModelListenerImpl = + new TapiNetworkModelListenerImpl(networkTransaction); tapiProvider = initTapi(lightyServices, servicehandler, networkTransaction, serviceDataStoreOperations, - tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl, tapiPceListenerImpl, - tapiRendererListenerImpl, tapiServiceHandlerListener, lightyServices.getNotificationService(), - orLinkListener); + tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl, + tapiPceListenerImpl, tapiRendererListenerImpl, tapiServiceHandlerListener, + lightyServices.getNotificationService(), orLinkListener, tapiNetworkModelListenerImpl); } if (activateNbiNotification) { LOG.info("Creating nbi-notifications beans ..."); @@ -299,11 +303,13 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP TransportpceTapinetworkutilsService tapiNetworkutilsServiceImpl, TapiPceListenerImpl pceListenerImpl, TapiRendererListenerImpl rendererListenerImpl, TapiServiceHandlerListenerImpl serviceHandlerListenerImpl, - NotificationService notificationService, TapiOrLinkListener orLinkListener) { + NotificationService notificationService, TapiOrLinkListener orLinkListener, + TapiNetworkModelListenerImpl tapiNetworkModelListenerImpl) { return new TapiProvider(lightyServices.getBindingDataBroker(), lightyServices.getRpcProviderService(), servicehandler, serviceDataStoreOperations, new TapiListener(), networkTransactionService, tapiNetConfTopologyListener, tapiPortMappingListener, tapiNetworkutilsServiceImpl, pceListenerImpl, - rendererListenerImpl, serviceHandlerListenerImpl, notificationService, orLinkListener); + rendererListenerImpl, serviceHandlerListenerImpl, notificationService, orLinkListener, + tapiNetworkModelListenerImpl); } private RendererProvider initRenderer(LightyServices lightyServices, TransportpceOlmService olmPowerServiceRpc, diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/TapiStringConstants.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/TapiStringConstants.java index ffbb2d439..52e97af26 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/TapiStringConstants.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/TapiStringConstants.java @@ -42,6 +42,8 @@ public final class TapiStringConstants { public static final String JITTER_VALUE = "12345678"; public static final String WANDER_VALUE = "12345678"; public static final String QUEING_LATENCY_VALUE = "12345678"; + public static final String TAPI_CONNECTION_UPDATE_ERROR = "Could not update TAPI connections"; + public static final String TAPI_CONNECTION_READ_ERROR = "Could not read TAPI connection data"; private TapiStringConstants() { // hiding the default constructor diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/ConnectivityUtils.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/ConnectivityUtils.java index 392ae6d60..c88c5239c 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/ConnectivityUtils.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/ConnectivityUtils.java @@ -7,7 +7,7 @@ */ package org.opendaylight.transportpce.tapi.connectivity; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -119,7 +119,7 @@ import org.slf4j.LoggerFactory; public final class ConnectivityUtils { private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); private static final Logger LOG = LoggerFactory.getLogger(ConnectivityUtils.class); private final ServiceDataStoreOperations serviceDataStoreOperations; @@ -130,6 +130,9 @@ public final class ConnectivityUtils { org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionFullMap; // this variable is for complete connection objects private final NetworkTransactionService networkTransactionService; + private Connection topConnRdmRdm; + private Connection topConnXpdrXpdrPhtn; + private Connection topConnXpdrXpdrOdu; // TODO -> handle cases for which node id is ROADM-A1 and not ROADMA01 or XPDR-A1 and not XPDRA01 public ConnectivityUtils(ServiceDataStoreOperations serviceDataStoreOperations, @@ -140,6 +143,9 @@ public final class ConnectivityUtils { this.sipMap = sipMap; this.connectionFullMap = new HashMap<>(); this.networkTransactionService = networkTransactionService; + this.topConnRdmRdm = null; + this.topConnXpdrXpdrPhtn = null; + this.topConnXpdrXpdrOdu = null; } public static ServiceCreateInput buildServiceCreateInput(GenericServiceEndpoint sepA, GenericServiceEndpoint sepZ) { @@ -301,7 +307,7 @@ public final class ConnectivityUtils { .setAdministrativeState(AdministrativeState.UNLOCKED) .setOperationalState(OperationalState.ENABLED) .setLifecycleState(LifecycleState.INSTALLED) - .setUuid(new Uuid(UUID.nameUUIDFromBytes(service.getServiceName().getBytes(Charset.forName("UTF-8"))) + .setUuid(new Uuid(UUID.nameUUIDFromBytes(service.getServiceName().getBytes(StandardCharsets.UTF_8)) .toString())) .setServiceLayer(mapServiceLayer(serviceAEnd.getServiceFormat(), endPoint1, endPoint2)) .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY) @@ -336,7 +342,7 @@ public final class ConnectivityUtils { private OpenroadmNodeType getOpenroadmType(String nodeName) { LOG.info("Node name = {}", nodeName); Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",nodeName, TapiStringConstants.DSR)) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node tapiNode = this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid); if (tapiNode != null) { @@ -348,10 +354,10 @@ public final class ConnectivityUtils { private Map createConnectionsFromService( org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceAEnd - serviceAEnd, + serviceAEnd, org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceZEnd - serviceZEnd, - PathDescription pathDescription) { + serviceZEnd, + PathDescription pathDescription) { Map connectionServMap = new HashMap<>(); // build lists with ROADM nodes, XPDR/MUX/SWITCH nodes, ROADM DEG TTPs, ROADM SRG TTPs, XPDR CLIENT TTPs // and XPDR NETWORK TTPs (if any). From the path description. This will help to build the uuid of the CEPs @@ -364,7 +370,7 @@ public final class ConnectivityUtils { List rdmNodelist = new ArrayList<>(); List xpdrNodelist = new ArrayList<>(); for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream() - .sorted(Comparator.comparing(AToZ::getId)).collect(Collectors.toList())) { + .sorted((Comparator.comparing(atoz -> Integer.valueOf(atoz.getId())))).collect(Collectors.toList())) { resourceType = elem.getResource().getResource().implementedInterface().getSimpleName(); switch (resourceType) { case TapiStringConstants.TP: @@ -466,11 +472,16 @@ public final class ConnectivityUtils { // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist)); + this.topConnRdmRdm = null; break; case ODU: + // TODO: verify if this is correct // - XC Connection OTSi betwwen iODU and eODU of xpdr // - Top connection in the ODU layer, between xpdr eODU ports (?) - connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); + if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) { + connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrPhtn = null; + } break; case Ethernet: // Check if OC, OTU and ODU are created @@ -479,23 +490,26 @@ public final class ConnectivityUtils { connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist, edgeRoadm1, edgeRoadm2)); connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist)); + this.topConnRdmRdm = null; xpdrClientTplist = getAssociatedClientsPort(xpdrNetworkTplist); LOG.info("Associated client ports = {}", xpdrClientTplist); connectionServMap.putAll(createXpdrCepsAndConnectionsEth(xpdrClientTplist, xpdrNodelist, connectionServMap)); + this.topConnXpdrXpdrPhtn = null; } if (openroadmNodeType.equals(OpenroadmNodeType.SWITCH)) { // TODO: We create both ODU and DSR because there is no ODU service creation for the switch // - XC Connection OTSi betwwen iODU and eODU of xpdr // - Top connection in the ODU layer, between xpdr eODU ports (?) - connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrPhtn = null; } if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) { // TODO: OTN service but mux has 3 steps at rendering. Verify that things exist connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrOdu = null; } break; default: @@ -537,7 +551,7 @@ public final class ConnectivityUtils { // DSR top connection between edge xpdr CLIENT DSR org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR, - LayerProtocolName.DSR, xcMap); + LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connectionDsr.key(), connectionDsr); // DSR top connection that will be added to the service object @@ -598,7 +612,7 @@ public final class ConnectivityUtils { org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionOdu = createTopConnection(spcXpdr1, spcXpdr2, cepMapOdu, TapiStringConstants.E_ODU, - LayerProtocolName.ODU, xcMap); + LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrOdu); this.connectionFullMap.put(connectionOdu.key(), connectionOdu); // ODU top connection that will be added to the service object @@ -609,7 +623,7 @@ public final class ConnectivityUtils { org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR, - LayerProtocolName.DSR, xcMap); + LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connectionDsr.key(), connectionDsr); // DSR top connection that will be added to the service object @@ -649,12 +663,13 @@ public final class ConnectivityUtils { .get(xpdrNodelist.size() - 1))).findFirst().get(); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_ODU, - LayerProtocolName.ODU, xcMap); + LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connection.key(), connection); // ODU top connection that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); + this.topConnXpdrXpdrOdu = conn; return connServMap; } @@ -709,13 +724,13 @@ public final class ConnectivityUtils { .get(xpdrNodelist.size() - 1))).findFirst().get(); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_OTSI, - LayerProtocolName.PHOTONICMEDIA, xcMap); + LayerProtocolName.PHOTONICMEDIA, xcMap, this.topConnRdmRdm); this.connectionFullMap.put(connection.key(), connection); // OTSi top connection that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); - + this.topConnXpdrXpdrPhtn = conn; return connServMap; } @@ -724,106 +739,149 @@ public final class ConnectivityUtils { List rdmDegTplist, List rdmNodelist, String edgeRoadm1, String edgeRoadm2) { - // TODO: when the number of roadms between 2 SPDR/XPDR is more thatn 1, we need to refine this code - Map connServMap = new HashMap<>(); + // TODO: will need to check if things exist already or not Map cepMap = new HashMap<>(); - Map xcMap = new HashMap<>(); // create ceps and x connections within roadm + Map xcLowerMap = new HashMap<>(); for (String roadm : rdmNodelist) { LOG.info("Creating ceps and xc for roadm {}", roadm); - String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); - LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD); - // There should be only 1 AD and 1 DEG per roadm - // TODO photonic media model should be updated to have the corresponding CEPs. I will just create - // 3 different MC CEPs giving different IDs to show that they are different - // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs - // created in the topology creation - // add CEPs to the topology to the corresponding ONEP - ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1); - ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2); - ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3); - cepMap.put(adCep1.key(), adCep1); - cepMap.put(adCep2.key(), adCep2); - cepMap.put(adCep3.key(), adCep3); - - String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); - LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG); - - ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1); - ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2); - ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3); - cepMap.put(degCep1.key(), degCep1); - cepMap.put(degCep2.key(), degCep2); - cepMap.put(degCep3.key(), degCep3); - - LOG.info("Going to create cross connections for ROADM {}", roadm); - // Create X connections between MC and OTSi_MC for full map - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection1 = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC, - LayerProtocolName.PHOTONICMEDIA); - LOG.info("Cross connection 1 created = {}", connection1); - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection2 = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC, - LayerProtocolName.PHOTONICMEDIA); - LOG.info("Cross connection 2 created = {}", connection2); - this.connectionFullMap.put(connection1.key(), connection1); - this.connectionFullMap.put(connection2.key(), connection2); - - // Create X connections that will be added to the service object - LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); - LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); - - xcMap.put(conn1.key(), conn1); - xcMap.put(conn2.key(), conn2); - } - LOG.info("Going to create top connections betwee roadms"); - // create top connections between roadms: MC connections between AD MC CEPs of roadms - for (int i = 0; i < rdmNodelist.size(); i++) { - if (rdmNodelist.size() <= (i + 1)) { - LOG.info("Reached last roadm. No more MC connections"); - break; + if (roadm.equals(edgeRoadm1) || roadm.equals(edgeRoadm2)) { + LOG.info("EDGE ROADM, cross connections needed between SRG and DEG"); + String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD); + // There should be only 1 AD and 1 DEG per roadm + // TODO photonic media model should be updated to have the corresponding CEPs. I will just create + // 3 different MC CEPs giving different IDs to show that they are different + // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs + // created in the topology creation + // add CEPs to the topology to the corresponding ONEP + ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1); + ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2); + ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3); + cepMap.put(adCep1.key(), adCep1); + cepMap.put(adCep2.key(), adCep2); + cepMap.put(adCep3.key(), adCep3); + + String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG); + + ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1); + ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2); + ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3); + cepMap.put(degCep1.key(), degCep1); + cepMap.put(degCep2.key(), degCep2); + cepMap.put(degCep3.key(), degCep3); + + LOG.info("Going to create cross connections for ROADM {}", roadm); + // Create X connections between MC and OTSi_MC for full map + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection1 + = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC, + LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 1 created = {}", connection1.toString()); + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection2 + = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC, + LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 2 created = {}", connection2.toString()); + this.connectionFullMap.put(connection1.key(), connection1); + this.connectionFullMap.put(connection2.key(), connection2); + + // Create X connections that will be added to the service object + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); + + xcLowerMap.put(conn1.key(), conn1); + xcLowerMap.put(conn2.key(), conn2); + } else { + LOG.info("MIDDLE ROADM, cross connections needed between DEG and DEG"); + String spcRdmDEG1 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("Degree 1 port of ROADm {} = {}", roadm, spcRdmDEG1); + + ConnectionEndPoint deg1Cep1 = createCepRoadm(spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA, deg1Cep1); + ConnectionEndPoint deg1Cep2 = createCepRoadm(spcRdmDEG1, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.MC, deg1Cep2); + ConnectionEndPoint deg1Cep3 = createCepRoadm(spcRdmDEG1, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.OTSI_MC, deg1Cep3); + cepMap.put(deg1Cep1.key(), deg1Cep1); + cepMap.put(deg1Cep2.key(), deg1Cep2); + cepMap.put(deg1Cep3.key(), deg1Cep3); + + String spcRdmDEG2 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).skip(1).findFirst().get(); + LOG.info("Degree 2 port of ROADm {} = {}", roadm, spcRdmDEG2); + + ConnectionEndPoint deg2Cep1 = createCepRoadm(spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA, deg2Cep1); + ConnectionEndPoint deg2Cep2 = createCepRoadm(spcRdmDEG2, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.MC, deg2Cep2); + ConnectionEndPoint deg2Cep3 = createCepRoadm(spcRdmDEG2, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.OTSI_MC, deg2Cep3); + cepMap.put(deg2Cep1.key(), deg2Cep1); + cepMap.put(deg2Cep2.key(), deg2Cep2); + cepMap.put(deg2Cep3.key(), deg2Cep3); + + LOG.info("Going to create cross connections for ROADM {}", roadm); + // Create X connections between MC and OTSi_MC for full map + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection1 + = createXCBetweenCeps(deg1Cep2, deg2Cep2, spcRdmDEG1, spcRdmDEG2, + TapiStringConstants.MC, LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 1 created = {}", connection1.toString()); + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection2 + = createXCBetweenCeps(deg1Cep3, deg2Cep3, spcRdmDEG1, spcRdmDEG2, + TapiStringConstants.OTSI_MC, LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 2 created = {}", connection2.toString()); + this.connectionFullMap.put(connection1.key(), connection1); + this.connectionFullMap.put(connection2.key(), connection2); + + // Create X connections that will be added to the service object + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); + + xcLowerMap.put(conn1.key(), conn1); + xcLowerMap.put(conn2.key(), conn2); } - // Current roadm with roadm i + 1 --> MC - String roadm1 = rdmNodelist.get(i); - String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm1)).findFirst().get(); - String roadm2 = rdmNodelist.get(i + 1); - String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm2)).findFirst().get(); - LOG.info("Creating top connection from {} to {} between tps: {}-{}", roadm1, roadm2, spcRdmAD1, spcRdmAD2); - - // Create top connections between MC for full map - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC, - LayerProtocolName.PHOTONICMEDIA, xcMap); - this.connectionFullMap.put(connection.key(), connection); - LOG.info("Top connection created = {}", connection); - - // Create top connections that will be added to the service object - Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); - connServMap.put(conn.key(), conn); - LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); - xcMap.put(conn1.key(), conn1); } - - // OTSiMC top connection between edge roadms - LOG.info("Going to created top connection between OTSiMC"); + LOG.info("Going to create top connections between roadms"); String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().get(); String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().get(); + // MC top connection between edge roadms + LOG.info("Going to created top connection between MC"); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC, - LayerProtocolName.PHOTONICMEDIA, xcMap); + connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC, + LayerProtocolName.PHOTONICMEDIA, xcLowerMap, null); this.connectionFullMap.put(connection.key(), connection); - LOG.info("Top connection created = {}", connection); + LOG.info("Top connection created = {}", connection.toString()); + Map connServMap = new HashMap<>(); // OTSiMC top connections that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); + Map topLowerMap = new HashMap<>(); + topLowerMap.put(conn1.key(), conn1); + + // OTSiMC top connection between edge roadms + LOG.info("Going to created top connection between OTSiMC"); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection + connection1 = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC, + LayerProtocolName.PHOTONICMEDIA, topLowerMap, null); + this.connectionFullMap.put(connection1.key(), connection1); + LOG.info("Top connection created = {}", connection1.toString()); + + // OTSiMC top connections that will be added to the service object + Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + connServMap.put(conn2.key(), conn2); + this.topConnRdmRdm = conn2; return connServMap; } @@ -832,14 +890,14 @@ public final class ConnectivityUtils { Map cepMap, String qual, LayerProtocolName topPortocol, - Map xcMap) { + Map xcMap, Connection additionalLowerConn) { // find cep for each AD MC of roadm 1 and 2 LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual)); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep1 = cepMap.get(new org.opendaylight.yang.gen.v1.urn .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0], - qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qual, tp1.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString()))); LOG.info("ADCEP1 = {}", adCep1); org.opendaylight.yang.gen.v1.urn @@ -858,7 +916,7 @@ public final class ConnectivityUtils { cepMap.get(new org.opendaylight.yang.gen.v1.urn .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0], - qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qual, tp2.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString()))); LOG.info("ADCEP2 = {}", adCep2); org.opendaylight.yang.gen.v1.urn @@ -882,10 +940,14 @@ public final class ConnectivityUtils { .setValue(String.join("+", "TOP", tp1, tp2, qual)) .build(); // TODO: lower connection, supported link....... + if (additionalLowerConn != null) { + xcMap.putIfAbsent(new LowerConnectionKey(additionalLowerConn.getConnectionUuid()), + new LowerConnectionBuilder().setConnectionUuid(additionalLowerConn.getConnectionUuid()).build()); + } return new org.opendaylight.yang.gen.v1.urn .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual)) - .getBytes(Charset.forName("UTF-8"))).toString())) + .getBytes(StandardCharsets.UTF_8)).toString())) .setName(Map.of(connName.key(), connName)) .setConnectionEndPoint(ceps) .setOperationalState(OperationalState.ENABLED) @@ -939,7 +1001,7 @@ public final class ConnectivityUtils { return new org.opendaylight.yang.gen.v1.urn .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual)) - .getBytes(Charset.forName("UTF-8"))).toString())) + .getBytes(StandardCharsets.UTF_8)).toString())) .setName(Map.of(connName.key(), connName)) .setConnectionEndPoint(ceps) .setOperationalState(OperationalState.ENABLED) @@ -958,19 +1020,19 @@ public final class ConnectivityUtils { .build(); ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder() .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString())) .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0], - qualifier)).getBytes(Charset.forName("UTF-8"))) + qualifier)).getBytes(StandardCharsets.UTF_8)) .toString())) .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER - .getBytes(Charset.forName("UTF-8"))).toString())) + .getBytes(StandardCharsets.UTF_8)).toString())) .build(); // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...) // TODO: add parent ONEP?? ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString())) .setClientNodeEdgePoint(Map.of(cnep.key(), cnep)) .setName(Map.of(cepName.key(), cepName)) @@ -991,19 +1053,19 @@ public final class ConnectivityUtils { .build(); ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder() .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString())) .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0], - nodeLayer)).getBytes(Charset.forName("UTF-8"))) + nodeLayer)).getBytes(StandardCharsets.UTF_8)) .toString())) .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER - .getBytes(Charset.forName("UTF-8"))).toString())) + .getBytes(StandardCharsets.UTF_8)).toString())) .build(); // TODO: add augmentation with the corresponding cep-spec (i.e. MC, OTSiMC...) // TODO: add parent ONEP?? ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(StandardCharsets.UTF_8)) .toString())) .setClientNodeEdgePoint(Map.of(cnep.key(), cnep)) .setName(Map.of(cepName.key(), cepName)) @@ -1016,8 +1078,8 @@ public final class ConnectivityUtils { } private EndPoint mapServiceZEndPoint( - org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceZEnd - serviceZEnd, PathDescription pathDescription) { + org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceZEnd + serviceZEnd, PathDescription pathDescription) { EndPointBuilder endPointBuilder = new EndPointBuilder(); // 1. Service Format: ODU, OTU, ETH ServiceFormat serviceFormat = serviceZEnd.getServiceFormat(); @@ -1073,8 +1135,8 @@ public final class ConnectivityUtils { } private EndPoint mapServiceAEndPoint( - org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceAEnd - serviceAEnd, PathDescription pathDescription) { + org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceAEnd + serviceAEnd, PathDescription pathDescription) { EndPointBuilder endPointBuilder = new EndPointBuilder(); // 1. Service Format: ODU, OTU, ETH ServiceFormat serviceFormat = serviceAEnd.getServiceFormat(); @@ -1136,7 +1198,7 @@ public final class ConnectivityUtils { ZToA firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("0")).findFirst().get(); TerminationPoint tp = (TerminationPoint) firstElement.getResource().getResource(); Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) + tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(StandardCharsets.UTF_8)) .toString()); LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())); for (ServiceInterfacePoint sip:this.sipMap.values()) { @@ -1157,9 +1219,8 @@ public final class ConnectivityUtils { firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("2")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Network-Network ports --> iODU layer SIPs TODO --> updated to E_ODU - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.I_ODU, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.I_ODU, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_ODU, tp.getTpId())); break; @@ -1167,9 +1228,8 @@ public final class ConnectivityUtils { firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("2")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Network-Network ports --> iOTSi layer SIPs - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_OTSI, tp.getTpId())); break; @@ -1178,9 +1238,8 @@ public final class ConnectivityUtils { firstElement = mapztoa.values().stream().filter(ztoa -> ztoa.getId().equals("0")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Client-client ports --> DSR layer SIPs - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.DSR, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.DSR, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.DSR, tp.getTpId())); break; @@ -1211,7 +1270,7 @@ public final class ConnectivityUtils { LOG.info("First element of service path = {}", firstElement.getResource().getResource()); TerminationPoint tp = (TerminationPoint) firstElement.getResource().getResource(); Uuid sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) + tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())).getBytes(StandardCharsets.UTF_8)) .toString()); LOG.info("ROADM SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.MC, tp.getTpId())); @@ -1233,9 +1292,8 @@ public final class ConnectivityUtils { firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("2")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Network-Network ports --> iODU layer SIPs. TODO -> updated to eODU - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.I_ODU, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.I_ODU, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("ODU XPDR SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_ODU, tp.getTpId())); break; @@ -1243,9 +1301,8 @@ public final class ConnectivityUtils { firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("2")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Network-Network ports --> iOTSi layer SIPs - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.I_OTSI, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("OTU XPDR SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.I_OTSI, tp.getTpId())); break; @@ -1254,9 +1311,8 @@ public final class ConnectivityUtils { firstElement = mapatoz.values().stream().filter(atoz -> atoz.getId().equals("0")).findFirst().get(); tp = (TerminationPoint) firstElement.getResource().getResource(); // Client-client ports --> DSR layer SIPs - sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", - tp.getTpNodeId(), TapiStringConstants.DSR, tp.getTpId())).getBytes(Charset.forName("UTF-8"))) - .toString()); + sipUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "SIP", tp.getTpNodeId(), + TapiStringConstants.DSR, tp.getTpId())).getBytes(StandardCharsets.UTF_8)).toString()); LOG.info("DSR XPDR SIP name = {}", String.join("+", tp.getTpNodeId(), TapiStringConstants.DSR, tp.getTpId())); break; @@ -1281,11 +1337,11 @@ public final class ConnectivityUtils { LOG.info("Node of NEP id before Merge = {}", String.join("+", node, TapiStringConstants.PHTNC_MEDIA)); // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, TapiStringConstants.PHTNC_MEDIA) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcRdmAD.split("\\+")[1]) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); this.tapiContext.updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep); } @@ -1293,17 +1349,17 @@ public final class ConnectivityUtils { ConnectionEndPoint cep) { // Give uuids so that it is easier to look for things: topology uuid, node uuid, nep uuid, cep Uuid topoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, nodeLayer) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes(String.join("+", node, qual, spcXpdrNet.split("\\+")[1]) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); this.tapiContext.updateTopologyWithCep(topoUuid, nodeUuid, nepUuid, cep); } public Map + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey, + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> getConnectionFullMap() { return this.connectionFullMap; } @@ -1404,7 +1460,7 @@ public final class ConnectivityUtils { // It could be obtained from the SIP which has the NEP and includes all the OR name. Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid(); // Todo -> need to find the NEP associated to that SIP - Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeZid.getBytes(Charset.forName("UTF-8"))).toString()); + Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeZid.getBytes(StandardCharsets.UTF_8)).toString()); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node = this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid); if (node == null) { @@ -1492,10 +1548,10 @@ public final class ConnectivityUtils { if (!serviceLayer.equals(LayerProtocolName.ETH)) { serviceZEndBuilder .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(new SubrateEthSlaBuilder() - .setCommittedBurstSize(Uint16.valueOf(64)) - .setCommittedInfoRate(Uint32.valueOf(100000)) - .build()) - .build()); + .setCommittedBurstSize(Uint16.valueOf(64)) + .setCommittedInfoRate(Uint32.valueOf(100000)) + .build()) + .build()); } return serviceZEndBuilder.build(); } @@ -1509,7 +1565,7 @@ public final class ConnectivityUtils { // It could be obtained from the SIP which has the NEP and includes all the OR name. Uuid sipUuid = endPoint.getServiceInterfacePoint().getServiceInterfacePointUuid(); // Todo -> need to find the NEP associated to that SIP - Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeAid.getBytes(Charset.forName("UTF-8"))).toString()); + Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes(nodeAid.getBytes(StandardCharsets.UTF_8)).toString()); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node node = this.tapiContext.getTapiNode(this.tapiTopoUuid, nodeUuid); if (node == null) { @@ -1552,11 +1608,11 @@ public final class ConnectivityUtils { .setServiceFormat(serviceFormat) .setServiceRate(Uint32.valueOf(capacity)) .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla( - new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.subrate.eth - .sla.SubrateEthSlaBuilder() - .setCommittedBurstSize(Uint16.valueOf(64)) - .setCommittedInfoRate(Uint32.valueOf(100000)) - .build()) + new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.subrate.eth + .sla.SubrateEthSlaBuilder() + .setCommittedBurstSize(Uint16.valueOf(64)) + .setCommittedInfoRate(Uint32.valueOf(100000)) + .build()) .build()) .setTxDirection(Map.of(new TxDirectionKey(Uint8.ZERO), new TxDirectionBuilder() .setPort(new PortBuilder() @@ -1599,10 +1655,10 @@ public final class ConnectivityUtils { if (!serviceLayer.equals(LayerProtocolName.ETH)) { serviceAEndBuilder .setEthernetAttributes(new EthernetAttributesBuilder().setSubrateEthSla(new SubrateEthSlaBuilder() - .setCommittedBurstSize(Uint16.valueOf(64)) - .setCommittedInfoRate(Uint32.valueOf(100000)) - .build()) - .build()); + .setCommittedBurstSize(Uint16.valueOf(64)) + .setCommittedInfoRate(Uint32.valueOf(100000)) + .build()) + .build()); } return serviceAEndBuilder.build(); } @@ -1631,13 +1687,13 @@ public final class ConnectivityUtils { private ConnectionEndPoint getAssociatediODUCep(String spcXpdrNetwork) { Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0], - TapiStringConstants.DSR).getBytes(Charset.forName("UTF-8")))).toString()); + TapiStringConstants.DSR).getBytes(StandardCharsets.UTF_8))).toString()); Uuid nepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", spcXpdrNetwork.split("\\+")[0], - TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]).getBytes(Charset.forName("UTF-8")))) + TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1]).getBytes(StandardCharsets.UTF_8))) .toString()); Uuid cepUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", spcXpdrNetwork.split("\\+")[0], TapiStringConstants.I_ODU, spcXpdrNetwork.split("\\+")[1])) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); return this.tapiContext.getTapiCEP(this.tapiTopoUuid, nodeUuid, nepUuid, cepUuid); } @@ -1686,7 +1742,7 @@ public final class ConnectivityUtils { List openroadmNodeTypeList = new ArrayList<>(); for (String xpdrNode:xpdrNodelist) { Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",xpdrNode, TapiStringConstants.DSR)) - .getBytes(Charset.forName("UTF-8"))).toString()); + .getBytes(StandardCharsets.UTF_8)).toString()); InstanceIdentifier nodeIID = InstanceIdentifier.builder( Context.class).augmentation(org.opendaylight.yang.gen.v1.urn @@ -1717,4 +1773,4 @@ public final class ConnectivityUtils { } return openroadmNodeTypeList.get(0); } -} +} \ No newline at end of file diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImpl.java index bd7932f13..a4499cf02 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImpl.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/connectivity/TapiConnectivityImpl.java @@ -183,6 +183,7 @@ public class TapiConnectivityImpl implements TapiConnectivityService { .setOperationalState(OperationalState.DISABLED) .setLifecycleState(LifecycleState.PLANNED) .setServiceLayer(input.getConnectivityConstraint().getServiceLayer()) + .setServiceLevel(input.getConnectivityConstraint().getServiceLevel()) .setServiceType(ServiceType.POINTTOPOINTCONNECTIVITY) .setConnectivityDirection(ForwardingDirection.BIDIRECTIONAL) .setName(Map.of(name.key(), name)) diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java index fe0487234..b68f43ccf 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/impl/TapiProvider.java @@ -20,6 +20,7 @@ import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations; import org.opendaylight.transportpce.tapi.connectivity.ConnectivityUtils; import org.opendaylight.transportpce.tapi.connectivity.TapiConnectivityImpl; +import org.opendaylight.transportpce.tapi.listeners.TapiNetworkModelListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl; @@ -82,6 +83,7 @@ public class TapiProvider { private ListenerRegistration pcelistenerRegistration; private ListenerRegistration rendererlistenerRegistration; private ListenerRegistration servicehandlerlistenerRegistration; + private ListenerRegistration tapinetworkmodellistenerRegistration; private final OrgOpenroadmServiceService serviceHandler; private final ServiceDataStoreOperations serviceDataStoreOperations; private final TapiListener tapiListener; @@ -94,6 +96,7 @@ public class TapiProvider { private TapiRendererListenerImpl rendererListenerImpl; private TapiServiceHandlerListenerImpl serviceHandlerListenerImpl; private final NotificationService notificationService; + private TapiNetworkModelListenerImpl tapiNetworkModelListenerImpl; public TapiProvider(DataBroker dataBroker, RpcProviderService rpcProviderService, OrgOpenroadmServiceService serviceHandler, ServiceDataStoreOperations serviceDataStoreOperations, @@ -101,7 +104,8 @@ public class TapiProvider { TapiNetconfTopologyListener topologyListener, TapiPortMappingListener tapiPortMappingListener, TransportpceTapinetworkutilsService tapiNetworkUtils, TapiPceListenerImpl pceListenerImpl, TapiRendererListenerImpl rendererListenerImpl, TapiServiceHandlerListenerImpl serviceHandlerListenerImpl, - NotificationService notificationService, TapiOrLinkListener orLinkListener) { + NotificationService notificationService, TapiOrLinkListener orLinkListener, + TapiNetworkModelListenerImpl tapiNetworkModelListenerImpl) { this.dataBroker = dataBroker; this.rpcProviderService = rpcProviderService; this.serviceHandler = serviceHandler; @@ -116,6 +120,7 @@ public class TapiProvider { this.serviceHandlerListenerImpl = serviceHandlerListenerImpl; this.notificationService = notificationService; this.orLinkListener = orLinkListener; + this.tapiNetworkModelListenerImpl = tapiNetworkModelListenerImpl; } /** @@ -161,6 +166,8 @@ public class TapiProvider { rendererlistenerRegistration = notificationService.registerNotificationListener(rendererListenerImpl); servicehandlerlistenerRegistration = notificationService.registerNotificationListener(serviceHandlerListenerImpl); + tapinetworkmodellistenerRegistration = + notificationService.registerNotificationListener(tapiNetworkModelListenerImpl); } /** @@ -184,5 +191,6 @@ public class TapiProvider { rendererlistenerRegistration.close(); servicehandlerlistenerRegistration.close(); rpcRegistration.close(); + tapinetworkmodellistenerRegistration.close(); } } diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiNetworkModelListenerImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiNetworkModelListenerImpl.java new file mode 100644 index 000000000..995fee80c --- /dev/null +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiNetworkModelListenerImpl.java @@ -0,0 +1,483 @@ +/* + * 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.listeners; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.transportpce.common.network.NetworkTransactionService; +import org.opendaylight.transportpce.tapi.TapiStringConstants; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; +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.Context; +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.connectivity.rev181210.OwnedNodeEdgePoint1; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connection.LowerConnection; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey; +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.context.ConnectivityContext; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NameAndValueChange; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.Notification; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NotificationType; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.ObjectType; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.TapiNotificationListener; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.Context1; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.NodeEdgePointRef; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.context.TopologyContext; +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.topology.Node; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.Topology; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.context.TopologyKey; +import org.opendaylight.yangtools.yang.binding.Enumeration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TapiNetworkModelListenerImpl implements TapiNotificationListener { + + private static final Logger LOG = LoggerFactory.getLogger(TapiNetworkModelListenerImpl.class); + private final NetworkTransactionService networkTransactionService; + private final List connectivityServiceChanges = new ArrayList<>(); + private final Uuid tapiTopoUuid = new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER + .getBytes(StandardCharsets.UTF_8)).toString()); + private final List orderedServiceLayerList; + + + public TapiNetworkModelListenerImpl(NetworkTransactionService networkTransactionService) { + this.networkTransactionService = networkTransactionService; + this.orderedServiceLayerList = List.of(LayerProtocolName.PHOTONICMEDIA, LayerProtocolName.ODU, + LayerProtocolName.DSR, LayerProtocolName.ETH); + } + + @Override + public void onNotification(Notification notification) { + LOG.info("Received network model notification {}", notification); + if (notification.getNotificationType() == NotificationType.ATTRIBUTEVALUECHANGE + && notification.getTargetObjectType() == ObjectType.NODEEDGEPOINT) { + if (notification.getChangedAttributes() == null) { + return; + } + // TODO: need to re-think this to update first the connections from roadm to roadm and then the others + updateConnections(notification.getChangedAttributes().keySet().stream() + .map(changedAttributesKey -> new Uuid(changedAttributesKey.getValueName())) + .collect(Collectors.toList()), + notification.getChangedAttributes().values().stream() + .map(NameAndValueChange::getNewValue) + .collect(Collectors.toList())); + updateConnectivityServices(); + // todo create NotificationPublishSerivce (Tapi) object + send Notification + } + } + + private void updateConnectivityServices() { + try { + this.connectivityServiceChanges.clear(); + InstanceIdentifier connectivityContextIID = + InstanceIdentifier.builder(Context.class).augmentation( + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(ConnectivityContext.class) + .build(); + Optional optConnContext = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get(); + if (optConnContext.isEmpty()) { + LOG.error("Could not update TAPI connectivity services"); + return; + } + ConnectivityContext connContext = optConnContext.get(); + Map states = new HashMap<>(); + if (connContext.getConnectivityService() == null) { + return; + } + for (ConnectivityService connService : connContext.getConnectivityService().values()) { + LOG.info("Connectivity service = {}", connService); + // TODO: maybe we need to check lower connections if my new code doesnt work + states.put(connService.getUuid(), getStates(connService)); + AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0]; + OperationalState operState = (OperationalState) states.get(connService.getUuid())[1]; + + InstanceIdentifier connServIID = InstanceIdentifier + .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi + .connectivity.rev181210.Context1.class) + .child(ConnectivityContext.class) + .child(ConnectivityService.class, new ConnectivityServiceKey(connService.getUuid())) + .build(); + ConnectivityService changedConnServ = new ConnectivityServiceBuilder() + .setUuid(connService.getUuid()) + .setAdministrativeState(adminState) + .setOperationalState(operState) + .build(); + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connServIID, + changedConnServ); + this.networkTransactionService.commit().get(); + + if (connService.getAdministrativeState() != adminState + || connService.getOperationalState() != operState) { + this.connectivityServiceChanges.add(changedConnServ); + } + } + // TODO: this last function may need some refactoring... if the PHOT_MEDIA goes down, + // then ODU goes down and then DSR should also go down + for (ConnectivityService connService : connContext.getConnectivityService().values()) { + AdministrativeState adminState = (AdministrativeState) states.get(connService.getUuid())[0]; + OperationalState operState = (OperationalState) states.get(connService.getUuid())[1]; + this.connectivityServiceChanges.addAll(updateSupportedConnectivityServices( + connContext.getConnectivityService().values(), connService.getUuid(), adminState, operState, + LayerProtocolName.ODU)); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Could not update TAPI connectivity services"); + } + } + + private Enumeration[] getStates(ConnectivityService connService) throws InterruptedException, ExecutionException { + OperationalState operState = OperationalState.ENABLED; + AdministrativeState adminState = AdministrativeState.UNLOCKED; + if (connService.getConnection() == null) { + LOG.info("No connections on service = {}", connService); + return new Enumeration[]{null, null}; + } + for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210 + .connectivity.service.Connection connection : connService.getConnection().values()) { + InstanceIdentifier connIID = + InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(ConnectivityContext.class) + .child(Connection.class, new ConnectionKey(connection.getConnectionUuid())) + .build(); + Optional optConn = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, + connIID).get(); + if (optConn.isEmpty()) { + LOG.error("Could not get state for a TAPI connection"); + continue; + } + LOG.info("State of connection {} of connectivity service {} = {}", optConn.get().getUuid().getValue(), + connService.getUuid().getValue(), optConn.get().getOperationalState().getName()); + if (optConn.get().getOperationalState() == OperationalState.DISABLED) { + adminState = AdministrativeState.LOCKED; + operState = OperationalState.DISABLED; + } + } + return new Enumeration[]{adminState, operState}; + } + + private void updateConnections(List changedOneps, List onepStates) { + LOG.info("Updating TAPI connections"); + LOG.info("Change in oneps = {}, new states = {}", changedOneps, onepStates); + try { + //should it return a list of connections? + InstanceIdentifier connectivityContextIID = + InstanceIdentifier.builder(Context.class).augmentation( + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .build(); + Optional optConnContext = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityContextIID).get(); + if (optConnContext.isEmpty()) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR); + return; + } + if (optConnContext.get().getConnectivityService() == null) { + LOG.info("No TAPI connectivity service to update"); + return; + } + // TODO: order services from lower layer to upper layer + Map connServMap + = optConnContext.get().getConnectivityService(); + if (connServMap == null) { + LOG.info("No connections to update"); + return; + } + connServMap = orderConnServiceMap(connServMap); + for (ConnectivityService connService : connServMap.values()) { + LOG.info("Looping through connectivity service = {}", connService.getUuid().getValue()); + if (connService.getConnection() == null) { + continue; + } + for (org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210 + .connectivity.service.Connection connection : connService.getConnection().values()) { + InstanceIdentifier connIID = + InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(Connection.class, new ConnectionKey(connection.getConnectionUuid())) + .build(); + Optional optConn = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get(); + if (optConn.isEmpty()) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR); + continue; + } + Connection newConn = optConn.get(); + // Check LowerConnection states and if any of the lower connection is disabled then we can put + // the connection out of service. And based on the connection previous state we decide + // the update necessary + OperationalState newConnState = newConn.getOperationalState(); + if (newConn.getLowerConnection() != null) { + newConnState = updateLowerConnections(changedOneps, onepStates, + newConn.getLowerConnection().values(), newConn.getOperationalState()); + } + if (newConnState.equals(newConn.getOperationalState())) { + // To check if the oneps are from the original Top connection + newConnState = getConnectionState(changedOneps, onepStates, newConn); + } + + LOG.info("Previous connection state = {} & New connection state = {}", + newConn.getOperationalState().getName(), newConnState.getName()); + Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build(); + // TODO: the changed NEP is a DEG port which is not in any connection, + // therefore we also need to change the cross connections, + // the lower connections uuid and check the states. + // If any of the lower connections of a connection is DISABLED then the top connection is DISABLED + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn); + this.networkTransactionService.commit().get(); + } + } + } catch (InterruptedException | ExecutionException e) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR); + } + } + + private Map orderConnServiceMap( + Map connServMap) { + Map orderedServiceMap = new HashMap<>(); + for (LayerProtocolName lpn:this.orderedServiceLayerList) { + for (ConnectivityService connServ:connServMap.values()) { + if (connServ.getServiceLayer().equals(lpn)) { + LOG.info("Layer of service is equal to entry of lpn = {}", lpn); + orderedServiceMap.put(connServ.key(), connServ); + } + } + } + LOG.info("Ordered map of services = {}", orderedServiceMap); + return orderedServiceMap; + } + + private OperationalState updateLowerConnections(List changedOneps, List onepStates, + Collection lowerConnections, + OperationalState uppConnState) { + LOG.info("Updating lower connections"); + OperationalState topConnectionState = uppConnState; + Boolean allLowerConnEna = true; + try { + for (LowerConnection lowerConn:lowerConnections) { + InstanceIdentifier connIID = + InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid())) + .build(); + Optional optConn = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get(); + if (optConn.isEmpty()) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR); + continue; + } + Connection newConn = optConn.get(); // Current state of connection + if (newConn.getLowerConnection() != null) { + // TODO: we can receive disable here because the lower connection haven been yet looped through and + // therefore it is disabled but it has to be changed to enable before returning disable. + // We need to recall the update Lower Connections with the lower connection we are checking now + // and all its lower connections, until no lower connections are found in the connection + updateLowerConnections(changedOneps, onepStates, newConn.getLowerConnection().values(), + newConn.getOperationalState()); + } + OperationalState newConnState = getConnectionState(changedOneps, onepStates, newConn); + // updated connection state if it contains a nep that has changed + if (!newConn.getOperationalState().equals(newConnState)) { + Connection changedConn = new ConnectionBuilder(newConn).setOperationalState(newConnState).build(); + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connIID, changedConn); + this.networkTransactionService.commit().get(); + } + if (newConnState.equals(OperationalState.DISABLED)) { + LOG.info("LowerConnection state is disable"); + allLowerConnEna = false; + topConnectionState = OperationalState.DISABLED; + } + } + if (allLowerConnEna) { + return OperationalState.ENABLED; + } + return OperationalState.DISABLED; + } catch (InterruptedException | ExecutionException e) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR); + return topConnectionState; + } + } + + private OperationalState getConnectionState(List changedOneps, List operState, Connection conn) + throws InterruptedException, ExecutionException { + LOG.info("Getting TAPI connectionState"); + List connectionNeps = Objects.requireNonNull(conn.getConnectionEndPoint()).values().stream() + .map(NodeEdgePointRef::getNodeEdgePointUuid).collect(Collectors.toList()); + LOG.info("Changed neps = {}", changedOneps); + LOG.info("Connection NEPs = {}", connectionNeps); + if (!Collections.disjoint(changedOneps, connectionNeps)) { + LOG.info("Connection neps {} are included in changed oneps {}", connectionNeps, changedOneps); + if ((changedOneps.contains(connectionNeps.get(0)) ? transformOperState(operState.get( + changedOneps.indexOf(connectionNeps.get(0)))) : null) == OperationalState.DISABLED + || (changedOneps.contains(connectionNeps.get(1)) ? transformOperState(operState.get( + changedOneps.indexOf(connectionNeps.get(1)))) : null) == OperationalState.DISABLED) { + return OperationalState.DISABLED; + } + LOG.info("Didnt transform correctly the states"); + for (Uuid connectionNep : connectionNeps) { + Optional ocep + = conn.getConnectionEndPoint().values().stream() + .filter(connectionEndPoint -> connectionEndPoint.getNodeEdgePointUuid() == connectionNep) + .findFirst(); + if (ocep.isEmpty()) { + continue; + } + InstanceIdentifier onepIID = InstanceIdentifier.builder(Context.class) + .augmentation(Context1.class).child(TopologyContext.class) + .child(Topology.class, new TopologyKey(tapiTopoUuid)) + .child(Node.class, new NodeKey(ocep.get().getNodeUuid())) + .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(connectionNep)) + .build(); + Optional onep = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, onepIID).get(); + if (onep.isEmpty() || onep.get().augmentation(OwnedNodeEdgePoint1.class) == null + || onep.get().augmentation(OwnedNodeEdgePoint1.class).getCepList() == null) { + continue; + } + if (onep.get().getOperationalState() == OperationalState.DISABLED + && !changedOneps.contains(onep.get().getUuid())) { + return OperationalState.DISABLED; + } + } + return OperationalState.ENABLED; + } + LOG.info("Connection state = {}. Going to check lower connections", conn.getOperationalState()); + // TODO --> check all lower connections state and if all of them are enabled we return enable, otherwise disable + if (conn.getLowerConnection() != null && allLowerConEnabled(conn.getLowerConnection().values())) { + return OperationalState.ENABLED; + } + return conn.getOperationalState(); + } + + private boolean allLowerConEnabled(Collection lowerConnections) { + try { + for (LowerConnection lowerConn:lowerConnections) { + InstanceIdentifier connIID = + InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context + .ConnectivityContext.class) + .child(Connection.class, new ConnectionKey(lowerConn.getConnectionUuid())) + .build(); + Optional optConn = + this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connIID).get(); + if (optConn.isEmpty()) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_READ_ERROR); + continue; + } + Connection newConn = optConn.get(); // Current state of connection + // updated connection state if it contains a nep that has changed + if (newConn.getOperationalState().equals(OperationalState.DISABLED)) { + LOG.info("LowerConnection state is disable"); + return false; + } + } + return true; + } catch (InterruptedException | ExecutionException e) { + LOG.error(TapiStringConstants.TAPI_CONNECTION_UPDATE_ERROR); + return false; + } + } + + private List updateSupportedConnectivityServices(Collection connServices, + Uuid supportingConnService, + AdministrativeState adminState, + OperationalState operState, + LayerProtocolName layer) { + // TODO we need to check this function + List changedServices = new ArrayList<>(); + if (adminState != AdministrativeState.LOCKED && operState != OperationalState.DISABLED) { + return changedServices; + } + try { + for (ConnectivityService supportedConnService : connServices) { + // TODO currently supporting service uuid is saved in service layer, replace with name as soon + // as name is implemented + if (supportedConnService.getServiceLayer() != layer) { + continue; + } + InstanceIdentifier supportedConnServIID = InstanceIdentifier + .builder(Context.class).augmentation(org.opendaylight.yang.gen.v1 + .urn.onf.otcc.yang.tapi.connectivity.rev181210.Context1.class) + .child(org.opendaylight.yang.gen.v1 + .urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(ConnectivityService.class, new ConnectivityServiceKey(supportedConnService.getUuid())) + .build(); + Optional optNewConnService = this.networkTransactionService.read( + LogicalDatastoreType.OPERATIONAL, supportedConnServIID).get(); + if (optNewConnService.isEmpty()) { + LOG.error("Could not update TAPI connectivity service"); + continue; + } + ConnectivityService newConnService = optNewConnService.get(); + if (supportedConnService.getServiceLevel() != null + && supportedConnService.getServiceLevel().equals(supportingConnService.getValue()) + && newConnService.getAdministrativeState() != AdministrativeState.LOCKED + && newConnService.getOperationalState() != OperationalState.DISABLED) { + + ConnectivityService changedSupportedConnServ = new ConnectivityServiceBuilder() + .setUuid(supportedConnService.getUuid()) + .setAdministrativeState(adminState) + .setOperationalState(operState) + .build(); + // TODO: may need to update connections... + this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, supportedConnServIID, + changedSupportedConnServ); + this.networkTransactionService.commit().get(); + changedServices.add(changedSupportedConnServ); + if (layer == LayerProtocolName.ODU) { + changedServices.addAll(updateSupportedConnectivityServices(connServices, + supportedConnService.getUuid(), adminState, operState, LayerProtocolName.DSR)); + } + } + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Could not update TAPI connectivity service"); + } + return changedServices; + } + + private OperationalState transformOperState(String operString) { + LOG.debug("Operstring to be converted = {}", operString); + State operState = org.opendaylight.transportpce.networkmodel.util.TopologyUtils.setNetworkOperState(operString); + LOG.debug("State received from topologyutils = {}", operState); + return operState.equals(State.InService) ? OperationalState.ENABLED : OperationalState.DISABLED; + } + +} diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiPceListenerImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiPceListenerImpl.java index c37edd616..713e496f5 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiPceListenerImpl.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/listeners/TapiPceListenerImpl.java @@ -96,11 +96,17 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey, org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection> connectionFullMap; // this variable is for complete connection objects + private Connection topConnRdmRdm; + private Connection topConnXpdrXpdrPhtn; + private Connection topConnXpdrXpdrOdu; public TapiPceListenerImpl(DataBroker dataBroker) { this.connectionFullMap = new HashMap<>(); this.dataBroker = dataBroker; this.networkTransactionService = new NetworkTransactionImpl(new RequestProcessor(this.dataBroker)); + this.topConnRdmRdm = null; + this.topConnXpdrXpdrPhtn = null; + this.topConnXpdrXpdrOdu = null; } @Override @@ -131,7 +137,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { private void onPathComputationResult(ServicePathRpcResult notification) { this.connectionFullMap.clear(); LOG.info("PCE '{}' Notification received : {}",servicePathRpcResult.getNotificationType().getName(), - notification); + notification); if (servicePathRpcResult.getStatus() == RpcStatusEx.Failed) { LOG.error("PCE path computation failed !"); return; @@ -162,7 +168,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // Create connections and ceps for the connectivity service. // Connections must be with a locked stated. As the renderer hasnt implemented yet the oc's Map connectionMap = createConnectionsAndCepsForService(pathDescription, - input.getConnectivityConstraint().getServiceLayer()); + input.getConnectivityConstraint().getServiceLayer()); // add connections to connection context and to connectivity context updateConnectionContextWithConn(this.connectionFullMap, connectionMap, serviceUuid); } @@ -181,7 +187,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { List rdmNodelist = new ArrayList<>(); List xpdrNodelist = new ArrayList<>(); for (AToZ elem:pathDescription.getAToZDirection().getAToZ().values().stream() - .sorted(Comparator.comparing(AToZ::getId)).collect(Collectors.toList())) { + .sorted((Comparator.comparing(atoz -> Integer.valueOf(atoz.getId())))).collect(Collectors.toList())) { resourceType = elem.getResource().getResource().implementedInterface().getSimpleName(); switch (resourceType) { case TapiStringConstants.TP: @@ -270,19 +276,24 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // - Top Connection MC betwwen MC CEPs of different roadms // - Top Connection OTSiMC betwwen OTSiMC CEPs of extreme roadms connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist, - edgeRoadm1, edgeRoadm2)); + edgeRoadm1, edgeRoadm2)); if (!pathDescription.getAToZDirection().getAToZ().values().stream().findFirst().get().getId() .contains("ROADM")) { // - XC Connection OTSi betwwen iOTSi y eOTSi of xpdr // - Top connection OTSi between network ports of xpdrs in the Photonic media layer -> i_OTSi connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist)); + this.topConnRdmRdm = null; } break; case ODU: + // TODO: verify if this is correct LOG.info("OTN ODU service"); // - XC Connection OTSi between iODU and eODU of xpdr // - Top connection in the ODU layer, between xpdr iODU ports - connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); + if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) { + connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrPhtn = null; + } break; case ETH: LOG.info("WDM service"); @@ -295,10 +306,12 @@ public class TapiPceListenerImpl implements TransportpcePceListener { connectionServMap.putAll(createRoadmCepsAndConnections(rdmAddDropTplist, rdmDegTplist, rdmNodelist, edgeRoadm1, edgeRoadm2)); connectionServMap.putAll(createXpdrCepsAndConnectionsPht(xpdrNetworkTplist, xpdrNodelist)); + this.topConnRdmRdm = null; xpdrClientTplist = getAssociatedClientsPort(xpdrNetworkTplist); LOG.info("Associated client ports = {}", xpdrClientTplist); connectionServMap.putAll(createXpdrCepsAndConnectionsEth(xpdrClientTplist, xpdrNodelist, connectionServMap)); + this.topConnXpdrXpdrPhtn = null; } break; case DSR: @@ -310,14 +323,15 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // TODO: We create both ODU and DSR because there is no ODU service creation for the switch // - XC Connection OTSi betwwen iODU and eODU of xpdr // - Top connection in the ODU layer, between xpdr eODU ports (?) - connectionServMap.putAll(createXpdrCepsAndConnectionsOdu(xpdrNetworkTplist, xpdrNodelist)); connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrPhtn = null; } if (openroadmNodeType.equals(OpenroadmNodeType.MUXPDR)) { // TODO: OTN service but mux has 3 steps at rendering. Verify that things exist connectionServMap.putAll(createXpdrCepsAndConnectionsDsr(xpdrClientTplist, xpdrNetworkTplist, xpdrNodelist)); + this.topConnXpdrXpdrOdu = null; } break; default: @@ -343,7 +357,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { } LOG.info("PCE cancel resource done OK !"); Uuid suuid = new Uuid(UUID.nameUUIDFromBytes(serviceName.getBytes(Charset.forName("UTF-8"))) - .toString()); + .toString()); // get connections of connectivity service and remove them from tapi context and then remove // service from context. The CEPs are maintained as they could be reused by another service ConnectivityService connService = getConnectivityService(suuid); @@ -358,8 +372,8 @@ public class TapiPceListenerImpl implements TransportpcePceListener { } @SuppressFBWarnings( - value = "ES_COMPARING_STRINGS_WITH_EQ", - justification = "false positives, not strings but real object references comparisons") + value = "ES_COMPARING_STRINGS_WITH_EQ", + justification = "false positives, not strings but real object references comparisons") private Boolean compareServicePathRpcResult(ServicePathRpcResult notification) { if (servicePathRpcResult == null) { return false; @@ -412,7 +426,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // DSR top connection between edge xpdr CLIENT DSR org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR, - LayerProtocolName.DSR, xcMap); + LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connectionDsr.key(), connectionDsr); // DSR top connection that will be added to the service object @@ -457,7 +471,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // Create x connection between I_ODU and E_ODU within xpdr org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrClient, spcXpdrNetwork, - TapiStringConstants.ODU, LayerProtocolName.ODU); + TapiStringConstants.ODU, LayerProtocolName.ODU); this.connectionFullMap.put(connection.key(), connection); // Create X connection that will be added to the service object @@ -473,7 +487,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // eODU top connection between edge xpdr CLIENT eODU org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionOdu = createTopConnection(spcXpdr1, spcXpdr2, cepMapOdu, TapiStringConstants.E_ODU, - LayerProtocolName.ODU, xcMap); + LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrOdu); this.connectionFullMap.put(connectionOdu.key(), connectionOdu); // ODU top connection that will be added to the service object and also lower connection @@ -485,7 +499,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // DSR top connection between edge xpdr CLIENT DSR org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connectionDsr = createTopConnection(spcXpdr1, spcXpdr2, cepMapDsr, TapiStringConstants.DSR, - LayerProtocolName.DSR, xcMap); + LayerProtocolName.DSR, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connectionDsr.key(), connectionDsr); // DSR top connection that will be added to the service object @@ -524,12 +538,13 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .get(xpdrNodelist.size() - 1))).findFirst().get(); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_ODU, - LayerProtocolName.ODU, xcMap); + LayerProtocolName.ODU, xcMap, this.topConnXpdrXpdrPhtn); this.connectionFullMap.put(connection.key(), connection); // ODU top connection that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); + this.topConnXpdrXpdrOdu = conn; return connServMap; } @@ -543,7 +558,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // be added to the lower connection of a top connection Map xcMap = new HashMap<>(); - // create ceps and x connections within xpdr + // create ceps and xc connections within xpdr for (String xpdr:xpdrNodelist) { LOG.info("Creating ceps and xc for xpdr {}", xpdr); String spcXpdrNetwork = xpdrNetworkTplist.stream().filter(netp -> netp.contains(xpdr)).findFirst().get(); @@ -570,7 +585,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // Create x connection between I_OTSi and E_OTSi within xpdr org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createXCBetweenCeps(netCep2, netCep3, spcXpdrNetwork, spcXpdrNetwork, - TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA); + TapiStringConstants.OTSI, LayerProtocolName.PHOTONICMEDIA); this.connectionFullMap.put(connection.key(), connection); // Create X connection that will be added to the service object @@ -584,14 +599,13 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .get(xpdrNodelist.size() - 1))).findFirst().get(); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection = createTopConnection(spcXpdr1, spcXpdr2, cepMap, TapiStringConstants.I_OTSI, - LayerProtocolName.PHOTONICMEDIA, xcMap); + LayerProtocolName.PHOTONICMEDIA, xcMap, this.topConnRdmRdm); this.connectionFullMap.put(connection.key(), connection); // OTSi top connection that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); - - + this.topConnXpdrXpdrPhtn = conn; return connServMap; } @@ -600,128 +614,170 @@ public class TapiPceListenerImpl implements TransportpcePceListener { List rdmNodelist, String edgeRoadm1, String edgeRoadm2) { // TODO: will need to check if things exist already or not - Map connServMap = new HashMap<>(); Map cepMap = new HashMap<>(); // create ceps and x connections within roadm - Map xcMap = new HashMap<>(); + Map xcLowerMap = new HashMap<>(); for (String roadm : rdmNodelist) { LOG.info("Creating ceps and xc for roadm {}", roadm); - String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); - LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD); - // There should be only 1 AD and 1 DEG per roadm - // TODO photonic media model should be updated to have the corresponding CEPs. I will just create - // 3 different MC CEPs giving different IDs to show that they are different - // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs - // created in the topology creation - // add CEPs to the topology to the corresponding ONEP - ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1); - ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2); - ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC); - putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3); - cepMap.put(adCep1.key(), adCep1); - cepMap.put(adCep2.key(), adCep2); - cepMap.put(adCep3.key(), adCep3); - - String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); - LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG); - - ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1); - ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2); - ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC); - putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3); - cepMap.put(degCep1.key(), degCep1); - cepMap.put(degCep2.key(), degCep2); - cepMap.put(degCep3.key(), degCep3); - - LOG.info("Going to create cross connections for ROADM {}", roadm); - // Create X connections between MC and OTSi_MC for full map - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection1 = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC, - LayerProtocolName.PHOTONICMEDIA); - LOG.info("Cross connection 1 created = {}", connection1.toString()); - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection2 = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC, - LayerProtocolName.PHOTONICMEDIA); - LOG.info("Cross connection 2 created = {}", connection2.toString()); - this.connectionFullMap.put(connection1.key(), connection1); - this.connectionFullMap.put(connection2.key(), connection2); - - // Create X connections that will be added to the service object - LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); - LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); - - xcMap.put(conn1.key(), conn1); - xcMap.put(conn2.key(), conn2); - } - LOG.info("Going to create top connections between roadms"); - // create top connections between roadms: MC connections between AD MC CEPs of roadms - for (int i = 0; i < rdmNodelist.size(); i++) { - if (rdmNodelist.size() <= (i + 1)) { - LOG.info("Reached last roadm. No more MC connections"); - break; + if (roadm.equals(edgeRoadm1) || roadm.equals(edgeRoadm2)) { + LOG.info("EDGE ROADM, cross connections needed between SRG and DEG"); + String spcRdmAD = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("AD port of ROADm {} = {}", roadm, spcRdmAD); + // There should be only 1 AD and 1 DEG per roadm + // TODO photonic media model should be updated to have the corresponding CEPs. I will just create + // 3 different MC CEPs giving different IDs to show that they are different + // Create 3 CEPs for each AD and DEG and the corresponding cross connections, matching the NEPs + // created in the topology creation + // add CEPs to the topology to the corresponding ONEP + ConnectionEndPoint adCep1 = createCepRoadm(spcRdmAD, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.PHTNC_MEDIA, adCep1); + ConnectionEndPoint adCep2 = createCepRoadm(spcRdmAD, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.MC, adCep2); + ConnectionEndPoint adCep3 = createCepRoadm(spcRdmAD, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmAD, TapiStringConstants.OTSI_MC, adCep3); + cepMap.put(adCep1.key(), adCep1); + cepMap.put(adCep2.key(), adCep2); + cepMap.put(adCep3.key(), adCep3); + + String spcRdmDEG = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("Degree port of ROADm {} = {}", roadm, spcRdmDEG); + + ConnectionEndPoint degCep1 = createCepRoadm(spcRdmDEG, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.PHTNC_MEDIA, degCep1); + ConnectionEndPoint degCep2 = createCepRoadm(spcRdmDEG, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.MC, degCep2); + ConnectionEndPoint degCep3 = createCepRoadm(spcRdmDEG, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG, TapiStringConstants.OTSI_MC, degCep3); + cepMap.put(degCep1.key(), degCep1); + cepMap.put(degCep2.key(), degCep2); + cepMap.put(degCep3.key(), degCep3); + + LOG.info("Going to create cross connections for ROADM {}", roadm); + // Create X connections between MC and OTSi_MC for full map + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection1 + = createXCBetweenCeps(adCep2, degCep2, spcRdmAD, spcRdmDEG, TapiStringConstants.MC, + LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 1 created = {}", connection1.toString()); + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection2 + = createXCBetweenCeps(adCep3, degCep3, spcRdmAD, spcRdmDEG, TapiStringConstants.OTSI_MC, + LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 2 created = {}", connection2.toString()); + this.connectionFullMap.put(connection1.key(), connection1); + this.connectionFullMap.put(connection2.key(), connection2); + + // Create X connections that will be added to the service object + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); + + xcLowerMap.put(conn1.key(), conn1); + xcLowerMap.put(conn2.key(), conn2); + } else { + LOG.info("MIDDLE ROADM, cross connections needed between DEG and DEG"); + String spcRdmDEG1 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).findFirst().get(); + LOG.info("Degree 1 port of ROADm {} = {}", roadm, spcRdmDEG1); + + ConnectionEndPoint deg1Cep1 = createCepRoadm(spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.PHTNC_MEDIA, deg1Cep1); + ConnectionEndPoint deg1Cep2 = createCepRoadm(spcRdmDEG1, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.MC, deg1Cep2); + ConnectionEndPoint deg1Cep3 = createCepRoadm(spcRdmDEG1, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG1, TapiStringConstants.OTSI_MC, deg1Cep3); + cepMap.put(deg1Cep1.key(), deg1Cep1); + cepMap.put(deg1Cep2.key(), deg1Cep2); + cepMap.put(deg1Cep3.key(), deg1Cep3); + + String spcRdmDEG2 = rdmDegTplist.stream().filter(adp -> adp.contains(roadm)).skip(1).findFirst().get(); + LOG.info("Degree 2 port of ROADm {} = {}", roadm, spcRdmDEG2); + + ConnectionEndPoint deg2Cep1 = createCepRoadm(spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.PHTNC_MEDIA, deg2Cep1); + ConnectionEndPoint deg2Cep2 = createCepRoadm(spcRdmDEG2, TapiStringConstants.MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.MC, deg2Cep2); + ConnectionEndPoint deg2Cep3 = createCepRoadm(spcRdmDEG2, TapiStringConstants.OTSI_MC); + putRdmCepInTopologyContext(roadm, spcRdmDEG2, TapiStringConstants.OTSI_MC, deg2Cep3); + cepMap.put(deg2Cep1.key(), deg2Cep1); + cepMap.put(deg2Cep2.key(), deg2Cep2); + cepMap.put(deg2Cep3.key(), deg2Cep3); + + LOG.info("Going to create cross connections for ROADM {}", roadm); + // Create X connections between MC and OTSi_MC for full map + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection1 + = createXCBetweenCeps(deg1Cep2, deg2Cep2, spcRdmDEG1, spcRdmDEG2, + TapiStringConstants.MC, LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 1 created = {}", connection1.toString()); + org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection connection2 + = createXCBetweenCeps(deg1Cep3, deg2Cep3, spcRdmDEG1, spcRdmDEG2, + TapiStringConstants.OTSI_MC, LayerProtocolName.PHOTONICMEDIA); + LOG.info("Cross connection 2 created = {}", connection2.toString()); + this.connectionFullMap.put(connection1.key(), connection1); + this.connectionFullMap.put(connection2.key(), connection2); + + // Create X connections that will be added to the service object + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + LowerConnection conn2 = new LowerConnectionBuilder().setConnectionUuid(connection2.getUuid()).build(); + + xcLowerMap.put(conn1.key(), conn1); + xcLowerMap.put(conn2.key(), conn2); } - // Current roadm with roadm i + 1 --> MC - String roadm1 = rdmNodelist.get(i); - String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm1)).findFirst().get(); - String roadm2 = rdmNodelist.get(i + 1); - String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(roadm2)).findFirst().get(); - LOG.info("Creating top connection from {} to {} between tps: {}-{}", roadm1, roadm2, spcRdmAD1, spcRdmAD2); - - // Create top connections between MC for full map - org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC, - LayerProtocolName.PHOTONICMEDIA, xcMap); - this.connectionFullMap.put(connection.key(), connection); - LOG.info("Top connection created = {}", connection.toString()); - - // Create top connections that will be added to the service object and lower - // connection to the next top connection - Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); - connServMap.put(conn.key(), conn); - LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); - xcMap.put(conn1.key(), conn1); } - - // OTSiMC top connection between edge roadms - LOG.info("Going to created top connection between OTSiMC"); + LOG.info("Going to create top connections between roadms"); String spcRdmAD1 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm1)).findFirst().get(); String spcRdmAD2 = rdmAddDropTplist.stream().filter(adp -> adp.contains(edgeRoadm2)).findFirst().get(); + // MC top connection between edge roadms + LOG.info("Going to created top connection between MC"); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection - connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC, - LayerProtocolName.PHOTONICMEDIA, xcMap); + connection = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.MC, + LayerProtocolName.PHOTONICMEDIA, xcLowerMap, null); this.connectionFullMap.put(connection.key(), connection); LOG.info("Top connection created = {}", connection.toString()); + Map connServMap = new HashMap<>(); // OTSiMC top connections that will be added to the service object Connection conn = new ConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); connServMap.put(conn.key(), conn); + LowerConnection conn1 = new LowerConnectionBuilder().setConnectionUuid(connection.getUuid()).build(); + Map topLowerMap = new HashMap<>(); + topLowerMap.put(conn1.key(), conn1); + + // OTSiMC top connection between edge roadms + LOG.info("Going to created top connection between OTSiMC"); + org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection + connection1 = createTopConnection(spcRdmAD1, spcRdmAD2, cepMap, TapiStringConstants.OTSI_MC, + LayerProtocolName.PHOTONICMEDIA, topLowerMap, null); + this.connectionFullMap.put(connection1.key(), connection1); + LOG.info("Top connection created = {}", connection1.toString()); + + // OTSiMC top connections that will be added to the service object + Connection conn2 = new ConnectionBuilder().setConnectionUuid(connection1.getUuid()).build(); + connServMap.put(conn2.key(), conn2); + this.topConnRdmRdm = conn2; return connServMap; } private org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection createTopConnection(String tp1, String tp2, Map cepMap, String qual, LayerProtocolName topPortocol, - Map xcMap) { + .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey, + ConnectionEndPoint> cepMap, String qual, LayerProtocolName topPortocol, + Map xcMap, Connection additionalLowerConn) { // find cep for each AD MC of roadm 1 and 2 LOG.info("Top connection name = {}", String.join("+", "TOP", tp1, tp2, qual)); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep1 = cepMap.get(new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( + .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp1.split("\\+")[0], - qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qual, tp1.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString()))); LOG.info("ADCEP1 = {}", adCep1.toString()); org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep1 = + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep1 = new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() .setNodeEdgePointUuid(adCep1.getClientNodeEdgePoint() .values().stream().findFirst().get().getNodeEdgePointUuid()) .setTopologyUuid(adCep1.getClientNodeEdgePoint() @@ -732,15 +788,15 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .build(); org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.ConnectionEndPoint adCep2 = cepMap.get(new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( + .onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey( new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", tp2.split("\\+")[0], - qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qual, tp2.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString()))); LOG.info("ADCEP2 = {}", adCep2.toString()); org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep2 = + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cep2 = new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() .setNodeEdgePointUuid(adCep2.getClientNodeEdgePoint() .values().stream().findFirst().get().getNodeEdgePointUuid()) .setTopologyUuid(adCep2.getClientNodeEdgePoint() @@ -758,8 +814,12 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .setValue(String.join("+", "TOP", tp1, tp2, qual)) .build(); // TODO: lower connection, supported link....... + if (additionalLowerConn != null) { + xcMap.putIfAbsent(new LowerConnectionKey(additionalLowerConn.getConnectionUuid()), + new LowerConnectionBuilder().setConnectionUuid(additionalLowerConn.getConnectionUuid()).build()); + } return new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "TOP", tp1, tp2, qual)) .getBytes(Charset.forName("UTF-8"))).toString())) .setName(Map.of(connName.key(), connName)) @@ -780,9 +840,9 @@ public class TapiPceListenerImpl implements TransportpcePceListener { LOG.info("CEP1 = {}", cep1.getClientNodeEdgePoint().toString()); LOG.info("CEP2 = {}", cep2.getClientNodeEdgePoint().toString()); org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ1 = + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ1 = new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() .setNodeEdgePointUuid(cep1.getClientNodeEdgePoint() .values().stream().findFirst().get().getNodeEdgePointUuid()) .setTopologyUuid(cep1.getClientNodeEdgePoint() @@ -792,9 +852,9 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .setConnectionEndPointUuid(cep1.getUuid()) .build(); org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ2 = + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPoint cepServ2 = new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connection.ConnectionEndPointBuilder() .setNodeEdgePointUuid(cep2.getClientNodeEdgePoint() .values().stream().findFirst().get().getNodeEdgePointUuid()) .setTopologyUuid(cep2.getClientNodeEdgePoint() @@ -813,7 +873,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .build(); // TODO: lower connection, supported link....... return new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "XC", tp1, tp2, qual)) .getBytes(Charset.forName("UTF-8"))).toString())) .setName(Map.of(connName.key(), connName)) @@ -834,10 +894,10 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .build(); ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder() .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString())) .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0], - qualifier)).getBytes(Charset.forName("UTF-8"))) + "PHOTONIC_MEDIA")).getBytes(Charset.forName("UTF-8"))) .toString())) .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER .getBytes(Charset.forName("UTF-8"))).toString())) @@ -846,7 +906,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // TODO: add parent ONEP?? ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString())) .setClientNodeEdgePoint(Map.of(cnep.key(), cnep)) .setName(Map.of(cepName.key(), cepName)) @@ -867,10 +927,10 @@ public class TapiPceListenerImpl implements TransportpcePceListener { .build(); ClientNodeEdgePoint cnep = new ClientNodeEdgePointBuilder() .setNodeEdgePointUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString())) .setNodeUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+",id.split("\\+")[0], - nodeLayer)).getBytes(Charset.forName("UTF-8"))) + nodeLayer)).getBytes(Charset.forName("UTF-8"))) .toString())) .setTopologyUuid(new Uuid(UUID.nameUUIDFromBytes(TapiStringConstants.T0_FULL_MULTILAYER .getBytes(Charset.forName("UTF-8"))).toString())) @@ -879,7 +939,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // TODO: add parent ONEP?? ConnectionEndPointBuilder cepBldr = new ConnectionEndPointBuilder() .setUuid(new Uuid(UUID.nameUUIDFromBytes((String.join("+", "CEP", id.split("\\+")[0], - qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) + qualifier, id.split("\\+")[1])).getBytes(Charset.forName("UTF-8"))) .toString())) .setClientNodeEdgePoint(Map.of(cnep.key(), cnep)) .setName(Map.of(cepName.key(), cepName)) @@ -939,8 +999,8 @@ public class TapiPceListenerImpl implements TransportpcePceListener { OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class); if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) { if (onep1.getCepList().getConnectionEndPoint().containsKey( - new org.opendaylight.yang.gen.v1 - .urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cep.key()))) { + new org.opendaylight.yang.gen.v1 + .urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey(cep.key()))) { LOG.info("CEP already in topology, skipping merge"); return; } @@ -964,7 +1024,7 @@ public class TapiPceListenerImpl implements TransportpcePceListener { private void updateConnectionContextWithConn( Map connFullMap, Map connMap, Uuid suuid) { @@ -972,24 +1032,24 @@ public class TapiPceListenerImpl implements TransportpcePceListener { try { ConnectivityService connServ = getConnectivityService(suuid); ConnectivityService updtConnServ = new ConnectivityServiceBuilder(connServ) - .setConnection(connMap) - .build(); + .setConnection(connMap) + .build(); // Perform the merge operation with the new conn service and the connection context updated org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext - connectivityContext = new ConnectivityContextBuilder() + connectivityContext = new ConnectivityContextBuilder() .setConnectivityService(Map.of(updtConnServ.key(), updtConnServ)) .setConnection(connFullMap) .build(); InstanceIdentifier connectivitycontextIID = - InstanceIdentifier.builder(Context.class).augmentation(Context1.class) - .child(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) - .build(); + InstanceIdentifier.builder(Context.class).augmentation(Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .build(); // merge in datastore this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, connectivitycontextIID, - connectivityContext); + connectivityContext); this.networkTransactionService.commit().get(); LOG.info("TAPI connectivity merged successfully."); } catch (InterruptedException | ExecutionException e) { @@ -999,13 +1059,13 @@ public class TapiPceListenerImpl implements TransportpcePceListener { private ConnectivityService getConnectivityService(Uuid suuid) { try { - // First read connectivity service with service uuid and update info + // First read connectivity service with service uuid and update info InstanceIdentifier connectivityServIID = InstanceIdentifier.builder(Context.class).augmentation(Context1.class) - .child(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) - .child(ConnectivityService.class, new ConnectivityServiceKey(suuid)) - .build(); + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(ConnectivityService.class, new ConnectivityServiceKey(suuid)) + .build(); Optional optConnServ = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, connectivityServIID).get(); @@ -1023,11 +1083,11 @@ public class TapiPceListenerImpl implements TransportpcePceListener { private void deleteConnectivityService(Uuid suuid) { // First read connectivity service with service uuid and update info InstanceIdentifier connectivityServIID = - InstanceIdentifier.builder(Context.class).augmentation(Context1.class) - .child(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) - .child(ConnectivityService.class, new ConnectivityServiceKey(suuid)) - .build(); + InstanceIdentifier.builder(Context.class).augmentation(Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(ConnectivityService.class, new ConnectivityServiceKey(suuid)) + .build(); try { this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectivityServIID); this.networkTransactionService.commit().get(); @@ -1040,15 +1100,15 @@ public class TapiPceListenerImpl implements TransportpcePceListener { // First read connectivity service with service uuid and update info InstanceIdentifier connectionIID = - InstanceIdentifier.builder(Context.class).augmentation(Context1.class) - .child(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) - .child(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class, - new org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey( - connectionUuid)) - .build(); + InstanceIdentifier.builder(Context.class).augmentation(Context1.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.context.ConnectivityContext.class) + .child(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection.class, + new org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey( + connectionUuid)) + .build(); try { this.networkTransactionService.delete(LogicalDatastoreType.OPERATIONAL, connectionIID); this.networkTransactionService.commit().get(); @@ -1114,12 +1174,12 @@ public class TapiPceListenerImpl implements TransportpcePceListener { Uuid nodeUuid = new Uuid(UUID.nameUUIDFromBytes((String.join("+",xpdrNode, TapiStringConstants.DSR)) .getBytes(Charset.forName("UTF-8"))).toString()); InstanceIdentifier nodeIID = InstanceIdentifier.builder( - Context.class).augmentation(org.opendaylight.yang.gen.v1.urn - .onf.otcc.yang.tapi.topology.rev181210.Context1.class).child(TopologyContext.class) - .child(Topology.class, new TopologyKey(this.tapiTopoUuid)) - .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class, - new NodeKey(nodeUuid)).build(); + .onf.otcc.yang.tapi.topology.rev181210.topology.Node> nodeIID + = InstanceIdentifier.builder(Context.class).augmentation(org.opendaylight.yang.gen.v1.urn + .onf.otcc.yang.tapi.topology.rev181210.Context1.class).child(TopologyContext.class) + .child(Topology.class, new TopologyKey(this.tapiTopoUuid)) + .child(org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.topology.Node.class, + new NodeKey(nodeUuid)).build(); try { Optional optNode = this.networkTransactionService.read(LogicalDatastoreType.OPERATIONAL, nodeIID).get(); @@ -1183,4 +1243,4 @@ public class TapiPceListenerImpl implements TransportpcePceListener { public void setServiceUuid(Uuid serviceUuid) { this.serviceUuid = serviceUuid; } -} +} \ No newline at end of file diff --git a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkModelServiceImpl.java b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkModelServiceImpl.java index a0c1a355d..39163fed4 100644 --- a/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkModelServiceImpl.java +++ b/tapi/src/main/java/org/opendaylight/transportpce/tapi/topology/TapiNetworkModelServiceImpl.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import org.opendaylight.mdsal.binding.api.NotificationPublishService; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.transportpce.common.network.NetworkTransactionService; import org.opendaylight.transportpce.tapi.R2RTapiLinkDiscovery; @@ -66,6 +67,11 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.glob import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePoint; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.common.rev181210.tapi.context.ServiceInterfacePointBuilder; 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.connectivity.rev181210.OwnedNodeEdgePoint1; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.OwnedNodeEdgePoint1Builder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPoint; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.cep.list.ConnectionEndPointKey; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.Connection; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionBuilder; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.context.ConnectionKey; @@ -75,9 +81,17 @@ 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.connectivity.service.EndPoint; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.connectivity.service.EndPointKey; 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.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepList; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev181210.context.topology.context.topology.node.owned.node.edge.point.CepListBuilder; 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.notification.rev181210.NotificationBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.NotificationType; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.ObjectType; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributes; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.notification.rev181210.notification.ChangedAttributesKey; 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; @@ -120,6 +134,7 @@ import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.tr import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristic; import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.topology.rev181210.transfer.timing.pac.LatencyCharacteristicBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.common.Uint16; import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; @@ -134,13 +149,16 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService { private Map sipMap; private final R2RTapiLinkDiscovery linkDiscovery; private final TapiLink tapiLink; + private final NotificationPublishService notificationPublishService; public TapiNetworkModelServiceImpl(final R2RTapiLinkDiscovery linkDiscovery, - NetworkTransactionService networkTransactionService, TapiLink tapiLink) { + NetworkTransactionService networkTransactionService, TapiLink tapiLink, + final NotificationPublishService notificationPublishService) { this.networkTransactionService = networkTransactionService; this.sipMap = new HashMap<>(); this.linkDiscovery = linkDiscovery; this.tapiLink = tapiLink; + this.notificationPublishService = notificationPublishService; } @Override @@ -237,10 +255,38 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService { List changedOneps = updateNeps(mapping, uuids); updateLinks(changedOneps, mapping); + sendNotification(changedOneps, mapping); LOG.info("Updated TAPI topology successfully."); } + private void sendNotification(List changedOneps, Mapping mapping) { + Notification notification = new NotificationBuilder() + .setNotificationType(NotificationType.ATTRIBUTEVALUECHANGE) + .setTargetObjectType(ObjectType.NODEEDGEPOINT) + .setChangedAttributes(getChangedAttributes(changedOneps, mapping)) + .setUuid(tapiTopoUuid) + .build(); + try { + notificationPublishService.putNotification(notification); + } catch (InterruptedException e) { + LOG.error("Could not send notification"); + } + } + + private Map getChangedAttributes(List changedOneps, + Mapping mapping) { + Map changedAttributes = new HashMap<>(); + for (Uuid nep : changedOneps) { + changedAttributes.put(new ChangedAttributesKey(nep.getValue()), + new ChangedAttributesBuilder().setValueName(nep.getValue()) + .setOldValue(mapping.getPortOperState().equals("InService") ? "OutOfService" : "InService") + .setNewValue(mapping.getPortOperState()) + .build()); + } + return changedAttributes; + } + private void updateLinks(List changedOneps, Mapping mapping) { try { InstanceIdentifier topoIID = InstanceIdentifier.builder(Context.class) @@ -294,6 +340,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService { for (OwnedNodeEdgePoint onep : oneps) { changedOneps.add(onep.getUuid()); updateSips(mapping, onep); + CepList cepList = getUpdatedCeps(mapping, onep); InstanceIdentifier onepIID = InstanceIdentifier.builder(Context.class) .augmentation(Context1.class).child(TopologyContext.class) .child(Topology.class, new TopologyKey(tapiTopoUuid)) @@ -301,6 +348,7 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService { .child(OwnedNodeEdgePoint.class, new OwnedNodeEdgePointKey(onep.getUuid())) .build(); OwnedNodeEdgePoint onepblr = new OwnedNodeEdgePointBuilder().setUuid(onep.getUuid()) + .addAugmentation(new OwnedNodeEdgePoint1Builder().setCepList(cepList).build()) .setAdministrativeState(transformAdminState(mapping.getPortAdminState())) .setOperationalState(transformOperState(mapping.getPortOperState())).build(); this.networkTransactionService.merge(LogicalDatastoreType.OPERATIONAL, onepIID, onepblr); @@ -314,6 +362,20 @@ public class TapiNetworkModelServiceImpl implements TapiNetworkModelService { return changedOneps; } + private CepList getUpdatedCeps(Mapping mapping, OwnedNodeEdgePoint onep) { + OwnedNodeEdgePoint1 onep1 = onep.augmentation(OwnedNodeEdgePoint1.class); + Map cepMap = new HashMap<>(); + if (onep1 != null && onep1.getCepList() != null && onep1.getCepList().getConnectionEndPoint() != null) { + for (Map.Entry entry : onep1.getCepList().getConnectionEndPoint() + .entrySet()) { + ConnectionEndPoint cep = new ConnectionEndPointBuilder(entry.getValue()) + .setOperationalState(transformOperState(mapping.getPortOperState())).build(); + cepMap.put(entry.getKey(), cep); + } + } + return new CepListBuilder().setConnectionEndPoint(cepMap).build(); + } + private List getChangedNodeUuids(String nodeId, Mapping mapping) { List uuids = new ArrayList<>(); if (nodeId.contains("ROADM")) { diff --git a/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml b/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml index a44df3207..62a1d9633 100644 --- a/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml +++ b/tapi/src/main/resources/OSGI-INF/blueprint/tapi-blueprint.xml @@ -22,6 +22,9 @@ Author: Gilles Thouenon + + @@ -55,10 +58,15 @@ Author: Gilles Thouenon + + + + + @@ -92,6 +100,7 @@ Author: Gilles Thouenon + 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 index 8a575abd6..90877fb3e 100644 --- a/tapi/src/test/java/org/opendaylight/transportpce/tapi/provider/TapiProviderTest.java +++ b/tapi/src/test/java/org/opendaylight/transportpce/tapi/provider/TapiProviderTest.java @@ -23,6 +23,7 @@ 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.TapiNetworkModelListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiPceListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiRendererListenerImpl; import org.opendaylight.transportpce.tapi.listeners.TapiServiceHandlerListenerImpl; @@ -73,6 +74,9 @@ public class TapiProviderTest extends AbstractTest { @Mock TapiServiceHandlerListenerImpl serviceHandlerListenerImpl; + @Mock + TapiNetworkModelListenerImpl networkModelListener; + private AutoCloseable closeable; @Before @@ -91,7 +95,7 @@ public class TapiProviderTest extends AbstractTest { TapiProvider provider = new TapiProvider(getDataBroker(), rpcProviderRegistry, serviceHandler, serviceDataStoreOperations, tapiListener, networkTransactionService, topologyListener, tapiPortMappingListener, tapiNetworkUtils, pceListenerImpl, rendererListenerImpl, - serviceHandlerListenerImpl, getNotificationService(), orLinkListener); + serviceHandlerListenerImpl, getNotificationService(), orLinkListener, networkModelListener); provider.init(); -- 2.36.6