Fix issues in listeners 54/101454/6
authorThierry Jiao <thierry.jiao@orange.com>
Wed, 25 May 2022 14:31:58 +0000 (16:31 +0200)
committerGuillaume Lambert <guillaume.lambert@orange.com>
Thu, 30 Jun 2022 07:05:55 +0000 (07:05 +0000)
- In PortMappingListener, change the predicate that conditions
the topology update
- In NetworkModelListener, update only the OperationalState of
the service after the topology update (and no longer the AdminState)
- Update the functional tests accordingly
- Add JUnit tests for PortMappingListener & NetworkModelListenerImpl

JIRA: TRNSPRTPCE-668, TRNSPRTPCE-669
Signed-off-by: Thierry Jiao <thierry.jiao@orange.com>
Change-Id: Ifbc4402794830fa6e060f8f3c60132dc05e803ba

networkmodel/src/main/java/org/opendaylight/transportpce/networkmodel/listeners/PortMappingListener.java
networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/listeners/PortMappingListenerTest.java [new file with mode: 0644]
servicehandler/src/main/java/org/opendaylight/transportpce/servicehandler/listeners/NetworkModelListenerImpl.java
servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/NetworkModelListenerImplTest.java [new file with mode: 0644]
tests/transportpce_tests/hybrid/test01_device_change_notifications.py

index c862755bf177f98fa70fe79660e9d8d1dbec72f0..6ae864547dcf70a3a6f60148903f30072d374396 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Collection;
 import java.util.LinkedList;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
@@ -33,20 +34,22 @@ public class PortMappingListener implements DataTreeChangeListener<Mapping> {
                 Mapping oldMapping = change.getRootNode().getDataBefore();
                 Mapping newMapping = change.getRootNode().getDataAfter();
                 if (oldMapping.getPortAdminState().equals(newMapping.getPortAdminState())
-                    || oldMapping.getPortOperState().equals(newMapping.getPortOperState())) {
+                        && oldMapping.getPortOperState().equals(newMapping.getPortOperState())) {
                     return;
                 } else {
-                    LinkedList<PathArgument> path = new LinkedList<>();
-                    path.addAll((Collection<? extends PathArgument>) change.getRootPath().getRootIdentifier()
-                        .getPathArguments());
-                    path.removeLast();
-                    InstanceIdentifier<Nodes> portmappintNodeID = InstanceIdentifier.unsafeOf(path);
-                    //                    @SuppressWarnings("unchecked") InstanceIdentifier<Nodes> portmappintNodeID =
-//                        (InstanceIdentifier<Nodes>) InstanceIdentifier.create(path);
-                    String nodeId = InstanceIdentifier.keyOf(portmappintNodeID).getNodeId();
-                    networkModelService.updateOpenRoadmTopologies(nodeId, newMapping);
+                    networkModelService.updateOpenRoadmTopologies(
+                            getNodeIdFromMappingDataTreeIdentifier(change.getRootPath()), newMapping);
                 }
             }
         }
     }
+
+    protected String getNodeIdFromMappingDataTreeIdentifier(DataTreeIdentifier<Mapping> dataTreeIdentifier) {
+        LinkedList<PathArgument> path = new LinkedList<>((Collection<? extends PathArgument>)
+                dataTreeIdentifier.getRootIdentifier().getPathArguments());
+        path.removeLast();
+        InstanceIdentifier<Nodes> portMappingNodeID = InstanceIdentifier.unsafeOf(path);
+        return InstanceIdentifier.keyOf(portMappingNodeID).getNodeId();
+
+    }
 }
