Merge "Activate Swagger for Lighty"
[transportpce.git] / servicehandler / src / main / java / org / opendaylight / transportpce / servicehandler / listeners / NetworkModelListenerImpl.java
index be0eb888d3b59228ba353a0cd27f2bcd5758c2d6..150cd98c72fba435847fa033b0f7cb5b3a051d29 100644 (file)
  */
 package org.opendaylight.transportpce.servicehandler.listeners;
 
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.stream.Collectors;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
 import org.opendaylight.transportpce.common.OperationResult;
 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
 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.TransportpceNetworkmodelListener;
-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.OrdTopologyChangesKey;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates;
-import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.AToZDirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.AToZDirectionBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ZToADirection;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ZToADirectionBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZ;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.atoz.direction.AToZKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToA;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToABuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.path.description.ztoa.direction.ZToAKey;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.Resource;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.ResourceBuilder;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.Link;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.Node;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev201210.pce.resource.resource.resource.TerminationPoint;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.service.path.PathDescription;
-import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev200128.service.path.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChanges;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.Services;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.AToZDirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirection;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ZToADirectionBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZ;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.atoz.direction.AToZKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToA;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToABuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.path.description.ztoa.direction.ZToAKey;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.Resource;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.Link;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPoint;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.path.PathDescription;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.service.types.rev220118.service.path.PathDescriptionBuilder;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.ServicePathList;
 import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NetworkModelListenerImpl implements TransportpceNetworkmodelListener {
+@Component
+public class NetworkModelListenerImpl implements TransportpceNetworkmodelListener, NetworkListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetworkModelListenerImpl.class);
-    private final NotificationPublishService notificationPublishService; // to be used for T-API notification
     private ServiceDataStoreOperations serviceDataStoreOperations;
     private TopologyUpdateResult topologyUpdateResult;
 
