De-registration: send event(s) using central state 32/129932/16
authorsourabh_sourabh <sourabh.sourabh@est.tech>
Mon, 25 Jul 2022 08:49:40 +0000 (09:49 +0100)
committersourabh_sourabh <sourabh.sourabh@est.tech>
Mon, 25 Jul 2022 08:49:40 +0000 (09:49 +0100)
- refactored method "parseAndRemoveCmHandlesInDmiRegistration"
- added method to send events for DELETING and DELETED
- introduced private method in state handler
- updated unit tests for registration spec
- added unit test to cover new private method in state handler

Issue-ID: CPS-1003
Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech>
Change-Id: Ifc1d1e94b7103d85b6352b196edf7075257c211a
Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy

index 16b9a66..8d32c1a 100755 (executable)
@@ -37,6 +37,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler;
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
 import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
@@ -76,6 +77,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private final NetworkCmProxyCmHandlerQueryService networkCmProxyCmHandlerQueryService;
 
+    private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
+
     @Override
     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
             final DmiPluginRegistration dmiPluginRegistration) {
@@ -262,32 +265,41 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
             final List<String> tobeRemovedCmHandles) {
         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
                 new ArrayList<>(tobeRemovedCmHandles.size());
-        for (final String cmHandle : tobeRemovedCmHandles) {
+        for (final String cmHandleId : tobeRemovedCmHandles) {
             try {
-                CpsValidator.validateNameCharacters(cmHandle);
-                inventoryPersistence.deleteSchemaSetWithCascade(cmHandle);
-                inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandle + "']");
-                cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandle));
+                CpsValidator.validateNameCharacters(cmHandleId);
+                final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+                lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle,
+                        CmHandleState.DELETING);
+                deleteSchemaSetAndListElementByCmHandleId(cmHandleId);
+                cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId));
+                lcmEventsCmHandleStateHandler.updateCmHandleState(yangModelCmHandle,
+                        CmHandleState.DELETED);
             } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
                 log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
-                        cmHandle, dataNodeNotFoundException.getMessage());
+                        cmHandleId, dataNodeNotFoundException.getMessage());
                 cmHandleRegistrationResponses.add(CmHandleRegistrationResponse
-                        .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_DOES_NOT_EXIST));
+                        .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_DOES_NOT_EXIST));
             } catch (final DataValidationException dataValidationException) {
                 log.error("Unable to de-register cm-handle id: {}, caused by: {}",
-                        cmHandle, dataValidationException.getMessage());
+                        cmHandleId, dataValidationException.getMessage());
                 cmHandleRegistrationResponses.add(CmHandleRegistrationResponse
-                        .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_INVALID_ID));
+                        .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_INVALID_ID));
             } catch (final Exception exception) {
                 log.error("Unable to de-register cm-handle id : {} , caused by : {}",
-                        cmHandle, exception.getMessage());
+                        cmHandleId, exception.getMessage());
                 cmHandleRegistrationResponses.add(
-                        CmHandleRegistrationResponse.createFailureResponse(cmHandle, exception));
+                        CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception));
             }
         }
         return cmHandleRegistrationResponses;
     }
 
+    private void deleteSchemaSetAndListElementByCmHandleId(final String cmHandleId) {
+        inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
+        inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandleId + "']");
+    }
+
     private CmHandleRegistrationResponse registerNewCmHandle(final YangModelCmHandle yangModelCmHandle) {
         try {
             inventoryPersistence.saveCmHandle(yangModelCmHandle);
index 650251f..bd47bea 100644 (file)
@@ -21,6 +21,7 @@
 package org.onap.cps.ncmp.api.impl.event.lcm;
 
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED;
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED;
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.LOCKED;
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.READY;
 
@@ -75,11 +76,11 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
             } else {
                 registerNewCmHandle(yangModelCmHandle);
             }
+        } else if (DELETED == targetCmHandleState) {
+            setCmHandleState(yangModelCmHandle, targetCmHandleState);
         } else {
-            CompositeStateUtils.setCompositeState(targetCmHandleState).accept(yangModelCmHandle.getCompositeState());
-            inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState());
+            updateAndSaveCmHandleState(yangModelCmHandle, targetCmHandleState);
         }
-
     }
 
     private void retryCmHandle(final YangModelCmHandle yangModelCmHandle) {
@@ -88,7 +89,7 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
     }
 
     private void registerNewCmHandle(final YangModelCmHandle yangModelCmHandle) {
-        CompositeStateUtils.setCompositeState(ADVISED).accept(yangModelCmHandle.getCompositeState());
+        setCmHandleState(yangModelCmHandle, ADVISED);
         inventoryPersistence.saveCmHandle(yangModelCmHandle);
     }
 
@@ -99,4 +100,14 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
         final LcmEvent lcmEvent = lcmEventsCreator.populateLcmEvent(cmHandleId);
         lcmEventsService.publishLcmEvent(cmHandleId, lcmEvent);
     }
