Refactor existing model sync code into separate package 41/128341/3
authorsourabh_sourabh <sourabh.sourabh@est.tech>
Wed, 6 Apr 2022 15:24:52 +0000 (16:24 +0100)
committersourabh_sourabh <sourabh.sourabh@est.tech>
Tue, 12 Apr 2022 14:21:06 +0000 (15:21 +0100)
- Created a new class to seperate sync related operations of modules.
- Kept newly created class into .../api/inventory/sync package.
- Created a separate groovy test.
- Fixed existing groovy test.

Issue-ID: CPS-950
Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
Change-Id: Ie7cc36ea75daf43f1383757bcf2057c5cb4894b1

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/inventory/sync/ModuleSyncService.java [new file with mode: 0644]
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/inventory/sync/ModuleSyncServiceSpec.groovy [moved from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy with 65% similarity]

index f498e5d..e624953 100755 (executable)
@@ -34,7 +34,6 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
 import com.google.common.base.Strings;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -48,10 +47,10 @@ import org.onap.cps.api.CpsModuleService;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
-import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
 import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
 import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService;
 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError;
@@ -79,8 +78,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private final DmiDataOperations dmiDataOperations;
 
-    private final DmiModelOperations dmiModelOperations;
-
     private final CpsModuleService cpsModuleService;
 
     private final CpsAdminService cpsAdminService;
@@ -89,6 +86,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
 
     private final YangModelCmHandleRetriever yangModelCmHandleRetriever;
 
+    private final ModuleSyncService moduleSyncService;
+
     @Override
     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
         final DmiPluginRegistration dmiPluginRegistration) {
@@ -223,8 +222,10 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     protected void syncModulesAndCreateAnchor(final YangModelCmHandle yangModelCmHandle) {
-        syncAndCreateSchemaSet(yangModelCmHandle);
-        createAnchor(yangModelCmHandle);
+        final String schemaSetName = moduleSyncService.syncAndCreateSchemaSet(yangModelCmHandle);
+        final String anchorName = yangModelCmHandle.getId();
+        cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
+                anchorName);
     }
 
     protected List<CmHandleRegistrationResponse> parseAndRemoveCmHandlesInDmiRegistration(
@@ -267,35 +268,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
-    private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
-        final Collection<ModuleReference> moduleReferencesFromCmHandle =
-            dmiModelOperations.getModuleReferences(yangModelCmHandle);
-
-        final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
-            .identifyNewModuleReferences(moduleReferencesFromCmHandle);
-
-        final Collection<ModuleReference> existingModuleReferencesFromCmHandle =
-            moduleReferencesFromCmHandle.stream().filter(moduleReferenceFromCmHandle ->
-                !identifiedNewModuleReferencesFromCmHandle.contains(moduleReferenceFromCmHandle)
-            ).collect(Collectors.toList());
-
-        final Map<String, String> newModuleNameToContentMap;
-        if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
-            newModuleNameToContentMap = new HashMap<>();
-        } else {
-            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
-                identifiedNewModuleReferencesFromCmHandle);
-        }
-        cpsModuleService
-            .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
-                newModuleNameToContentMap, existingModuleReferencesFromCmHandle);
-    }
-
-    private void createAnchor(final YangModelCmHandle yangModelCmHandle) {
-        cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
-            yangModelCmHandle.getId());
-    }
-
     private Object getResourceDataResponse(final String cmHandleId,
                                            final String resourceIdentifier,
                                            final DmiOperations.DataStoreEnum dataStore,
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java
new file mode 100644 (file)
index 0000000..1d00f0d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.inventory.sync;
+
+import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+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.model.ModuleReference;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class ModuleSyncService {
+
+    private final DmiModelOperations dmiModelOperations;
+    private final CpsModuleService cpsModuleService;
+
+    /**
+     * This method registers a cm handle and initiates modules sync.
+     *
+     * @param yangModelCmHandle the yang model of cm handle.
+     * @return schemaSetName the name of the schema set (same as cm handle name).
+     */
+    public String syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
+
+        final Collection<ModuleReference> moduleReferencesFromCmHandle =
+                dmiModelOperations.getModuleReferences(yangModelCmHandle);
+
+        final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
+                .identifyNewModuleReferences(moduleReferencesFromCmHandle);
+
+        final Collection<ModuleReference> existingModuleReferencesFromCmHandle =
+                moduleReferencesFromCmHandle.stream().filter(moduleReferenceFromCmHandle ->
+                        !identifiedNewModuleReferencesFromCmHandle.contains(moduleReferenceFromCmHandle)
+                ).collect(Collectors.toList());
+
+        final Map<String, String> newModuleNameToContentMap;
+        if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
+            newModuleNameToContentMap = new HashMap<>();
+        } else {
+            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
+                    identifiedNewModuleReferencesFromCmHandle);
+        }
+        return createSchemaSet(yangModelCmHandle, existingModuleReferencesFromCmHandle, newModuleNameToContentMap);
+    }
+
+    private String createSchemaSet(final YangModelCmHandle yangModelCmHandle,
+                                 final Collection<ModuleReference> existingModuleReferencesFromCmHandle,
+                                 final Map<String, String> newModuleNameToContentMap) {
+        final String schemaSetName = yangModelCmHandle.getId();
+        cpsModuleService
+                .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
+                        newModuleNameToContentMap, existingModuleReferencesFromCmHandle);
+        return schemaSetName;
+    }
+
+}
index 1f41c6b..5683d57 100644 (file)
@@ -33,6 +33,7 @@ import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService
 import org.onap.cps.spi.exceptions.AlreadyDefinedException
 import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.spi.exceptions.DataValidationException