-    public NetworkModelListenerImpl(NotificationPublishService notificationPublishService,
-                                    ServiceDataStoreOperations serviceDataStoreOperations) {
-        this.notificationPublishService = notificationPublishService;
+    @Activate
+    public NetworkModelListenerImpl(@Reference NotificationPublishService notificationPublishService,
+            @Reference ServiceDataStoreOperations serviceDataStoreOperations) {
         this.serviceDataStoreOperations = serviceDataStoreOperations;
     }
 
     @Override
     public void onTopologyUpdateResult(TopologyUpdateResult notification) {
-        LOG.info("Topology update notification: {}", notification.toString());
+        LOG.debug("Topology update notification: {}", notification);
         if (compareTopologyUpdateResult(notification)) {
             LOG.warn("TopologyUpdateResult already wired !");
             return;
         }
-        topologyUpdateResult = notification;
-        switch (topologyUpdateResult.getNotificationType().getIntValue()) {
-            case 1:
-                // Update service datastore and service path description
-                LOG.info("openroadm-topology update");
-                updateServicePaths(notification);
-                break;
-            case 2:
-                LOG.info("openroadm-network update");
-                break;
-            case 3:
-                LOG.info("clli-network update");
-                break;
-            case 4:
-                LOG.info("otn-topology update");
-                break;
-            default:
-                break;
-        }
+        topologyUpdateResult = new TopologyUpdateResultBuilder()
+                .setTopologyChanges(new HashMap<>(notification.getTopologyChanges()))
+                .build();
+        // Update service datastore and service path description
+        updateServicePaths(notification);
     }
 
     /**
      * Process topology update result.
      * @param notification the result notification.
      */
-    private void updateServicePaths(TopologyUpdateResult notification) {
-        Map<OrdTopologyChangesKey, OrdTopologyChanges> ordTopologyChanges = notification.getOrdTopologyChanges();
+    protected void updateServicePaths(TopologyUpdateResult notification) {
+        @Nullable
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = notification.getTopologyChanges();
         Optional<ServicePathList> servicePathListOptional = this.serviceDataStoreOperations.getServicePaths();
-        ServicePathList servicePathList = null;
-        if (!servicePathListOptional.isPresent()) {
-            LOG.error("Couldn't retrieve service path list");
-            return;
-        }
-        servicePathList = servicePathListOptional.get();
-        if (servicePathList.getServicePaths().isEmpty()) {
+        if (servicePathListOptional.isEmpty()) {
+            LOG.warn("Enable to retrieve service path list");
             return;
         }
+        ServicePathList servicePathList = servicePathListOptional.get();
         for (ServicePaths servicePaths : servicePathList.getServicePaths().values()) {
             String serviceName = servicePaths.getServicePathName();
             PathDescription pathDescription = servicePaths.getPathDescription();
             // update path descriptions in the datastore
-            Map<AToZKey, AToZ> updatedAtoZ = changePathElementStateAZ(ordTopologyChanges, pathDescription);
-            Map<ZToAKey, ZToA> updatedZtoA = changePathElementStateZA(ordTopologyChanges, pathDescription);
+            Map<AToZKey, AToZ> updatedAtoZ = changePathElementStateAZ(topologyChanges, pathDescription);
+            Map<ZToAKey, ZToA> updatedZtoA = changePathElementStateZA(topologyChanges, pathDescription);
             OperationResult operationResult = this.serviceDataStoreOperations
                     .modifyServicePath(buildNewPathDescription(pathDescription, updatedAtoZ, updatedZtoA), serviceName);
             if (!operationResult.isSuccess()) {
@@ -116,176 +103,139 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
             // update service in the datastore. Only path description with all elements in service can have a service
             // in service. Therefore we check if all the states of the path description resources are inService
             Optional<Services> serviceOptional = this.serviceDataStoreOperations.getService(serviceName);
-            Services services = null;
-            if (!serviceOptional.isPresent()) {
+            if (serviceOptional.isEmpty()) {
                 LOG.error("Couldn't retrieve service");
                 continue;
             }
-            services = serviceOptional.get();
-            OperationResult operationResult1 = null;
-            if (State.InService.equals(services.getOperationalState())
-                    && !allElementsinPathinService(updatedAtoZ, updatedZtoA)) {
-                LOG.info("Service={} needs to be updated to outOfService", serviceName);
-                operationResult1 = this.serviceDataStoreOperations.modifyService(serviceName, State.OutOfService,
-                        AdminStates.OutOfService);
-            } else if (State.OutOfService.equals(services.getOperationalState())
-                    && allElementsinPathinService(updatedAtoZ, updatedZtoA)) {
-                LOG.info("Service={} needs to be updated to inService", serviceName);
-                operationResult1 = this.serviceDataStoreOperations.modifyService(serviceName, State.InService,
-                        AdminStates.InService);
-            } else {
-                LOG.info("Service {} state doesnt need to be modified", serviceName);
-            }
-            if (operationResult1 != null && operationResult1.isSuccess()) {
-                LOG.info("Service state correctly updated in datastore");
-            }
-        }
-    }
-
-    private Map<ZToAKey, ZToA> changePathElementStateZA(Map<OrdTopologyChangesKey,
-            OrdTopologyChanges> ordTopologyChanges, PathDescription pathDescription) {
-        Map<ZToAKey, ZToA> ztoaMap = pathDescription.getZToADirection().getZToA();
-        // Needed as ztoaMap is immutable
-        Map<ZToAKey, ZToA> newztoaMap = new HashMap<ZToAKey, ZToA>();
-        for (ZToA element : ztoaMap.values()) {
-            org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State elementState
-                    = element.getResource().getState();
-            String elementType = element.getResource().getResource().implementedInterface().getSimpleName();
-            org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State updatedState = null;
-            ZToAKey elementKey = null;
-            Resource elementResource = null;
-            switch (elementType) {
-                case "TerminationPoint":
-                    TerminationPoint tp = (TerminationPoint) element.getResource().getResource();
-                    // for the tps we need to merge nodeId and tpId
-                    String tpId = tp.getTpNodeId() + "-" + tp.getTpId();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(tpId))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(tpId)).getState()
-                            .equals(elementState))) {
-                        newztoaMap.put(element.key(), element);
-                        continue;
-                    }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(tpId)).getState();
-                    LOG.info("Updating path element {} to {}", tpId, updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new ZToAKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(tp).setState(updatedState).build();
-                    ZToA tpResource = new ZToABuilder().setId(tp.getTpId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newztoaMap.put(elementKey, tpResource);
-                    break;
-                case "Link":
-                    Link link = (Link) element.getResource().getResource();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(link.getLinkId()))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(link.getLinkId())).getState()
-                            .equals(elementState))) {
-                        newztoaMap.put(element.key(), element);
+            Services services = serviceOptional.get();
+            State newState;
+            switch (services.getOperationalState()) {
+                case InService:
+                    if (allElementsinPathinService(updatedAtoZ, updatedZtoA)) {
+                        LOG.debug("Service {} state does not need to be modified", serviceName);
                         continue;
                     }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(link.getLinkId())).getState();
-                    LOG.info("Updating path element {} to {}", link.getLinkId(), updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new ZToAKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(link).setState(updatedState).build();
-                    ZToA linkResource = new ZToABuilder().setId(link.getLinkId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newztoaMap.put(elementKey, linkResource);
+                    newState = State.OutOfService;
                     break;
-                case "Node":
-                    Node node = (Node) element.getResource().getResource();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(node.getNodeId()))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(node.getNodeId())).getState()
-                            .equals(elementState))) {
-                        newztoaMap.put(element.key(), element);
+                case OutOfService:
+                    if (!allElementsinPathinService(updatedAtoZ, updatedZtoA)) {
+                        LOG.debug("Service {} state does not need to be modified", serviceName);
                         continue;
                     }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(node.getNodeId())).getState();