diff --git a/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/listeners/PortMappingListenerTest.java b/networkmodel/src/test/java/org/opendaylight/transportpce/networkmodel/listeners/PortMappingListenerTest.java
new file mode 100644 (file)
index 0000000..32ec06a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2022 Orange.  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.networkmodel.listeners;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collection;
+import java.util.HashSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.mdsal.binding.api.DataObjectModification;
+import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev220316.mapping.Mapping;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class PortMappingListenerTest {
+
+    @Mock
+    private NetworkModelService networkModelService;
+    private PortMappingListener portMappingListenerSpy;
+
+    @Before
+    public void setUp() {
+        portMappingListenerSpy = Mockito.spy(new PortMappingListener(networkModelService));
+        doReturn("NodeID").when(portMappingListenerSpy).getNodeIdFromMappingDataTreeIdentifier(any());
+    }
+
+    @Test
+    public void testOnDataTreeChangedWhenMappingOperAndAdminDidntChange() {
+        final Collection<DataTreeModification<Mapping>> changes = new HashSet<>();
+        @SuppressWarnings("unchecked") final DataTreeModification<Mapping> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        @SuppressWarnings("unchecked") final DataObjectModification<Mapping> mappingObject =
+                mock(DataObjectModification.class);
+        final Mapping oldMapping = mock(Mapping.class);
+        final Mapping newMapping = mock(Mapping.class);
+
+        when(ch.getRootNode()).thenReturn(mappingObject);
+        when(mappingObject.getDataBefore()).thenReturn(oldMapping);
+        when(mappingObject.getDataAfter()).thenReturn(newMapping);
+        when(oldMapping.getPortAdminState()).thenReturn("InService");
+        when(oldMapping.getPortOperState()).thenReturn("InService");
+        when(newMapping.getPortAdminState()).thenReturn("InService");
+        when(newMapping.getPortOperState()).thenReturn("InService");
+
+        portMappingListenerSpy.onDataTreeChanged(changes);
+        verify(networkModelService, never()).updateOpenRoadmTopologies(anyString(), any(Mapping.class));
+    }
+
+    @Test
+    public void testOnDataTreeChangedWhenMappingAdminChanged() {
+        final Collection<DataTreeModification<Mapping>> changes = new HashSet<>();
+        @SuppressWarnings("unchecked") final DataTreeModification<Mapping> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        @SuppressWarnings("unchecked") final DataObjectModification<Mapping> mappingObject =
+                mock(DataObjectModification.class);
+        final Mapping oldMapping = mock(Mapping.class);
+        final Mapping newMapping = mock(Mapping.class);
+
+        when(ch.getRootNode()).thenReturn(mappingObject);
+        when(mappingObject.getDataBefore()).thenReturn(oldMapping);
+        when(mappingObject.getDataAfter()).thenReturn(newMapping);
+        when(oldMapping.getPortAdminState()).thenReturn("InService");
+        when(newMapping.getPortAdminState()).thenReturn("OutOfService");
+
+        portMappingListenerSpy.onDataTreeChanged(changes);
+        verify(networkModelService, times(1)).updateOpenRoadmTopologies(anyString(), any(Mapping.class));
+    }
+
+    @Test
+    public void testOnDataTreeChangedWhenMappingOperChanged() {
+        final Collection<DataTreeModification<Mapping>> changes = new HashSet<>();
+        @SuppressWarnings("unchecked") final DataTreeModification<Mapping> ch = mock(DataTreeModification.class);
+        changes.add(ch);
+        @SuppressWarnings("unchecked") final DataObjectModification<Mapping> mappingObject =
+                mock(DataObjectModification.class);
+        final Mapping oldMapping = mock(Mapping.class);
+        final Mapping newMapping = mock(Mapping.class);
+
+        when(ch.getRootNode()).thenReturn(mappingObject);
+        when(mappingObject.getDataBefore()).thenReturn(oldMapping);
+        when(mappingObject.getDataAfter()).thenReturn(newMapping);
+        when(oldMapping.getPortAdminState()).thenReturn("InService");
+        when(oldMapping.getPortOperState()).thenReturn("InService");
+        when(newMapping.getPortAdminState()).thenReturn("InService");
+        when(newMapping.getPortOperState()).thenReturn("OutOfService");
+
+        portMappingListenerSpy.onDataTreeChanged(changes);
+        verify(networkModelService, times(1)).updateOpenRoadmTopologies(anyString(), any(Mapping.class));
+    }
+}
index b1a162a3bf2abc6f5bfbb764bb65fdaaeaf2b824..6a87f56199bf88d6a08438a9ac7253e7ea8b2b42 100644 (file)
@@ -18,11 +18,11 @@ 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.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.equipment.states.types.rev191129.AdminStates;
 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;