@@ -64,6 +65,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
     def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
+    def mockModuleSyncService = Mock(ModuleSyncService)
 
     def noTimestamp = null
     def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
@@ -386,7 +388,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
     }
 
     def getObjectUnderTest() {
-        return Spy(new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-            mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever))
+        return Spy(new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations,
+            mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever, mockModuleSyncService))
     }
 }
index 7ddbbb2..7629500 100644 (file)
@@ -25,7 +25,10 @@ package org.onap.cps.ncmp.api.impl
 import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException
 import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.spi.exceptions.DataValidationException
+import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService
 import spock.lang.Shared
 
 import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
@@ -34,7 +37,6 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
 
-import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
 import org.onap.cps.utils.JsonObjectMapper
 import com.fasterxml.jackson.core.JsonProcessingException
 import com.fasterxml.jackson.databind.ObjectMapper
@@ -54,17 +56,21 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     def mockCpsModuleService = Mock(CpsModuleService)
     def mockCpsAdminService = Mock(CpsAdminService)
     def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
-    def mockDmiModelOperations = Mock(DmiModelOperations)
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def nullNetworkCmProxyDataServicePropertyHandler = null
     def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
+    def mockModuleSyncService = Mock(ModuleSyncService)
+    def mockDmiPluginRegistration = Mock(DmiPluginRegistration)
+
     def NO_TOPIC = null
     def NO_REQUEST_ID = null
     @Shared
     def OPTIONS_PARAM = '(a=1,b=2)'
+    @Shared
+    def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id')
 
-    def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever)
+    def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations,
+        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever, mockModuleSyncService)
 
     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
@@ -332,4 +338,20 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             'READ'   | READ           || 'Unable to read resource data.'
             'UPDATE' | UPDATE         || 'Unable to update resource data.'
     }
+
+    def 'Verify modules and create anchor params'() {
+        given: 'dmi plugin registration return created cm handles'
+            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'service1', dmiModelPlugin: 'service1',
+                    dmiDataPlugin: 'service2')
+            dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
+            mockDmiPluginRegistration.getCreatedCmHandles() >> [ncmpServiceCmHandle]
+        when: 'parse and create cm handle in dmi registration then sync module'
+            objectUnderTest.parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(mockDmiPluginRegistration)
+        then: 'validate params for creating anchor and list elements'
+            1 * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry',
+                    '/dmi-registry', '{"cm-handles":[{"id":"some-cm-handle-id",' +
+                    '"additional-properties":[],"public-properties":[]}]}', null)
+            1 * mockCpsAdminService.createAnchor('NFP-Operational', null,
+                    'some-cm-handle-id')
+    }
 }
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2022 Nordix Foundation
+ *  Copyright (C) 2022 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  ============LICENSE_END=========================================================
  */
 