-                    LOG.info("Updating path element {} to {}", node.getNodeId(), updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new ZToAKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(node).setState(updatedState).build();
-                    ZToA nodeResource = new ZToABuilder().setId(node.getNodeId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newztoaMap.put(elementKey, nodeResource);
+                    newState = State.InService;
                     break;
                 default:
-                    LOG.warn("Element type {} not recognized", elementType);
-                    break;
+                    LOG.warn("Service {} state not managed", serviceName);
+                    continue;
+            }
+
+
+            LOG.debug("Service={} needs to be updated to {}", serviceName, newState);
+            //if (operationResult1 != null && operationResult1.isSuccess()) {
+            //null check probably no more needed
+            if (this.serviceDataStoreOperations
+                    .modifyService(serviceName, newState, services.getAdministrativeState())
+                    .isSuccess()) {
+                LOG.info("Service state of {} correctly updated to {} in datastore", serviceName, newState);
+                continue;
             }
+            LOG.error("Service state of {} cannot be updated to {} in datastore", serviceName, newState);
+
         }
-        return newztoaMap;
     }
 
-    private Map<AToZKey, AToZ> changePathElementStateAZ(Map<OrdTopologyChangesKey,
-            OrdTopologyChanges> ordTopologyChanges, PathDescription pathDescription) {
-        Map<AToZKey, AToZ> atozMap = pathDescription.getAToZDirection().getAToZ();
-        // Needed as atozMap is immutable
-        Map<AToZKey, AToZ> newatozMap = new HashMap<AToZKey, AToZ>();
-        for (AToZ element : atozMap.values()) {
-            org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State elementState
-                = element.getResource().getState();
-            String elementType = element.getResource().getResource().implementedInterface().getSimpleName();
-            org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State updatedState = null;
-            AToZKey elementKey = null;
-            Resource elementResource = null;
-            switch (elementType) {
-                case "TerminationPoint":
-                    TerminationPoint tp = (TerminationPoint) element.getResource().getResource();
-                    // for the tps we need to merge nodeId and tpId
-                    String tpId = tp.getTpNodeId() + "-" + tp.getTpId();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(tpId))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(tpId)).getState()
-                            .equals(elementState))) {
-                        newatozMap.put(element.key(), element);
-                        continue;
-                    }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(tpId)).getState();
-                    LOG.info("Updating path element {} to {}", tpId, updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new AToZKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(tp).setState(updatedState).build();
-                    AToZ tpResource = new AToZBuilder().setId(tp.getTpId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newatozMap.put(elementKey, tpResource);
-                    break;
-                case "Link":
-                    Link link = (Link) element.getResource().getResource();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(link.getLinkId()))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(link.getLinkId())).getState()
-                            .equals(elementState))) {
-                        newatozMap.put(element.key(), element);
-                        continue;
+    protected Map<ZToAKey, ZToA> changePathElementStateZA(Map<TopologyChangesKey, TopologyChanges> topologyChanges,
+        PathDescription pathDescription) {
+        Map<ZToAKey, ZToA> newztoaMap = new HashMap<>(pathDescription.getZToADirection().getZToA());
+        List<ZToA> tpResources = pathDescription.getZToADirection().getZToA().values().stream()
+                .filter(ele -> ele.getResource().getResource() instanceof TerminationPoint)
+                .collect(Collectors.toList());
+        List<ZToA> linkResources = pathDescription.getZToADirection().getZToA().values().stream()
+            .filter(ele -> ele.getResource().getResource() instanceof Link)
+            .collect(Collectors.toList());
+        for (ZToA ztoA : tpResources) {
+            String ztoAid = ztoA.getId();
+            State ztoAState = ztoA.getResource().getState();
+            TerminationPoint tp = (TerminationPoint) ztoA.getResource().getResource();
+            if (topologyChanges.containsKey(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId()))
+                && !topologyChanges.get(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId())).getState()
+                .equals(ztoAState)) {
+                LOG.debug("updating ztoa tp {}", ztoA);
+                State updatedState = topologyChanges.get(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId()))
+                    .getState();
+                Resource updatedResource = new ResourceBuilder()
+                    .setResource(tp)
+                    .setState(updatedState)
+                    .build();
+                ZToA updatedZToA = new ZToABuilder(ztoA)
+                    .setId(ztoAid)
+                    .setResource(updatedResource)
+                    .build();
+                newztoaMap.put(updatedZToA.key(), updatedZToA);
+                for (ZToA ztoALink : linkResources) {
+                    Link link = (Link)ztoALink.getResource().getResource();
+                    if (link.getLinkId().contains(tp.getTpNodeId())
+                            && link.getLinkId().contains(tp.getTpId())
+                            && ztoALink.getResource().getState() != updatedState) {
+                        ZToA updatedZToAlink = new ZToABuilder(ztoALink)
+                            .setId(ztoAid)
+                            .setResource(new ResourceBuilder()
+                                .setResource(link)
+                                .setState(updatedState)
+                                .build())
+                            .build();
+                        newztoaMap.put(updatedZToAlink.key(), updatedZToAlink);
                     }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(link.getLinkId()))
-                            .getState();
-                    LOG.info("Updating path element {} to {}", link.getLinkId(), updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new AToZKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(link).setState(updatedState).build();
-                    AToZ linkResource = new AToZBuilder().setId(link.getLinkId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newatozMap.put(elementKey, linkResource);
-                    break;
-                case "Node":
-                    Node node = (Node) element.getResource().getResource();
-                    if (!(ordTopologyChanges.containsKey(new OrdTopologyChangesKey(node.getNodeId()))
-                            && !ordTopologyChanges.get(new OrdTopologyChangesKey(node.getNodeId())).getState()
-                            .equals(elementState))) {
-                        newatozMap.put(element.key(), element);
-                        continue;
+                }
+            }
+        }
+        return newztoaMap;
+    }
+
+    protected Map<AToZKey, AToZ> changePathElementStateAZ(Map<TopologyChangesKey,
+            TopologyChanges> topologyChanges, PathDescription pathDescription) {
+
+        Map<AToZKey, AToZ> newatozMap = new HashMap<>(pathDescription.getAToZDirection().getAToZ());
+        List<AToZ> tpResources = pathDescription.getAToZDirection().getAToZ().values().stream()
+            .filter(ele -> ele.getResource().getResource() instanceof TerminationPoint)
+            .collect(Collectors.toList());
+        List<AToZ> linkResources = pathDescription.getAToZDirection().getAToZ().values().stream()
+            .filter(ele -> ele.getResource().getResource() instanceof Link)
+            .collect(Collectors.toList());
+        for (AToZ atoZ : tpResources) {
+            String atoZid = atoZ.getId();
+            State atoZState = atoZ.getResource().getState();
+            TerminationPoint tp = (TerminationPoint) atoZ.getResource().getResource();
+            if (topologyChanges.containsKey(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId()))
+                && !topologyChanges.get(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId())).getState()
+                .equals(atoZState)) {
+                LOG.debug("updating atoz tp {}", atoZ);
+                State updatedState = topologyChanges.get(new TopologyChangesKey(tp.getTpNodeId(), tp.getTpId()))
+                    .getState();
+                Resource updatedResource = new ResourceBuilder()
+                    .setResource(tp)
+                    .setState(updatedState)
+                    .build();
+                AToZ updatedAToZ = new AToZBuilder(atoZ)
+                    .setId(atoZid)
+                    .setResource(updatedResource)
+                    .build();
+                newatozMap.put(updatedAToZ.key(), updatedAToZ);
+                for (AToZ atozLink : linkResources) {
+                    Link link = (Link)atozLink.getResource().getResource();
+                    if (link.getLinkId().contains(tp.getTpNodeId())
+                            && link.getLinkId().contains(tp.getTpId())
+                            && atozLink.getResource().getState() != updatedState) {
+                        AToZ updatedAToZlink = new AToZBuilder(atozLink)
+                            .setId(atoZid)
+                            .setResource(new ResourceBuilder()
+                                .setResource(link)
+                                .setState(updatedState)
+                                .build())
+                            .build();
+                        newatozMap.put(updatedAToZlink.key(), updatedAToZlink);
                     }
-                    updatedState = ordTopologyChanges.get(new OrdTopologyChangesKey(node.getNodeId())).getState();
-                    LOG.info("Updating path element {} to {}", node.getNodeId(), updatedState.getName());
-                    // Create new resource element and replace on map
-                    elementKey = new AToZKey(element.getId());
-                    elementResource = new ResourceBuilder().setResource(node).setState(updatedState).build();
-                    AToZ nodeResource = new AToZBuilder().setId(node.getNodeId()).withKey(elementKey)
-                            .setResource(elementResource).build();
-                    newatozMap.put(elementKey, nodeResource);
-                    break;
-                default:
-                    LOG.warn("Element type {} not recognized", elementType);
-                    break;
+                }
             }
         }
         return newatozMap;
