Allow Module Re-Sync 98/129698/5
authorlukegleeson <luke.gleeson@est.tech>
Mon, 27 Jun 2022 15:26:21 +0000 (16:26 +0100)
committerlukegleeson <luke.gleeson@est.tech>
Thu, 30 Jun 2022 15:58:52 +0000 (16:58 +0100)
Allows the Resync of an already synced CmHandle
Currently: Advised -(create schemaset)-> Ready -(manual write)-> Advised -> Locked as schemaset for cmhandle already exists
With this: Advised -(create schemaset)-> Ready -(manual write)-> Advised -(delete schemaset, create schemaset)-> Ready
Included some logging
Renamed ModuleSyncSpec -> ModuleSyncWatchdogSpec to match class

Issue-ID: CPS-1045
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: I408fbea698b7926dbf5d0cddc74acf1b00235b1f

cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncServiceSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy with 96% similarity]

index 58e2bf3..c574aa6 100644 (file)
@@ -32,6 +32,8 @@ import org.onap.cps.api.CpsAdminService;
 import org.onap.cps.api.CpsModuleService;
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.spi.CascadeDeleteAllowed;
+import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
 import org.onap.cps.spi.model.ModuleReference;
 import org.springframework.stereotype.Service;
 
@@ -83,4 +85,21 @@ public class ModuleSyncService {
             schemaSetAndAnchorName);
     }
 
+    /**
+     * Deletes the SchemaSet for provided cmHandle if the SchemaSet Exists.
+     *
+     * @param yangModelCmHandle the yang model of cm handle.
+     */
+    public void deleteSchemaSetIfExists(final YangModelCmHandle yangModelCmHandle) {
+        final String schemaSetAndAnchorName = yangModelCmHandle.getId();
+        try {
+            cpsModuleService.deleteSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName,
+                CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED);
+            log.debug("SchemaSet for {} has been deleted. Ready to be recreated.", schemaSetAndAnchorName);
+        } catch (final SchemaSetNotFoundException e) {
+            log.debug("No SchemaSet for {}. Assuming CmHandle has not been previously Module Synced.",
+                schemaSetAndAnchorName);
+        }
+    }
+
 }
index 402f9f6..9383ac1 100644 (file)
@@ -53,6 +53,7 @@ public class ModuleSyncWatchdog {
             final String cmHandleId = advisedCmHandle.getId();
             final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
             try {
+                moduleSyncService.deleteSchemaSetIfExists(advisedCmHandle);
                 moduleSyncService.syncAndCreateSchemaSetAndAnchor(advisedCmHandle);
                 compositeState.setCmHandleState(CmHandleState.READY);
             } catch (final Exception e) {
index f93b3a7..6a2fbe8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ============LICENSE_START=======================================================
+ *  ============LICENSE_START=======================================================
  *  Copyright (C) 2022 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +24,11 @@ import org.onap.cps.api.CpsAdminService
 import org.onap.cps.api.CpsModuleService
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
 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
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.spi.CascadeDeleteAllowed
+import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
 import org.onap.cps.spi.model.ModuleReference
 import spock.lang.Specification
 
@@ -67,6 +71,44 @@ class ModuleSyncServiceSpec extends Specification {
             'no new module'      | [['module1' : '1'], ['module2' : '2']] | []                            | [:]                             | [new ModuleReference(moduleName:'module1',revision:'1'), new ModuleReference(moduleName:'module2',revision:'2')]
     }
 
+    def 'Delete Schema Set for CmHandle' () {
+        given: 'a CmHandle in the advised state'
+            def cmHandle = new YangModelCmHandle(id: 'some-cmhandle-id', compositeState: new CompositeState(cmHandleState: CmHandleState.ADVISED))
+        and: 'the Schema Set exists for the CmHandle'
+            1 * mockCpsModuleService.deleteSchemaSet(_ as String, 'some-cmhandle-id',
+                CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED)
+        when: 'delete schema set if exists is called'
+            objectUnderTest.deleteSchemaSetIfExists(cmHandle)
+        then: 'there are no exceptions'
+            noExceptionThrown()
+    }
+
+    def 'Delete a non-existing Schema Set for CmHandle' () {
+        given: 'a CmHandle in the advised state'
+            def cmHandle = new YangModelCmHandle(id: 'some-cmhandle-id', compositeState: new CompositeState(cmHandleState: CmHandleState.ADVISED))
+        and: 'the DB throws an exception because its Schema Set does not exist'
+            1 * mockCpsModuleService.deleteSchemaSet(_ as String, 'some-cmhandle-id',
+                CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED) >> { throw new SchemaSetNotFoundException('some-dataspace-name', 'some-cmhandle-id') }
+        when: 'delete schema set if exists is called'
+            objectUnderTest.deleteSchemaSetIfExists(cmHandle)
+        then: 'there are no exceptions'
+            noExceptionThrown()
+    }
+
+    def 'Delete Schema Set for CmHandle with other exception' () {
+        given: 'a CmHandle in the advised state'
+            def cmHandle = new YangModelCmHandle(id: 'some-cmhandle-id', compositeState: new CompositeState(cmHandleState: CmHandleState.ADVISED))
+        and: 'an exception other than SchemaSetNotFoundException is thrown'
+            UnsupportedOperationException unsupportedOperationException = new UnsupportedOperationException();
+            1 * mockCpsModuleService.deleteSchemaSet(_ as String, 'some-cmhandle-id',
+                CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED) >> { throw unsupportedOperationException }
+        when: 'delete schema set if exists is called'
+            objectUnderTest.deleteSchemaSetIfExists(cmHandle)
+        then: 'an exception is thrown'
+            def result = thrown(UnsupportedOperationException)
+            result == unsupportedOperationException
+    }
+
     def toModuleReference(moduleReferenceAsMap) {
         def moduleReferences = [].withDefault { [:] }
         moduleReferenceAsMap.forEach(property ->
@@ -29,7 +29,7 @@ import org.onap.cps.ncmp.api.inventory.LockReasonCategory
 import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
 import spock.lang.Specification
 
-class ModuleSyncSpec extends Specification {
+class ModuleSyncWatchdogSpec extends Specification {
 
     def mockInventoryPersistence = Mock(InventoryPersistence)
 
@@ -53,6 +53,8 @@ class ModuleSyncSpec extends Specification {
             objectUnderTest.executeAdvisedCmHandlePoll()
         then: 'the inventory persistence cm handle returns a composite state for the first cm handle'
             1 * mockInventoryPersistence.getCmHandleState('some-cm-handle') >> compositeState1
+        and: 'module sync service deletes schema set of cm handle if it exists'
+            1 * mockModuleSyncService.deleteSchemaSetIfExists(yangModelCmHandle1)
         and: 'module sync service syncs the first cm handle and creates a schema set'
             1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle1)
         and: 'the composite state cm handle state is now READY'