NetworkModelListener implementation (interface D) 81/93881/24
authorErrea Moreno, Javier <javier.errea_moreno@nokia.com>
Wed, 18 Nov 2020 12:49:09 +0000 (13:49 +0100)
committerJavier <errea@eurecom.fr>
Wed, 20 Jan 2021 16:02:08 +0000 (17:02 +0100)
- TopologyListener in ServiceHandler to receive topology notifications
- Send notifications from NetworkModel to ServiceHandler
- Edited Rdm2CpdrLink.java to add states to links (forgotten before)

JIRA: TRNSPRTPCE-359
Change-Id: I56a4b2eb8a2bac2f7dd877821fca5aee0c27e500
Signed-off-by: Javier <errea@eurecom.fr>
api/src/main/yang/service_path/transportpce-networkmodel@2020-11-16.yang
lighty/src/main/java/io/lighty/controllers/tpce/module/TransportPCEImpl.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/Rdm2XpdrLink.java
networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/service/NetworkModelServiceImpl.java
networkmodel/src/main/resources/OSGI-INF/blueprint/networkmodel-blueprint.xml
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/impl/ServicehandlerImpl.java

index 0624c3982e3074e1da3e5943847285dcfe7ae24f..de06306cc6b7776d600a29b7afdc161214e136b9 100644 (file)
@@ -7,9 +7,9 @@ module transportpce-networkmodel {
     revision-date 2020-11-16;
   }
 
-  import org-openroadm-common-types {
-    prefix org-openroadm-common-types;
-    revision-date 2018-10-19;
+  import org-openroadm-common-state-types {
+    prefix org-openroadm-common-state-types;
+    revision-date 2019-11-29;
   }
 
   organization
@@ -59,7 +59,7 @@ module transportpce-networkmodel {
       description "Id of abstracted element that changed in the topology";
     }
     leaf state {
-      type org-openroadm-common-types:state;
+      type org-openroadm-common-state-types:state;
       mandatory true;
       description "Operational state of the affected element";
     }
index c7386fd182f71668a84240341f5126a579b77f57..02bf1a50b31d4644f99ce0b784b415b0079275b2 100644 (file)
@@ -121,7 +121,7 @@ public class TransportPCEImpl extends AbstractLightyModule implements TransportP
         OpenRoadmInterfaces openRoadmInterfaces = initOpenRoadmInterfaces(mappingUtils);
         PortMapping portMapping = initPortMapping(lightyServices, openRoadmInterfaces);
         NetworkModelService networkModelService = new NetworkModelServiceImpl(networkTransaction, linkDiscoveryImpl,
-                portMapping);
+                portMapping, lightyServices.getBindingNotificationPublishService());
         FrequenciesService networkModelWavelengthService =
                 new FrequenciesServiceImpl(lightyServices.getBindingDataBroker());
         NetConfTopologyListener netConfTopologyListener = new NetConfTopologyListener(networkModelService,
index 5615aafa082f68a170f627c57cc2f825002c72be..c7aa9958d4684c7aee8de82bcd1952a08e48dfe7 100644 (file)
@@ -23,6 +23,8 @@ import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
 import org.opendaylight.transportpce.networkmodel.util.TopologyUtils;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkutils.rev170818.links.input.grouping.LinksInput;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1Builder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.Link1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.TerminationPoint1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.network.topology.rev200529.TerminationPoint1Builder;
@@ -64,8 +66,10 @@ final class Rdm2XpdrLink {
         String destTp = linksInput.getTerminationPointNum();
         // update tail-equipment-id for tp of link
         TerminationPoint xpdrTp = getTpofNode(srcNode, srcTp, dataBroker);
+        TerminationPoint rdmTp = getTpofNode(destNode, destTp, dataBroker);
 
-        Network topoNetowkLayer = createNetworkBuilder(srcNode, srcTp, destNode, destTp, false, xpdrTp).build();
+        Network topoNetowkLayer = createNetworkBuilder(srcNode, srcTp, destNode, destTp, false, xpdrTp,
+                rdmTp).build();
         InstanceIdentifier.InstanceIdentifierBuilder<Network> nwIID = InstanceIdentifier.builder(Networks.class)
             .child(Network.class, new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)));
         WriteTransaction wrtx = dataBroker.newWriteOnlyTransaction();