@@ -293,28 +243,19 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
 
     private PathDescription buildNewPathDescription(PathDescription pathDescription, Map<AToZKey, AToZ> updatedAtoZ,
                                                     Map<ZToAKey, ZToA> updatedZtoA) {
-        // A to Z
-        AToZDirection atozDir = new AToZDirectionBuilder()
+        AToZDirection atozDir = new AToZDirectionBuilder(pathDescription.getAToZDirection())
                 .setAToZ(updatedAtoZ)
-                .setAToZWavelengthNumber(pathDescription.getAToZDirection().getAToZWavelengthNumber())
-                .setModulationFormat(pathDescription.getAToZDirection().getModulationFormat())
-                .setRate(pathDescription.getAToZDirection().getRate())
-                .setTribPortNumber(pathDescription.getAToZDirection().getTribPortNumber())
-                .setTribSlotNumber(pathDescription.getAToZDirection().getTribSlotNumber())
                 .build();
-        // Z to A
-        ZToADirection ztoaDir = new ZToADirectionBuilder()
+        ZToADirection ztoaDir = new ZToADirectionBuilder(pathDescription.getZToADirection())
                 .setZToA(updatedZtoA)
-                .setZToAWavelengthNumber(pathDescription.getZToADirection().getZToAWavelengthNumber())
-                .setModulationFormat(pathDescription.getZToADirection().getModulationFormat())
-                .setRate(pathDescription.getAToZDirection().getRate())
-                .setTribPortNumber(pathDescription.getAToZDirection().getTribPortNumber())
-                .setTribSlotNumber(pathDescription.getAToZDirection().getTribSlotNumber())
                 .build();
-        return new PathDescriptionBuilder().setAToZDirection(atozDir).setZToADirection(ztoaDir).build();
+        return new PathDescriptionBuilder()
+            .setAToZDirection(atozDir)
+            .setZToADirection(ztoaDir)
+            .build();
     }
 