-package org.onap.cps.ncmp.api.impl
+package org.onap.cps.ncmp.api.inventory.sync
 
-import org.onap.cps.api.CpsAdminService
 import org.onap.cps.api.CpsModuleService
-import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
-import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
 import org.onap.cps.spi.model.ModuleReference
-import org.onap.cps.utils.JsonObjectMapper
 import spock.lang.Specification
 
-class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
+class ModuleSyncServiceSpec extends Specification {
+
 
-    def nullCpsDataService = null
-    def mockJsonObjectMapper = Mock(JsonObjectMapper)
     def mockCpsModuleService = Mock(CpsModuleService)
-    def mockCpsAdminService = Mock(CpsAdminService)
     def mockDmiModelOperations = Mock(DmiModelOperations)
-    def mockDmiDataOperations = Mock(DmiDataOperations)
-    def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
-    def nullNetworkCmProxyDataServicePropertyHandler = null
 
-    def objectUnderTest = new NetworkCmProxyDataServiceImpl(nullCpsDataService, mockJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-            mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler,mockYangModelCmHandleRetriever)
+    def objectUnderTest = new ModuleSyncService(mockDmiModelOperations, mockCpsModuleService)
 
     def expectedDataspaceName = 'NFP-Operational'
 
@@ -51,7 +41,7 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
         given: 'a cm handle'
             def ncmpServiceCmHandle = new NcmpServiceCmHandle()
             def dmiServiceName = 'some service name'
-            ncmpServiceCmHandle.cmHandleId = 'cm-handle-id-1'
+            ncmpServiceCmHandle.cmHandleId = 'cmHandleId-1'
             def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '' , '', ncmpServiceCmHandle)
         and: 'DMI operations returns some module references'
             def moduleReferences =  [ new ModuleReference(moduleName:'module1',revision:'1'),
@@ -63,16 +53,14 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
             mockDmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, [new ModuleReference('module1', '1')]) >> yangResourceToContentMap
         when: 'module sync is triggered'
             mockCpsModuleService.identifyNewModuleReferences(moduleReferences) >> toModuleReference(identifiedNewModuleReferences)
-            objectUnderTest.syncModulesAndCreateAnchor(yangModelCmHandle)
-        then: 'the CPS module service is called once with the correct parameters'
-            1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, yangModelCmHandle.getId(), yangResourceToContentMap, toModuleReference(expectedKnownModules))
-        and: 'admin service create anchor method has been called with correct parameters'
-            1 * mockCpsAdminService.createAnchor(expectedDataspaceName, yangModelCmHandle.getId(), yangModelCmHandle.getId())
+            def result = objectUnderTest.syncAndCreateSchemaSet(yangModelCmHandle)
+        then: 'the resulting schema set name is the same as the cm handle id'
+            assert result == 'cmHandleId-1'
         where: 'the following parameters are used'
-            scenario             | existingModuleResourcesInCps           | identifiedNewModuleReferences | yangResourceToContentMap      || expectedKnownModules
-            'one new module'     | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']]           | [module1: 'some yang source'] || [['module2' : '2']]
-            'no add. properties' | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']]           | [module1: 'some yang source'] || [['module2' : '2']]
-            'no new module'      | [['module1' : '1'], ['module2' : '2']] | []                            | [:]                           || [['module1' : '1'], ['module2' : '2']]
+            scenario             | existingModuleResourcesInCps           | identifiedNewModuleReferences | yangResourceToContentMap
+            'one new module'     | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']]           | [module1: 'some yang source']
+            'no add. properties' | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']]           | [module1: 'some yang source']
+            'no new module'      | [['module1' : '1'], ['module2' : '2']] | []                            | [:]
     }
 
     def toModuleReference(moduleReferenceAsMap) {