+
+    private void updateAndSaveCmHandleState(final YangModelCmHandle yangModelCmHandle,
+                                            final CmHandleState targetCmHandleState) {
+        setCmHandleState(yangModelCmHandle, targetCmHandleState);
+        inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState());
+    }
+
+    private void setCmHandleState(final YangModelCmHandle yangModelCmHandle, final CmHandleState targetCmHandleState) {
+        CompositeStateUtils.setCompositeState(targetCmHandleState).accept(yangModelCmHandle.getCompositeState());
+    }
 }
index dccba0b..1ee1ad2 100644 (file)
@@ -24,6 +24,7 @@ package org.onap.cps.ncmp.api.impl
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.onap.cps.api.CpsModuleService
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService
+import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler
 import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
@@ -58,6 +59,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
     def mockInventoryPersistence = Mock(InventoryPersistence)
     def stubbedNetworkCmProxyCmHandlerQueryService = Stub(NetworkCmProxyCmHandlerQueryService)
+    def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
     def objectUnderTest = getObjectUnderTest()
 
     def 'DMI Registration: Create, Update & Delete operations are processed in the right order'() {
@@ -249,7 +251,11 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                 { if (!schemaSetExist) { throw new SchemaSetNotFoundException("", "") } }
         when: 'registration is updated to delete cmhandle'
             def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
-        then: 'delete list or list element is called'
+        then: 'the cmHandle state is updated to "DELETING"'
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleState(_, CmHandleState.DELETING)
+        and: 'method to delete relevant schema set is called once'
+            1 * mockInventoryPersistence.deleteSchemaSetWithCascade(_)
+        and: 'method to delete relevant list/list element is called once'
             1 * mockInventoryPersistence.deleteListOrListElement(_)
         and: 'successful response is received'
             assert response.getRemovedCmHandles().size() == 1
@@ -257,6 +263,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                 assert it.status == Status.SUCCESS
                 assert it.cmHandle == 'cmhandle'
             }
+        and: 'the cmHandle state is updated to "DELETED"'
+            1 * mockLcmEventsCmHandleStateHandler.updateCmHandleState(_, CmHandleState.DELETED)
         where:
             scenario                                            | schemaSetExist
             'schema-set exists and can be deleted successfully' | true
@@ -303,6 +311,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             noExceptionThrown()
         and: 'cm-handle is not deleted'
             0 * mockInventoryPersistence.deleteListOrListElement(_)
+        and: 'the cmHandle state is not updated to "DELETED"'
+            0 * mockLcmEventsCmHandleStateHandler.updateCmHandleState(_, CmHandleState.DELETED)
         and: 'a failure response is received'
             assert response.getRemovedCmHandles().size() == 1
             with(response.getRemovedCmHandles().get(0)) {
@@ -321,9 +331,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
             mockInventoryPersistence.deleteListOrListElement(_) >> { throw deleteListElementException }
         when: 'registration is updated to delete cmhandle'
             def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
-        then: 'no exception is thrown'
-            noExceptionThrown()
-        and: 'a failure response is received'
+        then: 'a failure response is received'
             assert response.getRemovedCmHandles().size() == 1
             with(response.getRemovedCmHandles().get(0)) {
                 assert it.status == Status.FAILURE
@@ -331,6 +339,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
                 assert it.registrationError == expectedError
                 assert it.errorText == expectedErrorText
             }
+        and: 'the cm handle state is not updated to "DELETED"'
+            0 * mockLcmEventsCmHandleStateHandler.updateCmHandleState(_, CmHandleState.DELETED)
         where:
             scenario                     | cmHandleId             | deleteListElementException                ||  expectedError           | expectedErrorText
             'cm-handle does not exist'   | 'cmhandle'             | new DataNodeNotFoundException("", "", "") || CM_HANDLE_DOES_NOT_EXIST | 'cm-handle does not exist'
@@ -340,6 +350,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
 
     def getObjectUnderTest() {
         return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
-            mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, stubbedNetworkCmProxyCmHandlerQueryService))
+            mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, stubbedNetworkCmProxyCmHandlerQueryService,
+                mockLcmEventsCmHandleStateHandler))
     }
 }
index 3febaa5..d112557 100644 (file)
@@ -23,6 +23,7 @@
 package org.onap.cps.ncmp.api.impl
 
 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService
+import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.onap.cps.ncmp.api.inventory.CmHandleState
 import org.onap.cps.ncmp.api.inventory.CompositeState
@@ -63,6 +64,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     def mockInventoryPersistence = Mock(InventoryPersistence)
     def mockDmiPluginRegistration = Mock(DmiPluginRegistration)
     def mockCpsCmHandlerQueryService = Mock(NetworkCmProxyCmHandlerQueryService)
+    def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
 
     def NO_TOPIC = null
     def NO_REQUEST_ID = null
@@ -71,8 +73,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     @Shared
     def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'test-cm-handle-id')
 