@@ -59,12 +59,13 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
 
     @Override
     public void onTopologyUpdateResult(TopologyUpdateResult notification) {
-        LOG.debug("Topology update notification: {}", notification.toString());
+        LOG.debug("Topology update notification: {}", notification);
         if (compareTopologyUpdateResult(notification)) {
             LOG.warn("TopologyUpdateResult already wired !");
             return;
         }
-        topologyUpdateResult = notification;
+        topologyUpdateResult = new TopologyUpdateResultBuilder().setTopologyChanges(
+                new HashMap<>(notification.getTopologyChanges())).build();
         // Update service datastore and service path description
         updateServicePaths(notification);
     }
@@ -73,16 +74,15 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
      * Process topology update result.
      * @param notification the result notification.
      */
-    private void updateServicePaths(TopologyUpdateResult notification) {
+    protected void updateServicePaths(TopologyUpdateResult notification) {
         @Nullable
         Map<TopologyChangesKey, TopologyChanges> topologyChanges = notification.getTopologyChanges();
         Optional<ServicePathList> servicePathListOptional = this.serviceDataStoreOperations.getServicePaths();
-        ServicePathList servicePathList = null;
-        if (!servicePathListOptional.isPresent()) {
+        if (servicePathListOptional.isEmpty()) {
             LOG.warn("Enable to retrieve service path list");
             return;
         }
-        servicePathList = servicePathListOptional.get();
+        ServicePathList servicePathList = servicePathListOptional.get();
         for (ServicePaths servicePaths : servicePathList.getServicePaths().values()) {
             String serviceName = servicePaths.getServicePathName();
             PathDescription pathDescription = servicePaths.getPathDescription();
@@ -98,12 +98,11 @@ 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();
+            Services services = serviceOptional.get();
             OperationResult operationResult1 = null;
             switch (services.getOperationalState()) {
                 case InService:
@@ -112,7 +111,7 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
                         //if (operationResult1 != null && operationResult1.isSuccess()) {
                         //null check probably no more needed
                         if (this.serviceDataStoreOperations
-                                .modifyService(serviceName, State.OutOfService, AdminStates.OutOfService)
+                                .modifyService(serviceName, State.OutOfService, services.getAdministrativeState())
                                 .isSuccess()) {
                             LOG.info("Service state of {} correctly updated to outOfService in datastore", serviceName);
                             continue;
@@ -128,7 +127,7 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
                         //if (operationResult1 != null && operationResult1.isSuccess()) {
                         //null check probably no more needed
                         if (this.serviceDataStoreOperations
-                                .modifyService(serviceName, State.InService, AdminStates.InService)
+                                .modifyService(serviceName, State.InService, services.getAdministrativeState())
                                 .isSuccess()) {
                             LOG.info("Service state of {} correctly updated to inService in datastore", serviceName);
                             continue;
@@ -145,14 +144,12 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
         }
     }
 
-    private Map<ZToAKey, ZToA> changePathElementStateZA(Map<TopologyChangesKey, TopologyChanges> topologyChanges,
+    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().implementedInterface().getSimpleName()
-                .equals("TerminationPoint"))
-            .collect(Collectors.toList());
+                .filter(ele -> ele.getResource().getResource() instanceof TerminationPoint)
+                .collect(Collectors.toList());
         for (ZToA ztoA : tpResources) {
             String ztoAid = ztoA.getId();
             State ztoAState = ztoA.getResource().getState();
@@ -177,13 +174,12 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
         return newztoaMap;
     }
 
-    private Map<AToZKey, AToZ> changePathElementStateAZ(Map<TopologyChangesKey,
+    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().implementedInterface().getSimpleName()
-                .equals("TerminationPoint"))
+            .filter(ele -> ele.getResource().getResource() instanceof TerminationPoint)
             .collect(Collectors.toList());
         for (AToZ atoZ : tpResources) {
             String atoZid = atoZ.getId();
@@ -223,7 +219,7 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
             .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();
@@ -240,14 +236,8 @@ public class NetworkModelListenerImpl implements TransportpceNetworkmodelListene
     }
 
     private boolean compareTopologyUpdateResult(TopologyUpdateResult notification) {
-        if (topologyUpdateResult == null) {
-            return false;
-        }
-        if (topologyUpdateResult.getTopologyChanges().values()
-                .equals(notification.getTopologyChanges().values())) {
-            return false;
-        }
-        return true;
+        return topologyUpdateResult != null && topologyUpdateResult.getTopologyChanges()
+                .equals(notification.getTopologyChanges());
     }
 
     public void setserviceDataStoreOperations(ServiceDataStoreOperations serviceData) {
diff --git a/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/NetworkModelListenerImplTest.java b/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/NetworkModelListenerImplTest.java
new file mode 100644 (file)
index 0000000..396efb9
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * Copyright © 2022 Orange, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.transportpce.servicehandler.listeners;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+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.topology.update.result.TopologyChanges;
+import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.networkmodel.rev201116.topology.update.result.TopologyChangesBuilder;
+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.equipment.states.types.rev191129.AdminStates;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.ServicesBuilder;
+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.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.ResourceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.LinkBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.NodeBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.pathdescription.rev210705.pce.resource.resource.resource.TerminationPointBuilder;
+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.ServicePathListBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePaths;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.transportpce.b.c._interface.servicepath.rev171017.service.path.list.ServicePathsKey;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NetworkModelListenerImplTest {
+
+    @Mock
+    private NotificationPublishService notificationPublishService;
+    @Mock
+    private ServiceDataStoreOperations serviceDataStoreOperations;
+    private static PathDescription pathDescription;
+    private NetworkModelListenerImpl networkModelListener;
+
+    @Before
+    public void setUp() {
+        pathDescription = new PathDescriptionBuilder()
+                .setAToZDirection(new AToZDirectionBuilder().setAToZ(new HashMap<>(createMapAtoZ())).build())
+                .setZToADirection(new ZToADirectionBuilder().setZToA(new HashMap<>(createMapZtoA())).build())
+                .build();
+        networkModelListener = new NetworkModelListenerImpl(notificationPublishService,
+                serviceDataStoreOperations);
+    }
+
+    @Test
+    public void testChangePathElementStateZAShouldNotModifyPathDescriptionsElementStates() {
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.InService)
+                        .build(),
+                new TopologyChangesKey("tpNodeIdA", "TpIdA2"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA2")
+                        .setState(State.InService)
+                        .build()
+        );
+
+        assertEquals(pathDescription.getZToADirection().getZToA(),
+                networkModelListener.changePathElementStateZA(topologyChanges, pathDescription));
+    }
+
+    @Test
+    public void testChangePathElementStateZAShouldModifyPathDescriptionsElementStates() {
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.OutOfService)
+                        .build(),
+                new TopologyChangesKey("tpNodeIdA", "TpIdA2"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA2")
+                        .setState(State.OutOfService)
+                        .build());
+
+        Map<ZToAKey, ZToA> ztoamapExpected = pathDescription.getZToADirection().getZToA();
+        ztoamapExpected.computeIfPresent(
+                new ZToAKey("6"),
+                (zToAKey, zToA) -> new ZToABuilder(zToA)
+                        .setResource(new ResourceBuilder(zToA.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        ztoamapExpected.computeIfPresent(
+                new ZToAKey("4"),
+                (zToAKey, zToA) -> new ZToABuilder(zToA)
+                        .setResource(new ResourceBuilder(zToA.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        assertEquals(ztoamapExpected, networkModelListener.changePathElementStateZA(topologyChanges, pathDescription));
+    }
+
+    @Test
+    public void testChangePathElementStateAZShouldNotModifyPathDescriptionsElementStates() {
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.InService)
+                        .build(),
+                new TopologyChangesKey("tpNodeIdA", "TpIdA2"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA2")
+                        .setState(State.InService)
+                        .build());
+
+        assertEquals(pathDescription.getAToZDirection().getAToZ(),
+                networkModelListener.changePathElementStateAZ(topologyChanges, pathDescription));
+    }
+
+    @Test
+    public void testChangePathElementStateAZShouldModifyPathDescriptionsElementStates() {
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.OutOfService)
+                        .build(),
+                new TopologyChangesKey("tpNodeIdA", "TpIdA2"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA2")
+                        .setState(State.OutOfService)
+                        .build());
+
+        Map<AToZKey, AToZ> atozmapExpected = pathDescription.getAToZDirection().getAToZ();
+        atozmapExpected.computeIfPresent(
+                new AToZKey("0"),
+                (aToZKey, aToZ) -> new AToZBuilder(aToZ)
+                        .setResource(new ResourceBuilder(aToZ.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        atozmapExpected.computeIfPresent(
+                new AToZKey("2"),
+                (aToZKey, aToZ) -> new AToZBuilder(aToZ)
+                        .setResource(new ResourceBuilder(aToZ.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        assertEquals(atozmapExpected, networkModelListener.changePathElementStateAZ(topologyChanges, pathDescription));
+    }
+
+    @Test
+    public void testAllElementsinPathinServiceShouldReturnFalse() {
+        Map<AToZKey, AToZ> atozmap = pathDescription.getAToZDirection().getAToZ();
+        atozmap.computeIfPresent(
+                new AToZKey("0"),
+                (aToZKey, aToZ) -> new AToZBuilder(aToZ)
+                        .setResource(new ResourceBuilder(aToZ.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        Map<ZToAKey, ZToA> ztoamap = pathDescription.getZToADirection().getZToA();
+        ztoamap.computeIfPresent(
+                new ZToAKey("6"),
+                (zToAKey, zToA) -> new ZToABuilder(zToA)
+                        .setResource(new ResourceBuilder(zToA.getResource())
+                                .setState(State.OutOfService)
+                                .build())
+                        .build());
+        assertFalse(networkModelListener.allElementsinPathinService(atozmap, ztoamap));
+    }
+
+    @Test
+    public void testAllElementsinPathinServiceShouldReturnTrue() {
+        assertTrue(networkModelListener.allElementsinPathinService(pathDescription.getAToZDirection().getAToZ(),
+                pathDescription.getZToADirection().getZToA()));
+    }
+
+    @Test
+    public void testUpdateServicePathsShouldNotModifyServiceState() {
+        Map<ServicePathsKey, ServicePaths> servicePathMap = Map.of(new ServicePathsKey("service-path 1"),
+                new ServicePathsBuilder()
+                        .setServicePathName("service-path 1")
+                        .setPathDescription(pathDescription)
+                        .build());
+
+        when(serviceDataStoreOperations.getServicePaths()).thenReturn(Optional.of(new ServicePathListBuilder()
+                .setServicePaths(servicePathMap).build()));
+        when(serviceDataStoreOperations.modifyServicePath(any(PathDescription.class), anyString()))
+                .thenReturn(OperationResult.ok(""));
+        when(serviceDataStoreOperations.getService(anyString())).thenReturn(Optional.of(
+                new ServicesBuilder().setServiceName("serviceTest")
+                        .setOperationalState(State.InService)
+                        .setAdministrativeState(AdminStates.InService)
+                        .build()));
+
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdC", "TpIdC1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdC")
+                        .setTpId("TpIdC1")
+                        .setState(State.OutOfService)
+                        .build(),
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.InService)
+                        .build());
+
+        networkModelListener.updateServicePaths(new TopologyUpdateResultBuilder()
+                .setTopologyChanges(topologyChanges).build());
+        verify(serviceDataStoreOperations,
+                never()).modifyService(anyString(), any(State.class), any(AdminStates.class));
+    }
+
+    @Test
+    public void testUpdateServicePathsShouldModifyServiceState() {
+        Map<ServicePathsKey, ServicePaths> servicePathMap = Map.of(
+                new ServicePathsKey("service-path 1"),
+                new ServicePathsBuilder()
+                        .setServicePathName("service-path 1")
+                        .setPathDescription(pathDescription)
+                        .build());
+
+        when(serviceDataStoreOperations.getServicePaths()).thenReturn(Optional.of(new ServicePathListBuilder()
+                .setServicePaths(servicePathMap).build()));
+        when(serviceDataStoreOperations.modifyServicePath(any(PathDescription.class), anyString()))
+                .thenReturn(OperationResult.ok(""));
+        when(serviceDataStoreOperations.getService(anyString())).thenReturn(Optional.of(
+                new ServicesBuilder().setServiceName("serviceTest")
+                        .setOperationalState(State.InService)
+                        .setAdministrativeState(AdminStates.InService)
+                        .build()));
+        when(serviceDataStoreOperations.modifyService(anyString(), any(State.class), any(AdminStates.class)))
+                .thenReturn(OperationResult.ok(""));
+
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.OutOfService)
+                        .build());
+
+        networkModelListener.updateServicePaths(new TopologyUpdateResultBuilder()
+                .setTopologyChanges(topologyChanges).build());
+        verify(serviceDataStoreOperations, times(1)).modifyService(anyString(),
+                eq(State.OutOfService), any(AdminStates.class));
+    }
+
+    @Test
+    public void testOnTopologyUpdateResultWhenNeverWired() {
+        NetworkModelListenerImpl networkModelListenerMocked = Mockito.mock(NetworkModelListenerImpl.class);
+        doCallRealMethod().when(networkModelListenerMocked).onTopologyUpdateResult(any(TopologyUpdateResult.class));
+
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges1 = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.OutOfService)
+                        .build());
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges2 = Map.of(
+                new TopologyChangesKey("tpNodeIdC", "TpIdC1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdC")
+                        .setTpId("TpIdC1")
+                        .setState(State.OutOfService)
+                        .build());
+
+        networkModelListenerMocked.onTopologyUpdateResult(new TopologyUpdateResultBuilder()
+                .setTopologyChanges(topologyChanges1).build());
+        networkModelListenerMocked.onTopologyUpdateResult(new TopologyUpdateResultBuilder()
+                .setTopologyChanges(topologyChanges2).build());
+        verify(networkModelListenerMocked, times(2)).updateServicePaths(
+                any(TopologyUpdateResult.class));
+    }
+
+    @Test
+    public void testOnTopologyUpdateResultWhenAlreadyWired() {
+        NetworkModelListenerImpl networkModelListenerMocked = Mockito.mock(NetworkModelListenerImpl.class);
+        doCallRealMethod().when(networkModelListenerMocked).onTopologyUpdateResult(any(TopologyUpdateResult.class));
+
+        Map<TopologyChangesKey, TopologyChanges> topologyChanges = Map.of(
+                new TopologyChangesKey("tpNodeIdA", "TpIdA1"),
+                new TopologyChangesBuilder()
+                        .setNodeId("tpNodeIdA")
+                        .setTpId("TpIdA1")
+                        .setState(State.OutOfService)
+                        .build());
+        TopologyUpdateResult topologyUpdateResult = new TopologyUpdateResultBuilder()
+                .setTopologyChanges(topologyChanges).build();
+
+        networkModelListenerMocked.onTopologyUpdateResult(topologyUpdateResult);
+        networkModelListenerMocked.onTopologyUpdateResult(topologyUpdateResult);
+        verify(networkModelListenerMocked, times(1)).updateServicePaths(
+                any(TopologyUpdateResult.class));
+    }
+
+    private Map<AToZKey, AToZ> createMapAtoZ() {
+        Map<AToZKey, AToZ> atozmap = new HashMap<>();
+        atozmap.put(
+                new AToZKey("0"),
+                new AToZBuilder()
+                        .setId("0")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdA")
+                                        .setTpId("TpIdA1")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("1"),
+                new AToZBuilder()
+                        .setId("1")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new NodeBuilder()
+                                        .setNodeId("NodeIdA")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("2"),
+                new AToZBuilder()
+                        .setId("2")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdA")
+                                        .setTpId("TpIdA2")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("3"),
+                new AToZBuilder()
+                        .setId("3")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new LinkBuilder()
+                                        .setLinkId("LinkIdAZ")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("4"),
+                new AToZBuilder()
+                        .setId("4")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdZ")
+                                        .setTpId("TpIdZ2")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("5"),
+                new AToZBuilder()
+                        .setId("5")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new NodeBuilder()
+                                        .setNodeId("NodeIdZ")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        atozmap.put(
+                new AToZKey("6"),
+                new AToZBuilder()
+                        .setId("6")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdZ")
+                                        .setTpId("TpIdZ1")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        return atozmap;
+    }
+
+    private Map<ZToAKey, ZToA> createMapZtoA() {
+        Map<ZToAKey, ZToA> ztoamap = new HashMap<>();
+        ztoamap.put(
+                new ZToAKey("0"),
+                new ZToABuilder()
+                        .setId("0")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdZ")
+                                        .setTpId("TpIdZ1")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("1"),
+                new ZToABuilder()
+                        .setId("1")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new NodeBuilder()
+                                        .setNodeId("NodeIdZ")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("2"),
+                new ZToABuilder()
+                        .setId("2")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdZ")
+                                        .setTpId("TpIdZ2")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("3"),
+                new ZToABuilder()
+                        .setId("3")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new LinkBuilder()
+                                        .setLinkId("LinkIdAZ")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("4"),
+                new ZToABuilder()
+                        .setId("4")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdA")
+                                        .setTpId("TpIdA2")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("5"),
+                new ZToABuilder()
+                        .setId("5")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new NodeBuilder()
+                                        .setNodeId("NodeIdA")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        ztoamap.put(
+                new ZToAKey("6"),
+                new ZToABuilder()
+                        .setId("6")
+                        .setResource(new ResourceBuilder()
+                                .setResource(new TerminationPointBuilder()
+                                        .setTpNodeId("tpNodeIdA")
+                                        .setTpId("TpIdA1")
+                                        .build())
+                                .setState(State.InService)
+                                .build())
+                        .build());
+        return ztoamap;
+    }
+}
index 2d68f7b0354fa71542c4eab789578a1889061e92..ef39cb2625d8d3688c72be2c4f07932136ea1a48 100644 (file)
@@ -259,7 +259,7 @@ class TransportPCEFulltesting(unittest.TestCase):
         self.assertEqual(response.status_code, requests.codes.ok)
         res = response.json()
         self.assertEqual(res['services'][0]['operational-state'], 'outOfService')
-        self.assertEqual(res['services'][0]['administrative-state'], 'outOfService')
+        self.assertEqual(res['services'][0]['administrative-state'], 'inService')
         time.sleep(1)
 
     def test_17_restore_status_line_port_xpdra(self):