-    private boolean allElementsinPathinService(Map<AToZKey, AToZ> updatedAtoZ, Map<ZToAKey, ZToA> updatedZtoA) {
+    protected boolean allElementsinPathinService(Map<AToZKey, AToZ> updatedAtoZ, Map<ZToAKey, ZToA> updatedZtoA) {
         boolean allEleminService = true;
         Iterator<AToZ> i1 = updatedAtoZ.values().iterator();
         Iterator<ZToA> i2 = updatedZtoA.values().iterator();
@@ -330,23 +271,12 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
         return allEleminService;
     }
 
-    @SuppressFBWarnings(
-            value = "ES_COMPARING_STRINGS_WITH_EQ",
-            justification = "false positives, not strings but real object references comparisons")
     private boolean compareTopologyUpdateResult(TopologyUpdateResult notification) {
-        if (topologyUpdateResult == null) {
-            return false;
-        }
-        if (topologyUpdateResult.getNotificationType() != notification.getNotificationType()) {
-            return false;
-        }
-        if (topologyUpdateResult.getOrdTopologyChanges().values()
-                .equals(notification.getOrdTopologyChanges().values())) {
-            return false;
-        }
-        return true;
+        return topologyUpdateResult != null
+                && topologyUpdateResult.getTopologyChanges().equals(notification.getTopologyChanges());
     }
 
+    @Override
     public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
         this.serviceDataStoreOperations = serviceData;
     }