-    def objectUnderTest = new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations,
-        nullNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCpsCmHandlerQueryService)
+    def objectUnderTest = new NetworkCmProxyDataServiceImpl(
+            spiedJsonObjectMapper,
+            mockDmiDataOperations,
+            nullNetworkCmProxyDataServicePropertyHandler,
+            mockInventoryPersistence,
+            mockCpsCmHandlerQueryService,
+            mockLcmEventsCmHandleStateHandler)
 
     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
index 7a4bde0..b4e57c7 100644 (file)
@@ -27,6 +27,8 @@ import org.onap.cps.ncmp.api.inventory.InventoryPersistence
 import spock.lang.Specification
 
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETING
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.LOCKED
 import static org.onap.cps.ncmp.api.inventory.CmHandleState.READY
 import static org.onap.cps.ncmp.api.inventory.LockReasonCategory.LOCKED_MODULE_SYNC_FAILED
@@ -39,11 +41,14 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
 
     def objectUnderTest = new LcmEventsCmHandleStateHandlerImpl(mockInventoryPersistence, mockLcmEventsCreator, mockLcmEventsService)
 
+    def cmHandleId = 'cmhandle-id-1'
+    def compositeState
+    def yangModelCmHandle
+
     def 'Update and Publish Events on State Change #stateChange'() {
         given: 'Cm Handle represented as YangModelCmHandle'
-            def cmHandleId = 'cmhandle-id-1'
-            def compositeState = new CompositeState(cmHandleState: fromCmHandleState)
-            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+            compositeState = new CompositeState(cmHandleState: fromCmHandleState)
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
         when: 'update state is invoked'
             objectUnderTest.updateCmHandleState(yangModelCmHandle, toCmHandleState)
         then: 'state is saved using inventory persistence'
@@ -62,9 +67,8 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
 
     def 'Update and Publish Events on State Change from NO_EXISTING state to ADVISED'() {
         given: 'Cm Handle represented as YangModelCmHandle in READY state'
-            def cmHandleId = 'cmhandle-id-1'
-            def compositeState = new CompositeState()
-            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+            compositeState = new CompositeState()
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
         when: 'update state is invoked'
             objectUnderTest.updateCmHandleState(yangModelCmHandle, ADVISED)
         then: 'state is saved using inventory persistence'
@@ -75,10 +79,9 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
 
     def 'Update and Publish Events on State Change from LOCKED to ADVISED'() {
         given: 'Cm Handle represented as YangModelCmHandle in LOCKED state'
-            def cmHandleId = 'cmhandle-id-1'
-            def compositeState = new CompositeState(cmHandleState: LOCKED,
+            compositeState = new CompositeState(cmHandleState: LOCKED,
                 lockReason: CompositeState.LockReason.builder().lockReasonCategory(LOCKED_MODULE_SYNC_FAILED).details('some lock details').build())
-            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
         when: 'update state is invoked'
             objectUnderTest.updateCmHandleState(yangModelCmHandle, ADVISED)
         then: 'state is saved using inventory persistence and old lock reason details are retained'
@@ -93,9 +96,8 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
 
     def 'Update and Publish Events on State Change to READY with #scenario'() {
         given: 'Cm Handle represented as YangModelCmHandle'
-            def cmHandleId = 'cmhandle-id-1'
-            def compositeState = new CompositeState(cmHandleState: ADVISED)
-            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+            compositeState = new CompositeState(cmHandleState: ADVISED)
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
         and: 'global sync flag is set'
             objectUnderTest.isGlobalDataSyncCacheEnabled = dataSyncCacheEnabled
         when: 'update cmhandle state is invoked'
@@ -115,6 +117,31 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
             scenario                         | dataSyncCacheEnabled || expectedDataStoreSyncState
             'data sync cache enabled'        | true                 || DataStoreSyncState.UNSYNCHRONIZED
             'data sync cache is not enabled' | false                || DataStoreSyncState.NONE_REQUESTED
+    }
+
+    def 'Update cmHandle state to "DELETING"' (){
+        given: 'cm Handle as Yang model'
+            compositeState = new CompositeState(cmHandleState: READY)
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        when: 'updating cm handle state to "DELETING"'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, DELETING)
+        then: 'the cm handle state is as expected'
+            yangModelCmHandle.getCompositeState().getCmHandleState() == DELETING
+        and: 'method to persist cm handle state is called once'
+            1 * mockInventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState())
+        and: 'the method to publish Lcm event is called once'
+            1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _)
+    }
 
+    def 'Update cmHandle state to "DELETED"' (){
+        given: 'cm Handle with state "DELETING" as Yang model '
+            compositeState = new CompositeState(cmHandleState: DELETING)
+            yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        when: 'updating cm handle state to "DELETED"'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, DELETED)
+        then: 'the cm handle state is as expected'
+            yangModelCmHandle.getCompositeState().getCmHandleState() == DELETED
+        and: 'the method to publish Lcm event is called once'
+            1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _)
     }
 }