@@ -92,8 +96,10 @@ final class Rdm2XpdrLink {
         String destTp = new StringBuilder("XPDR").append(linksInput.getXpdrNum()).append("-NETWORK")
             .append(linksInput.getNetworkNum()).toString();
         TerminationPoint xpdrTp = getTpofNode(destNode, destTp, dataBroker);
+        TerminationPoint rdmTp = getTpofNode(srcNode, srcTp, dataBroker);
 
-        Network topoNetowkLayer = createNetworkBuilder(srcNode, srcTp, destNode, destTp, true, xpdrTp).build();
+        Network topoNetowkLayer = createNetworkBuilder(srcNode, srcTp, destNode, destTp, true, xpdrTp,
+                rdmTp).build();
         InstanceIdentifier.InstanceIdentifierBuilder<Network> nwIID =
             InstanceIdentifier.builder(Networks.class).child(Network.class,
                 new NetworkKey(new NetworkId(NetworkUtils.OVERLAY_NETWORK_ID)));
@@ -112,7 +118,7 @@ final class Rdm2XpdrLink {
     }
 
     private static NetworkBuilder createNetworkBuilder(String srcNode, String srcTp, String destNode, String destTp,
-        boolean isXponderInput, TerminationPoint xpdrTp) {
+        boolean isXponderInput, TerminationPoint xpdrTp, TerminationPoint rdmTp) {
         //update tp of nodes
         TerminationPointBuilder xpdrTpBldr = new TerminationPointBuilder(xpdrTp);
         if (xpdrTpBldr.augmentation(TerminationPoint1.class) != null) {
@@ -142,6 +148,15 @@ final class Rdm2XpdrLink {
             = new Link1Builder()
                 .setLinkType(isXponderInput ? OpenroadmLinkType.XPONDERINPUT : OpenroadmLinkType.XPONDEROUTPUT)
                 .setOppositeLink(LinkIdUtil.getOppositeLinkId(srcNode, srcTp, destNode, destTp));
+        // If both TPs of the Xpdr2Rdm link are inService --> link inService. Otherwise outOfService
+        if (State.InService.equals(xpdrTp.augmentation(org.opendaylight.yang.gen.v1.http
+                    .org.openroadm.common.network.rev200529.TerminationPoint1.class).getOperationalState())
+                && State.InService.equals(rdmTp.augmentation(org.opendaylight.yang.gen.v1.http
+                    .org.openroadm.common.network.rev200529.TerminationPoint1.class).getOperationalState())) {
+            lnk2bldr.setOperationalState(State.InService).setAdministrativeState(AdminStates.InService);
+        } else {
+            lnk2bldr.setOperationalState(State.OutOfService).setAdministrativeState(AdminStates.OutOfService);
+        }
         LinkBuilder linkBuilder = TopologyUtils.createLink(srcNode, destNode, srcTp, destTp, null)
             .addAugmentation(lnk2bldr.build());
 
index 42665ef5fbea328ba316d89db38c6cb5ee21a2ee..a184642af42a6ff702b3c961764ca24dd4539147 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.transportpce.networkmodel.service;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -19,6 +20,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.transportpce.common.NetworkUtils;
 import org.opendaylight.transportpce.common.mapping.PortMapping;
@@ -30,6 +32,11 @@ import org.opendaylight.transportpce.networkmodel.util.LinkIdUtil;
 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmNetwork;
 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmOtnTopology;
 import org.opendaylight.transportpce.networkmodel.util.OpenRoadmTopology;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResult;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.TopologyUpdateResultBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.OrdTopologyChanges;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.OrdTopologyChangesBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.OrdTopologyChangesKey;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.NodeInfo;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev201012.network.nodes.NodeInfo.OpenroadmVersion;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1Builder;
@@ -41,6 +48,7 @@ import org.opendaylight.yang.gen.v1.http.org.openroadm.device.types.rev191129.No
 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.Link1;
 import org.opendaylight.yang.gen.v1.http.org.openroadm.otn.network.topology.rev200529.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.d._interface.ord.topology.types.rev201116.TopologyNotificationTypes;
 import org.opendaylight.yang.gen.v1.http.transportpce.topology.rev201019.OtnLinkType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
@@ -80,9 +88,14 @@ public class NetworkModelServiceImpl implements NetworkModelService {
     // Maps that include topology component changed with its new operational state <id, state>
     private Map<String, State> linksChanged;
     private Map<String, State> terminationPointsChanged;
+    // Variables for creating and sending topology update notification
+    private final NotificationPublishService notificationPublishService;
+    private Map<OrdTopologyChangesKey, OrdTopologyChanges> topologyChanges;
+    private TopologyUpdateResult notification = null;
 
     public NetworkModelServiceImpl(final NetworkTransactionService networkTransactionService,
-            final R2RLinkDiscovery linkDiscovery, PortMapping portMapping) {
+            final R2RLinkDiscovery linkDiscovery, PortMapping portMapping,
+            final NotificationPublishService notificationPublishService) {
 
         this.networkTransactionService = networkTransactionService;
         this.linkDiscovery = linkDiscovery;
@@ -91,6 +104,8 @@ public class NetworkModelServiceImpl implements NetworkModelService {
         this.otnTopologyShardMountedDevice = new HashMap<String, TopologyShard>();
         this.linksChanged = new HashMap<String, State>();
         this.terminationPointsChanged = new HashMap<String, State>();
+        this.notificationPublishService = notificationPublishService;
+        this.topologyChanges = new HashMap<OrdTopologyChangesKey, OrdTopologyChanges>();
     }
 
     public void init() {
@@ -268,6 +283,7 @@ public class NetworkModelServiceImpl implements NetworkModelService {
         // Clear maps for each NETCONF notification received
         this.linksChanged.clear();
         this.terminationPointsChanged.clear();
+        this.topologyChanges.clear();
         // 1. Get the list links and nodes of the current openroadm network topology
         List<Link> linkList = null;
         List<Node> nodesList = null;
@@ -314,7 +330,8 @@ public class NetworkModelServiceImpl implements NetworkModelService {
                 updateOpenRoadmNetworkTopologyTPs(nodesList, nodeId);
                 // 4. Update the links of the topology affected by the changes on TPs (if any)
                 updateOpenRoadmNetworkTopologyLinks(linkList, nodesList);
-                // TODO: send notification to service handler
+                // Send notification to service handler
+                sendNotification(TopologyNotificationTypes.OpenroadmTopologyUpdate, this.topologyChanges);
                 break;
             case "port":
                 LOG.info("port circuit pack modified");
@@ -764,14 +781,26 @@ public class NetworkModelServiceImpl implements NetworkModelService {
                                 newTpOperationalState = State.InService;
                                 // Add TP and state inService to the links Map
                                 this.linksChanged.put(tpId, State.InService);
-                                // TODO: update change list for service handler notification
+                                // Update topology change list for service handler notification
+                                this.topologyChanges.put(
+                                    new OrdTopologyChangesKey(node.getNodeId().getValue() + "-" + tpId),
+                                    new OrdTopologyChangesBuilder()
+                                        .setId(node.getNodeId().getValue() + "-" + tpId)
+                                        .setState(newTpOperationalState)
+                                        .build());
                                 break;
                             case OutOfService:
                                 newTpAdminState = AdminStates.OutOfService;
                                 newTpOperationalState = State.OutOfService;
                                 // Add TP and state outOfService to the links Map
                                 this.linksChanged.put(tpId, State.OutOfService);
-                                // TODO: update change list for service handler notification
+                                // Update topology change list for service handler notification
+                                this.topologyChanges.put(
+                                    new OrdTopologyChangesKey(node.getNodeId().getValue() + "-" + tpId),
+                                    new OrdTopologyChangesBuilder()
+                                        .setId(node.getNodeId().getValue() + "-" + tpId)
+                                        .setState(newTpOperationalState)
+                                        .build());
                                 break;
                             case Degraded:
                                 LOG.warn("Operational state Degraded not handled");
@@ -905,6 +934,9 @@ public class NetworkModelServiceImpl implements NetworkModelService {
 
     private void updateLinkStates(Link link, State state, AdminStates adminStates) {
         // TODO: add change to list of changes
+        // Update topology change list
+        this.topologyChanges.put(new OrdTopologyChangesKey(link.getLinkId().getValue()),
+                new OrdTopologyChangesBuilder().setId(link.getLinkId().getValue()).setState(state).build());
         org.opendaylight.yang.gen.v1.http.org.openroadm.common.network.rev200529.Link1 link1 = new Link1Builder()
             .setOperationalState(state).setAdministrativeState(adminStates).build();
         Link updLink = new LinkBuilder().withKey(link.key()).addAugmentation(link1).build();
@@ -921,4 +953,23 @@ public class NetworkModelServiceImpl implements NetworkModelService {
             LOG.error("Couldnt commit changed to openroadm topology. Error={}", e.getMessage());
         }
     }
+
+    @SuppressFBWarnings(
+            value = "UPM_UNCALLED_PRIVATE_METHOD",
+            justification = "false positive, this method is used by public updateOpenRoadmNetworkTopology")
+    private void sendNotification(TopologyNotificationTypes notificationType,
+                                  Map<OrdTopologyChangesKey, OrdTopologyChanges> topologyChangesMap) {
+        if (topologyChangesMap.isEmpty()) {
+            LOG.warn("Empty Topology Change map. No updates in topology");
+            return;
+        }
+        TopologyUpdateResultBuilder topologyUpdateResultBuilder = new TopologyUpdateResultBuilder()
+                .setNotificationType(notificationType).setOrdTopologyChanges(topologyChangesMap);
+        this.notification = topologyUpdateResultBuilder.build();
+        try {
+            notificationPublishService.putNotification(this.notification);
+        } catch (InterruptedException e) {
+            LOG.error("Notification offer rejected. Error={}", e.getMessage());
+        }
+    }
 }
index 7b3e161eab7f17e8b4d6ec87b24b99462a1644d2..40a5b9ec78c9590b3d59033a95983a0c01992010 100644 (file)
     <reference id="networkTransactionImpl" interface="org.opendaylight.transportpce.common.network.NetworkTransactionService" />
     <reference id="mappingUtils" interface="org.opendaylight.transportpce.common.mapping.MappingUtils" />
     <reference id="notificationService" interface="org.opendaylight.mdsal.binding.api.NotificationService"/>
+    <reference id="notificationPublishService" interface="org.opendaylight.mdsal.binding.api.NotificationPublishService"/>
 
     <bean id="networkModelService" class="org.opendaylight.transportpce.networkmodel.service.NetworkModelServiceImpl">
         <argument ref="networkTransactionImpl" />
         <argument ref="linkDiscoveryImpl" />
         <argument ref="portMapping" />
+        <argument ref="notificationPublishService" />
     </bean>
 
     <bean id="provider" class="org.opendaylight.transportpce.networkmodel.NetworkModelProvider"
index 4852cc6bea44d528bfa3047acd070696dd4b3755..d7cfab0e13ac2feb4481b7553b25c53c0f9dea7b 100644 (file)
@@ -227,6 +227,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
                 .ServiceDeleteInput serviceDeleteInput =
             ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
@@ -268,6 +269,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         LOG.debug(SERVICE_FEASABILITY_CHECK_MSG, LogMessages.PCE_CALLING);
         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
         if (output == null) {
@@ -307,6 +309,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
                 .ServiceDeleteInput serviceDeleteInput =
                         ModelMappingUtils.createServiceDeleteInput(new ServiceInput(input));
@@ -387,6 +390,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(serviceInput);
         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
                     new ServiceInput(deleteInputBldr.build()));
@@ -453,6 +457,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.pceListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(serviceInput);
         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125
             .ServiceDeleteInput serviceDeleteInput = ModelMappingUtils.createServiceDeleteInput(
                     new ServiceInput(deleteInputBldr.build()));
@@ -530,6 +535,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.rendererListenerImpl.setserviceDataStoreOperations(this.serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
         this.rendererListenerImpl.setTempService(true);
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.rev201125.ServiceDeleteOutput output =
                 this.rendererServiceWrapper.performRenderer(input, ServiceNotificationTypes.ServiceDeleteResult);
         if (output == null) {
@@ -567,6 +573,7 @@ public class ServicehandlerImpl implements OrgOpenroadmServiceService {
         this.rendererListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         this.rendererListenerImpl.setServiceInput(new ServiceInput(input));
         this.rendererListenerImpl.setTempService(true);
+        this.networkModelListenerImpl.setserviceDataStoreOperations(serviceDataStoreOperations);
         PathComputationRequestOutput output = this.pceServiceWrapper.performPCE(input, true);
         if (output == null) {
             LOG.warn(TEMP_SERVICE_CREATE_MSG, LogMessages.ABORT_PCE_FAILED);