Fix SonarQube warnings 30/137530/4
authorToineSiebelink <toine.siebelink@est.tech>
Tue, 19 Mar 2024 10:42:07 +0000 (10:42 +0000)
committerToineSiebelink <toine.siebelink@est.tech>
Tue, 19 Mar 2024 14:20:24 +0000 (14:20 +0000)
targetted:
- Introduced CmResourceAddress (name agreed with Daniel and Priyank)
- Extracted out private method in AltenateIdChecker to reduce complexity
side effects:
- use 'record' java feature as suggested by ItelliJ
- had to uprade spotbugs version to avoid incorrect warning on 'record' equeals method
- convention: added missing 'asserts' in affected testware
- my preference: removed a lot of unnecessary linebreaks in affected testware
- removed redunfant (variation) of a 'delegation' test

Issue-ID: CPS-475
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
Change-Id: Ie0c9d5ebc33196ae14ed6c226843095a2a040d1d

16 files changed:
cps-dependencies/pom.xml
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java
cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
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/operations/DmiDataOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java [new file with mode: 0644]
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/operations/DmiDataOperationsSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy
cps-parent/pom.xml

index 69ea859..68f36fb 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ============LICENSE_START=======================================================
   Copyright (c) 2021 Linux Foundation.
-  Modifications Copyright (C) 2020-2023 Nordix Foundation
+  Modifications Copyright (C) 2020-2024 Nordix Foundation
   Modifications Copyright (C) 2022 Bell Canada.
   ================================================================================
   Licensed under the Apache License, Version 2.0 (the "License");
             <dependency>
                 <groupId>com.github.spotbugs</groupId>
                 <artifactId>spotbugs</artifactId>
-                <version>4.2.0</version>
+                <version>4.2.3</version>
             </dependency>
             <dependency>
                 <groupId>com.google.code.gson</groupId>
index 66c1591..93cbccf 100755 (executable)
@@ -44,6 +44,7 @@ import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
 import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler;
@@ -107,8 +108,9 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
                                                              final Boolean includeDescendants,
                                                              final String authorization) {
         final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName);
-        return ncmpDatastoreRequestHandler.executeRequest(datastoreName, cmHandle, resourceIdentifier,
-                optionsParamInQuery, topicParamInQuery, includeDescendants, authorization);
+        final CmResourceAddress cmResourceAddress = new CmResourceAddress(datastoreName, cmHandle, resourceIdentifier);
+        return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, topicParamInQuery,
+            includeDescendants, authorization);
     }
 
     @Override
index 430c099..e6d6faf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2023 Nordix Foundation
+ *  Copyright (C) 2022-2024 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ package org.onap.cps.ncmp.rest.controller.handlers;
 import java.util.function.Supplier;
 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
 import org.onap.cps.spi.FetchDescendantsOption;
 import org.springframework.http.ResponseEntity;
@@ -68,9 +69,7 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle
     }
 
     @Override
-    protected Supplier<Object> getTaskSupplierForGetRequest(final String datastoreName,
-                                                  final String cmHandleId,
-                                                  final String resourceIdentifier,
+    protected Supplier<Object> getTaskSupplierForGetRequest(final CmResourceAddress cmResourceAddress,
                                                   final String optionsParamInQuery,
                                                   final String topicParamInQuery,
                                                   final String requestId,
@@ -79,8 +78,7 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle
 
         final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
 
-        return () -> networkCmProxyDataService.getResourceDataForCmHandle(datastoreName, cmHandleId, resourceIdentifier,
-            fetchDescendantsOption);
+        return () -> networkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, fetchDescendantsOption);
     }
 
     private Supplier<Object> getTaskSupplierForQueryRequest(final String cmHandleId,
index 65410d3..1ae1682 100644 (file)
@@ -25,6 +25,7 @@ import java.util.UUID;
 import java.util.function.Supplier;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
 import org.onap.cps.ncmp.rest.util.TopicValidator;
 import org.springframework.beans.factory.annotation.Value;
@@ -50,18 +51,14 @@ public abstract class NcmpDatastoreRequestHandler {
     /**
      * Executes synchronous/asynchronous get request for given cm handle.
      *
-     * @param datastoreName       the name of the datastore
-     * @param cmHandleId          the cm handle
-     * @param resourceIdentifier  the resource identifier
+     * @param cmResourceAddress   the name of the datastore, cm handle and resource identifier
      * @param optionsParamInQuery the options param in query
      * @param topicParamInQuery   the topic param in query
      * @param includeDescendants  whether include descendants
      * @param authorization       contents of Authorization header, or null if not present
      * @return the response entity
      */
-    public ResponseEntity<Object> executeRequest(final String datastoreName,
-                                                 final String cmHandleId,
-                                                 final String resourceIdentifier,
+    public ResponseEntity<Object> executeRequest(final CmResourceAddress cmResourceAddress,
                                                  final String optionsParamInQuery,
                                                  final String topicParamInQuery,
                                                  final boolean includeDescendants,
@@ -69,16 +66,16 @@ public abstract class NcmpDatastoreRequestHandler {
 
         final boolean asyncResponseRequested = topicParamInQuery != null;
         if (asyncResponseRequested && notificationFeatureEnabled) {
-            return executeAsyncTaskAndGetResponseEntity(datastoreName, cmHandleId, resourceIdentifier,
-                optionsParamInQuery, topicParamInQuery, includeDescendants, authorization);
+            return executeAsyncTaskAndGetResponseEntity(cmResourceAddress, optionsParamInQuery, topicParamInQuery,
+                includeDescendants, authorization);
         }
 
         if (asyncResponseRequested) {
             log.warn("Asynchronous request is unavailable as notification feature is currently disabled, "
                     + "will use synchronous operation.");
         }
-        final Supplier<Object> taskSupplier = getTaskSupplierForGetRequest(datastoreName, cmHandleId,
-                resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID, includeDescendants, authorization);
+        final Supplier<Object> taskSupplier = getTaskSupplierForGetRequest(cmResourceAddress, optionsParamInQuery,
+            NO_TOPIC, NO_REQUEST_ID, includeDescendants, authorization);
         return executeTaskSync(taskSupplier);
     }
 
@@ -96,23 +93,18 @@ public abstract class NcmpDatastoreRequestHandler {
         return ResponseEntity.ok(taskSupplier.get());
     }
 
-    private ResponseEntity<Object> executeAsyncTaskAndGetResponseEntity(final String datastoreName,
-                                                                        final String cmHandleId,
-                                                                        final String resourceIdentifier,
+    private ResponseEntity<Object> executeAsyncTaskAndGetResponseEntity(final CmResourceAddress cmResourceAddress,
                                                                         final String optionsParamInQuery,
                                                                         final String topicParamInQuery,
                                                                         final boolean includeDescendants,
                                                                         final String authorization) {
         final String requestId = UUID.randomUUID().toString();
-        final Supplier<Object> taskSupplier = getTaskSupplierForGetRequest(datastoreName, cmHandleId,
-                resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId, includeDescendants,
-                authorization);
+        final Supplier<Object> taskSupplier = getTaskSupplierForGetRequest(cmResourceAddress,
+            optionsParamInQuery, topicParamInQuery, requestId, includeDescendants, authorization);
         return executeTaskAsync(topicParamInQuery, requestId, taskSupplier);
     }
 
-    protected abstract Supplier<Object> getTaskSupplierForGetRequest(final String datastoreName,
-                                                  final String cmHandleId,
-                                                  final String resourceIdentifier,
+    protected abstract Supplier<Object> getTaskSupplierForGetRequest(final CmResourceAddress cmResourceAddress,
                                                   final String optionsParamInQuery,
                                                   final String topicParamInQuery,
                                                   final String requestId,
index 430b749..75112ca 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2023 Nordix Foundation
+ *  Copyright (C) 2022-2024 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
 import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
 import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
 import org.onap.cps.ncmp.api.impl.operations.OperationType;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.api.models.DataOperationRequest;
 import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException;
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
@@ -77,18 +78,15 @@ public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestH
     }
 
     @Override
-    protected Supplier<Object> getTaskSupplierForGetRequest(final String datastoreName,
-                                                            final String cmHandleId,
-                                                            final String resourceIdentifier,
+    protected Supplier<Object> getTaskSupplierForGetRequest(final CmResourceAddress cmResourceAddress,
                                                             final String optionsParamInQuery,
                                                             final String topicParamInQuery,
                                                             final String requestId,
                                                             final boolean includeDescendants,
                                                             final String authorization) {
 
-        return () -> networkCmProxyDataService.getResourceDataForCmHandle(
-            datastoreName, cmHandleId, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId,
-            authorization);
+        return () -> networkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, optionsParamInQuery,
+            topicParamInQuery, requestId, authorization);
     }
 
     private ResponseEntity<Object> getRequestIdAndSendDataOperationRequestToDmiService(
index 616492d..a5b1f05 100644 (file)
@@ -39,6 +39,7 @@ import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState
 import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory
 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.ncmp.api.models.CmResourceAddress
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler
 import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
@@ -136,15 +137,15 @@ class NetworkCmProxyControllerSpec extends Specification {
     def NO_TOPIC = null
     def NO_REQUEST_ID = null
     def NO_AUTH_HEADER = null
-    def TIMOUT_FOR_TEST = 1234
+    def TIMEOUT_FOR_TEST = 1234
 
     def logger = Spy(ListAppender<ILoggingEvent>)
 
     def setup() {
         ncmpCachedResourceRequestHandler.notificationFeatureEnabled = true
-        ncmpCachedResourceRequestHandler.timeOutInMilliSeconds = TIMOUT_FOR_TEST
+        ncmpCachedResourceRequestHandler.timeOutInMilliSeconds = TIMEOUT_FOR_TEST
         ncmpPassthroughResourceRequestHandler.notificationFeatureEnabled = true
-        ncmpPassthroughResourceRequestHandler.timeOutInMilliSeconds = TIMOUT_FOR_TEST
+        ncmpPassthroughResourceRequestHandler.timeOutInMilliSeconds = TIMEOUT_FOR_TEST
         setupLogger()
     }
 
@@ -154,31 +155,28 @@ class NetworkCmProxyControllerSpec extends Specification {
 
     def 'Get Resource Data from pass-through operational.'() {
         given: 'resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
-                    "?resourceIdentifier=parent/child&options=(a=1,b=2)"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational?resourceIdentifier=parent/child&options=(a=1,b=2)"
+        and: 'the expected cm resource address'
+            def expectedCmResourceAddress = new CmResourceAddress(PASSTHROUGH_OPERATIONAL.datastoreName, 'testCmHandle', 'parent/child')
         when: 'get data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-            ).andReturn().response
-        then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle'
-            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(PASSTHROUGH_OPERATIONAL.datastoreName, 'testCmHandle',
-                    'parent/child','(a=1,b=2)', NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
+        then: 'the NCMP data service is called with correct parameters'
+            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(expectedCmResourceAddress, '(a=1,b=2)', NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
         and: 'response status is Ok'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Get Resource Data from ncmp-datastore:operational (cached) parameters handling with #scenario.'() {
         given: 'resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/h123/data/ds/ncmp-datastore:operational" +
-                    "?resourceIdentifier=parent/child${additionalUrlParam}"
+            def getUrl = "$ncmpBasePathV1/ch/h123/data/ds/ncmp-datastore:operational?resourceIdentifier=parent/child${additionalUrlParam}"
+        and: 'the expected cm resource address'
+            def expectedCmResourceAddress = new CmResourceAddress('ncmp-datastore:operational', 'h123', 'parent/child')
         when: 'get data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
-        then: 'task executor is called appropriate number of times'
-            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle('ncmp-datastore:operational', 'h123', 'parent/child', expectedIncludeDescendants)
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
+        then: 'the NCMP data service is called with correct parameters'
+            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(expectedCmResourceAddress, expectedIncludeDescendants)
         and: 'response status is OK'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         where: 'the following parameters are used'
             scenario                    | additionalUrlParam           || expectedIncludeDescendants
             'no additional param'       | ''                           || OMIT_DESCENDANTS
@@ -192,15 +190,11 @@ class NetworkCmProxyControllerSpec extends Specification {
     def 'Execute (async) data operation to read data from dmi service.'() {
         given: 'data operation url'
             def getUrl = "$ncmpBasePathV1/data?topic=my-topic-name"
-            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(getDataOperationRequest("read", datastore.datastoreName))
+            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(getDataOperationRequest('read', datastore.datastoreName))
         when: 'post data operation request is performed'
-            def response = mvc.perform(
-                    post(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content(dataOperationRequestJsonData)
-            ).andReturn().response
+            def response = mvc.perform(post(getUrl).contentType(MediaType.APPLICATION_JSON).content(dataOperationRequestJsonData)).andReturn().response
         then: 'response status is Ok'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         and: 'async request id is generated'
             assert response.contentAsString.contains('requestId')
         then: 'the request is handled asynchronously'
@@ -212,80 +206,57 @@ class NetworkCmProxyControllerSpec extends Specification {
     def 'Execute (async) data operation with some validation error.'() {
         given: 'data operation url'
             def getUrl = "$ncmpBasePathV1/data?topic=my-topic-name"
-            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(
-                    getDataOperationRequest('read', 'invalid datastore'))
+            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(getDataOperationRequest('read', 'invalid datastore'))
         when: 'post data resource request is performed'
-            def response = mvc.perform(
-                    post(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content(dataOperationRequestJsonData)
-            ).andReturn().response
+            def response = mvc.perform(post(getUrl).contentType(MediaType.APPLICATION_JSON).content(dataOperationRequestJsonData)).andReturn().response
         then: 'response status is BAD_REQUEST'
-            response.status == HttpStatus.BAD_REQUEST.value()
+            assert response.status == HttpStatus.BAD_REQUEST.value()
     }
 
     def 'Get data operation resource data when notification feature is disabled for datastore: #datastore.'() {
         given: 'data operation url'
             def getUrl = "$ncmpBasePathV1/data?topic=my-topic-name"
-            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(
-                    getDataOperationRequest("read", PASSTHROUGH_RUNNING.datastoreName))
+            def dataOperationRequestJsonData = jsonObjectMapper.asJsonString(getDataOperationRequest("read", PASSTHROUGH_RUNNING.datastoreName))
             ncmpPassthroughResourceRequestHandler.notificationFeatureEnabled = false
         when: 'post data resource request is performed'
-            def response = mvc.perform(
-                    post(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content(dataOperationRequestJsonData)
+            def response = mvc.perform(post(getUrl).contentType(MediaType.APPLICATION_JSON).content(dataOperationRequestJsonData)
             ).andReturn().response
         then: 'response status is Ok'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         and: 'async request id is unavailable'
             assert response.contentAsString == '{"status":"Asynchronous request is unavailable as notification feature is currently disabled."}'
     }
 
     def 'Query Resource Data from operational.'() {
         given: 'the query resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational/query" +
-                    "?cps-path=/cps/path"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational/query?cps-path=/cps/path"
         when: 'the query data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-            ).andReturn().response
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
         then: 'the NCMP query service is called with queryResourceDataOperationalForCmHandle'
-            1 * mockNetworkCmProxyQueryService.queryResourceDataOperational('testCmHandle',
-                    '/cps/path',
-                    FetchDescendantsOption.OMIT_DESCENDANTS)
+            1 * mockNetworkCmProxyQueryService.queryResourceDataOperational('testCmHandle','/cps/path',FetchDescendantsOption.OMIT_DESCENDANTS)
         and: 'response status is Ok'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Query Resource Data with unsupported datastore'() {
         given: 'the query resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running/query" +
-                    "?cps-path=/cps/path"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running/query?cps-path=/cps/path"
         when: 'the query data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-            ).andReturn().response
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
         then: 'a 400 BAD_REQUEST is returned for the unsupported datastore'
-            response.status == 400
+            assert response.status == 400
         and: 'the error message is that the datastore is not supported'
-            response.contentAsString.contains("ncmp-datastore:passthrough-running is not supported")
+            assert response.contentAsString.contains("ncmp-datastore:passthrough-running is not supported")
     }
 
     def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.'() {
         given: 'resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "?resourceIdentifier=" + resourceIdentifier + "&options=(a=1,b=2)"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=$resourceIdentifier&options=(a=1,b=2)"
         and: 'ncmp service returns json object'
-            mockNetworkCmProxyDataService.getResourceDataForCmHandle(PASSTHROUGH_RUNNING.datastoreName, 'testCmHandle',
-                    resourceIdentifier,'(a=1,b=2)', NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >> '{valid-json}'
+            def expectedCmResourceAddress = new CmResourceAddress(PASSTHROUGH_RUNNING.datastoreName, 'testCmHandle', resourceIdentifier)
+            mockNetworkCmProxyDataService.getResourceDataForCmHandle(expectedCmResourceAddress,'(a=1,b=2)', NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >> '{valid-json}'
         when: 'get data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-            ).andReturn().response
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
         then: 'response status is Ok'
             response.status == HttpStatus.OK.value()
         and: 'response contains valid object body'
@@ -302,34 +273,24 @@ class NetworkCmProxyControllerSpec extends Specification {
 
     def 'Update resource data from pass-through running.'() {
         given: 'update resource data url'
-            def updateUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "?resourceIdentifier=parent/child"
+            def updateUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child"
         when: 'update data resource request is performed'
-            def response = mvc.perform(
-                    put(updateUrl)
-                            .contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
-            ).andReturn().response
+            def response = mvc.perform(put(updateUrl).contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)).andReturn().response
         then: 'ncmp service method to update resource is called'
-            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                    'parent/child', UPDATE, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
+            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle','parent/child', UPDATE, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
         and: 'the response status is OK'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Create Resource Data from pass-through running with #scenario.'() {
         given: 'resource data url'
-            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "?resourceIdentifier=parent/child"
+            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child"
         when: 'create resource request is performed'
-            def response = mvc.perform(
-                    post(url)
-                            .contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
-            ).andReturn().response
+            def response = mvc.perform(post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)).andReturn().response
         then: 'ncmp service method to create resource called'
-            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                    'parent/child', CREATE, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
+            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', 'parent/child', CREATE, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
         and: 'resource is created'
-            response.status == HttpStatus.CREATED.value()
+            assert response.status == HttpStatus.CREATED.value()
     }
 
     def 'Get module references for the given dataspace and cm handle.'() {
@@ -338,12 +299,11 @@ class NetworkCmProxyControllerSpec extends Specification {
         when: 'get module resource request is performed'
             def response = mvc.perform(get(getUrl)).andReturn().response
         then: 'ncmp service method to get yang resource module references is called'
-            mockNetworkCmProxyDataService.getYangResourcesModuleReferences('some-cmhandle')
-                    >> [new ModuleReference(moduleName: 'some-name1', revision: '2021-10-03')]
+            mockNetworkCmProxyDataService.getYangResourcesModuleReferences('some-cmhandle') >> [new ModuleReference(moduleName: 'some-name1', revision: '2021-10-03')]
         and: 'response contains an array with the module name and revision'
             response.getContentAsString() == '[{"moduleName":"some-name1","revision":"2021-10-03"}]'
         and: 'response returns an OK http code'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Retrieve cm handles.'() {
@@ -364,13 +324,11 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'map for trust level per cmHandle has value for only one cm handle'
               trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
         when: 'the searches api is invoked'
-            def response = mvc.perform(post(searchesEndpoint)
-                    .contentType(MediaType.APPLICATION_JSON)
-                    .content(jsonString)).andReturn().response
+            def response = mvc.perform(post(searchesEndpoint).contentType(MediaType.APPLICATION_JSON).content(jsonString)).andReturn().response
         then: 'response status returns OK'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         and: 'the expected response content is returned'
-            response.contentAsString == '[{"cmHandle":"ch-1","publicCmHandleProperties":[{"color":"yellow"}],"state":null,"trustLevel":"NONE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null},{"cmHandle":"ch-2","publicCmHandleProperties":[{"color":"green"}],"state":null,"trustLevel":null,"moduleSetTag":"someModuleSetTag","alternateId":"someAlternateId","dataProducerIdentifier":"someDataProducerIdentifier"}]'
+            assert response.contentAsString == '[{"cmHandle":"ch-1","publicCmHandleProperties":[{"color":"yellow"}],"state":null,"trustLevel":"NONE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null},{"cmHandle":"ch-2","publicCmHandleProperties":[{"color":"green"}],"state":null,"trustLevel":null,"moduleSetTag":"someModuleSetTag","alternateId":"someAlternateId","dataProducerIdentifier":"someDataProducerIdentifier"}]'
     }
 
     def 'Get complete Cm Handle details by Cm Handle id.'() {
@@ -396,7 +354,7 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'the response contains the cm handle state'
             assertContainsState(response)
         and: 'the content does not contain dmi properties'
-            !response.contentAsString.contains("some DMI property")
+            assert !response.contentAsString.contains("some DMI property")
     }
 
     def 'Get Cm Handle public properties by Cm Handle id.'() {
@@ -405,13 +363,11 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'some cm handle public properties'
             def publicProperties = ['public prop': 'some public property']
         and: 'the service method is invoked with the cm handle id returning the cm handle public properties'
-            1 * mockNetworkCmProxyDataService
-                    .getCmHandlePublicProperties('some-cm-handle') >> publicProperties
+            1 * mockNetworkCmProxyDataService.getCmHandlePublicProperties('some-cm-handle') >> publicProperties
         when: 'the cm handle properties api is invoked'
-            def response = mvc.perform(
-                    get(cmHandlePropertiesEndpoint)).andReturn().response
+            def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
         then: 'the correct response is returned'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         and: 'the response contains the public properties'
             assertContainsPublicProperties(response)
     }
@@ -422,15 +378,13 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'some cm handle composite state'
             def compositeState = compositeStateTestObject()
         and: 'the service method is invoked with the cm handle id returning the cm handle composite state'
-            1 * mockNetworkCmProxyDataService
-                    .getCmHandleCompositeState('some-cm-handle') >> compositeState
+            1 * mockNetworkCmProxyDataService.getCmHandleCompositeState('some-cm-handle') >> compositeState
         when: 'the cm handle state api is invoked'
-            def response = mvc.perform(
-                    get(cmHandlePropertiesEndpoint)).andReturn().response
+            def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
         then: 'the correct response is returned'
             response.status == HttpStatus.OK.value()
         and: 'the response contains the cm handle state'
-            assertContainsState(response)
+            assert assertContainsState(response)
     }
 
     def 'Call execute cm handle searches with unrecognized condition name.'() {
@@ -449,12 +403,9 @@ class NetworkCmProxyControllerSpec extends Specification {
             trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
             trustLevelPerCmHandle.put('ch-2', TrustLevel.NONE)
         when: 'the searches api is invoked'
-            def response = mvc.perform(
-                    post(searchesEndpoint)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content(jsonString)).andReturn().response
+            def response = mvc.perform(post(searchesEndpoint).contentType(MediaType.APPLICATION_JSON).content(jsonString)).andReturn().response
         then: 'an empty cm handle identifier is returned'
-            response.contentAsString == '[{"cmHandle":"ch-1","publicCmHandleProperties":[{"color":"yellow"}],"state":null,"trustLevel":"COMPLETE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null},{"cmHandle":"ch-2","publicCmHandleProperties":[{"color":"green"}],"state":null,"trustLevel":"NONE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null}]'
+            assert response.contentAsString == '[{"cmHandle":"ch-1","publicCmHandleProperties":[{"color":"yellow"}],"state":null,"trustLevel":"COMPLETE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null},{"cmHandle":"ch-2","publicCmHandleProperties":[{"color":"green"}],"state":null,"trustLevel":"NONE","moduleSetTag":null,"alternateId":null,"dataProducerIdentifier":null}]'
     }
 
     def 'Query for cm handles matching query parameters'() {
@@ -463,68 +414,47 @@ class NetworkCmProxyControllerSpec extends Specification {
         and: 'the service method is invoked with module names and returns cm handle ids'
             1 * mockNetworkCmProxyDataService.executeCmHandleIdSearch(_) >> ['ch-1', 'ch-2']
         when: 'the searches api is invoked'
-            def response = mvc.perform(
-                    post(searchesEndpoint)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content('{}')).andReturn().response
+            def response = mvc.perform(post(searchesEndpoint).contentType(MediaType.APPLICATION_JSON).content('{}')).andReturn().response
         then: 'cm handle ids are returned'
-            response.contentAsString == '["ch-1","ch-2"]'
+            assert response.contentAsString == '["ch-1","ch-2"]'
     }
 
     def 'Query for cm handles with invalid request payload'() {
         when: 'the searches api is invoked'
             def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches"
             def invalidInputData = '{invalidJson}'
-            def response = mvc.perform(
-                    post(searchesEndpoint)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .content(invalidInputData)).andReturn().response
+            def response = mvc.perform(post(searchesEndpoint).contentType(MediaType.APPLICATION_JSON).content(invalidInputData)).andReturn().response
         then: 'BAD_REQUEST is returned'
-            response.getStatus() == 400
+            assert response.getStatus() == 400
     }
 
     def 'Patch resource data in pass-through running datastore.'() {
         given: 'patch resource data url'
-            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "?resourceIdentifier=parent/child"
+            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child"
         when: 'patch data resource request is performed'
-            def response = mvc.perform(
-                    patch(url)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .accept(MediaType.APPLICATION_JSON).content(requestBody)
-            ).andReturn().response
+            def response = mvc.perform(patch(url).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).content(requestBody)).andReturn().response
         then: 'ncmp service method to update resource is called'
-            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                    'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
+            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', 'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
         and: 'the response status is OK'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Delete resource data in pass-through running datastore.'() {
         given: 'delete resource data url'
-            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
-                    "?resourceIdentifier=parent/child"
+            def url = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child"
         when: 'delete data resource request is performed'
-            def response = mvc.perform(
-                    delete(url)
-                            .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andReturn().response
+            def response = mvc.perform(delete(url).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)).andReturn().response
         then: 'the ncmp service method to delete resource is called (with null as body)'
-            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                    'parent/child', DELETE, null, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
+            1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', 'parent/child', DELETE, null, 'application/json;charset=UTF-8', NO_AUTH_HEADER)
         and: 'the response is No Content'
-            response.status == HttpStatus.NO_CONTENT.value()
+            assert response.status == HttpStatus.NO_CONTENT.value()
     }
 
     def 'Get resource data from DMI with valid topic i.e. async request for #scenario'() {
         given: 'resource data url'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastoreInUrl}" +
-                    "?resourceIdentifier=parent/child&options=(a=1,b=2)&topic=my-topic-name"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastoreInUrl}?resourceIdentifier=parent/child&options=(a=1,b=2)&topic=my-topic-name"
         when: 'get data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-                            .accept(MediaType.APPLICATION_JSON_VALUE)
-            ).andReturn().response
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON_VALUE)).andReturn().response
         then: 'async request id is generated'
             assert response.contentAsString.contains("requestId")
         where: 'the following parameters are used'
@@ -535,17 +465,14 @@ class NetworkCmProxyControllerSpec extends Specification {
 
     def 'Getting module definitions for a module'() {
         when: 'get module definition request is performed with module name'
-            def response = mvc.perform(
-                get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions?module-name=sampleModuleName"))
-                .andReturn().response
+            def response = mvc.perform(get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions?module-name=sampleModuleName")).andReturn().response
         then: 'ncmp service method is invoked with correct parameters'
             mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleAndModule('some-cmhandle', 'sampleModuleName', _)
-                >> [new ModuleDefinition('sampleModuleName', '2021-10-03',
-                'module sampleModuleName{ sample module content }')]
+                >> [new ModuleDefinition('sampleModuleName', '2021-10-03','module sampleModuleName{ sample module content }')]
         and: 'response contains an array with the module name, revision and content'
             response.getContentAsString() == '[{"moduleName":"sampleModuleName","revision":"2021-10-03","content":"module sampleModuleName{ sample module content }"}]'
         and: 'response returns an OK http code'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
     }
 
     def 'Getting module definitions filtering on #scenario'() {
@@ -590,17 +517,15 @@ class NetworkCmProxyControllerSpec extends Specification {
 
     def 'Get Resource Data from operational with or without descendants'() {
         given: 'resource data url with descendants #enabled'
-            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational" +
-                    "?resourceIdentifier=parent/child&include-descendants=${booleanValue}"
+            def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational?resourceIdentifier=parent/child&include-descendants=${booleanValue}"
+        and: 'the expected target'
+            def expectedCmResourceAddress = new CmResourceAddress(OPERATIONAL.datastoreName, 'testCmHandle', 'parent/child')
         when: 'get data resource request is performed'
-            def response = mvc.perform(
-                    get(getUrl)
-                            .contentType(MediaType.APPLICATION_JSON)
-            ).andReturn().response
+            def response = mvc.perform(get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
         then: 'the NCMP data service is called with getResourceDataOperational with #descendantsOption'
-            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(OPERATIONAL.datastoreName, 'testCmHandle', 'parent/child', descendantsOption)
+            1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(expectedCmResourceAddress, descendantsOption)
         and: 'response status is Ok'
-            response.status == HttpStatus.OK.value()
+            assert response.status == HttpStatus.OK.value()
         where: 'the following parameters are used'
             booleanValue | descendantsOption
             false        | OMIT_DESCENDANTS
index ddeac51..bdd0e71 100644 (file)
@@ -25,6 +25,7 @@ import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException
 import org.onap.cps.ncmp.api.impl.exception.InvalidOperationException
 import org.onap.cps.ncmp.api.models.DataOperationDefinition
 import org.onap.cps.ncmp.api.models.DataOperationRequest
+import org.onap.cps.ncmp.api.models.CmResourceAddress
 import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException
 import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
 import spock.lang.Specification
@@ -48,12 +49,13 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
             objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled
         and: 'a flag to track the network service call'
             def networkServiceMethodCalled = false
+        and: 'a CM resource address'
+            def cmResourceAddress = new CmResourceAddress('ds', 'ch1', 'resource1')
         and: 'the (mocked) service will use the flag to indicate if it is called'
-            mockNetworkCmProxyDataService.getResourceDataForCmHandle('ds', 'ch1', 'resource1', 'options', _, _, NO_AUTH_HEADER) >> {
-                networkServiceMethodCalled = true
-            }
+            mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >>
+                { networkServiceMethodCalled = true }
         when: 'get request is executed with topic = #topic'
-            objectUnderTest.executeRequest('ds', 'ch1', 'resource1', 'options', topic, false, NO_AUTH_HEADER)
+            objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER)
         then: 'the task is executed in an async fashion or not'
             expectedCalls * spiedCpsNcmpTaskExecutor.executeTask(*_)
         and: 'the service request is invoked'
index 4230140..20545d7 100644 (file)
@@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
 import org.onap.cps.ncmp.api.impl.operations.OperationType;
 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
 import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.api.models.DataOperationRequest;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
@@ -53,18 +54,14 @@ public interface NetworkCmProxyDataService {
     /**
      * Get resource data for given data store using dmi.
      *
-     * @param datastoreName       datastore name
-     * @param cmHandleId          cm handle identifier
-     * @param resourceIdentifier  resource identifier
+     * @param cmResourceAddress   target datastore, cm handle and resource identifier
      * @param optionsParamInQuery options query
      * @param topicParamInQuery   topic name for (triggering) async responses
      * @param requestId           unique requestId for async request
      * @param authorization       contents of Authorization header, or null if not present
      * @return {@code Object} resource data
      */
-    Object getResourceDataForCmHandle(String datastoreName,
-                                      String cmHandleId,
-                                      String resourceIdentifier,
+    Object getResourceDataForCmHandle(CmResourceAddress cmResourceAddress,
                                       String optionsParamInQuery,
                                       String topicParamInQuery,
                                       String requestId,
@@ -73,15 +70,11 @@ public interface NetworkCmProxyDataService {
     /**
      * Get resource data for operational.
      *
-     * @param datastoreName      datastore name
-     * @param cmHandleId         cm handle identifier
-     * @param resourceIdentifier resource identifier
+     * @param cmResourceAddress     target datastore, cm handle and resource identifier
      * @Link FetchDescendantsOption fetch descendants option
      * @return {@code Object} resource data
      */
-    Object getResourceDataForCmHandle(String datastoreName,
-                                      String cmHandleId,
-                                      String resourceIdentifier,
+    Object getResourceDataForCmHandle(CmResourceAddress cmResourceAddress,
                                       FetchDescendantsOption fetchDescendantsOption);
 
     /**
@@ -110,11 +103,11 @@ public interface NetworkCmProxyDataService {
      * @return {@code Object} return data
      */
     Object writeResourceDataPassThroughRunningForCmHandle(String cmHandleId,
-                                                        String resourceIdentifier,
-                                                        OperationType operationType,
-                                                        String requestBody,
-                                                        String contentType,
-                                                        String authorization);
+                                                          String resourceIdentifier,
+                                                          OperationType operationType,
+                                                          String requestBody,
+                                                          String contentType,
+                                                          String authorization);
 
     /**
      * Retrieve module references for the given cm handle.
index 6ab6eab..c15df9c 100755 (executable)
@@ -72,6 +72,7 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
 import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.api.models.DataOperationRequest;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
@@ -127,15 +128,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     @Override
-    public Object getResourceDataForCmHandle(final String datastoreName,
-                                             final String cmHandleId,
-                                             final String resourceIdentifier,
+    public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
                                              final String optionsParamInQuery,
                                              final String topicParamInQuery,
                                              final String requestId,
                                              final String authorization) {
-        final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(datastoreName, cmHandleId,
-            resourceIdentifier,
+        final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmResourceAddress,
             optionsParamInQuery,
             topicParamInQuery,
             requestId,
@@ -144,12 +142,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
     }
 
     @Override
-    public Object getResourceDataForCmHandle(final String datastoreName,
-                                             final String cmHandleId,
-                                             final String resourceIdentifier,
+    public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
                                              final FetchDescendantsOption fetchDescendantsOption) {
-        return cpsDataService.getDataNodes(datastoreName, cmHandleId, resourceIdentifier,
-            fetchDescendantsOption).iterator().next();
+        return cpsDataService.getDataNodes(cmResourceAddress.datastoreName(),
+                                           cmResourceAddress.cmHandleId(),
+                                           cmResourceAddress.resourceIdentifier(),
+                                           fetchDescendantsOption).iterator().next();
     }
 
     @Override
index 2a4bcec..a9ec124 100644 (file)
@@ -42,6 +42,7 @@ import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
 import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
 import org.onap.cps.ncmp.api.impl.utils.data.operation.ResourceDataOperationRequestUtils;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.models.CmResourceAddress;
 import org.onap.cps.ncmp.api.models.DataOperationRequest;
 import org.onap.cps.spi.exceptions.CpsException;
 import org.onap.cps.utils.JsonObjectMapper;
@@ -70,9 +71,7 @@ public class DmiDataOperations extends DmiOperations {
      * This method fetches the resource data from operational data store for given cm handle
      * identifier on given resource using dmi client.
      *
-     * @param dataStoreName       name of data store
-     * @param cmHandleId          network resource identifier
-     * @param resourceId          resource identifier
+     * @param cmResourceAddress   target datastore, cm handle and resource identifier
      * @param optionsParamInQuery options query
      * @param topicParamInQuery   topic name for (triggering) async responses
      * @param requestId           requestId for async responses
@@ -82,19 +81,17 @@ public class DmiDataOperations extends DmiOperations {
     @Timed(value = "cps.ncmp.dmi.get",
             description = "Time taken to fetch the resource data from operational data store for given cm handle "
                     + "identifier on given resource using dmi client")
-    public ResponseEntity<Object> getResourceDataFromDmi(final String dataStoreName,
-                                                         final String cmHandleId,
-                                                         final String resourceId,
+    public ResponseEntity<Object> getResourceDataFromDmi(final CmResourceAddress cmResourceAddress,
                                                          final String optionsParamInQuery,
                                                          final String topicParamInQuery,
                                                          final String requestId,
                                                          final String authorization) {
-        final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
+        final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.cmHandleId());
         final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
         validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
-        final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null,
-                yangModelCmHandle);
-        final String dmiResourceDataUrl = getDmiRequestUrl(dataStoreName, cmHandleId, resourceId, optionsParamInQuery,
+        final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
+        final String dmiResourceDataUrl = getDmiRequestUrl(cmResourceAddress.datastoreName(),
+            cmResourceAddress.cmHandleId(), cmResourceAddress.resourceIdentifier(), optionsParamInQuery,
                 topicParamInQuery, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA));
         return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ, authorization);
     }
index f14439f..60f39fc 100644 (file)
@@ -115,23 +115,7 @@ public class AlternateIdChecker {
         for (final NcmpServiceCmHandle ncmpServiceCmHandle : newNcmpServiceCmHandles) {
             final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
             final String proposedAlternateId = ncmpServiceCmHandle.getAlternateId();
-            final boolean isAcceptable;
-            if (StringUtils.isEmpty(proposedAlternateId)) {
-                isAcceptable = true;
-            } else {
-                if (acceptedAlternateIds.contains(proposedAlternateId)) {
-                    isAcceptable = false;
-                    log.warn("Alternate id update ignored, cannot update cm handle {}, alternate id is already "
-                        + "assigned to a different cm handle (in this batch)", cmHandleId);
-                } else {
-                    if (Operation.CREATE.equals(operation)) {
-                        isAcceptable = canApplyAlternateId(cmHandleId, NO_CURRENT_ALTERNATE_ID, proposedAlternateId);
-                    } else {
-                        isAcceptable = canApplyAlternateId(cmHandleId, proposedAlternateId);
-                    }
-                }
-            }
-            if (isAcceptable) {
+            if (isProposedAlternateIdAcceptable(proposedAlternateId, operation, acceptedAlternateIds, cmHandleId)) {
                 acceptedAlternateIds.add(proposedAlternateId);
             } else {
                 rejectedCmHandleIds.add(cmHandleId);
@@ -140,6 +124,22 @@ public class AlternateIdChecker {
         return rejectedCmHandleIds;
     }
 
+    private boolean isProposedAlternateIdAcceptable(final String proposedAlternateId, final Operation operation,
+                                                    final Set<String> acceptedAlternateIds, final String cmHandleId) {
+        if (StringUtils.isEmpty(proposedAlternateId)) {
+            return true;
+        }
+        if (acceptedAlternateIds.contains(proposedAlternateId)) {
+            log.warn("Alternate id update ignored, cannot update cm handle {}, alternate id is already "
+                + "assigned to a different cm handle (in this batch)", cmHandleId);
+            return false;
+        }
+        if (Operation.CREATE.equals(operation)) {
+            return canApplyAlternateId(cmHandleId, NO_CURRENT_ALTERNATE_ID, proposedAlternateId);
+        }
+        return canApplyAlternateId(cmHandleId, proposedAlternateId);
+    }
+
     private boolean alternateIdAlreadyInDb(final String alternateId) {
         try {
             inventoryPersistence.getCmHandleDataNodeByAlternateId(alternateId);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmResourceAddress.java
new file mode 100644 (file)
index 0000000..21d82fc
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 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.models;
+
+public record CmResourceAddress(String datastoreName, String cmHandleId, String resourceIdentifier) {
+
+}
index 74016e4..d47be6c 100644 (file)
@@ -24,6 +24,7 @@
 package org.onap.cps.ncmp.api.impl
 
 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse
+import org.onap.cps.ncmp.api.models.CmResourceAddress
 
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME
@@ -121,35 +122,27 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 >> { new ResponseEntity<>(HttpStatus.CREATED) }
     }
 
-    def 'Get resource data for pass-through operational from DMI.'() {
+    def 'Get resource data for from DMI.'() {
         given: 'cpsDataService returns valid data node'
             mockDataNode()
+        and: 'some cm resource address'
+            def cmResourceAddress = new CmResourceAddress('some datastore','some CM Handle', 'some resource Id')
         and: 'get resource data from DMI is called'
-            mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_OPERATIONAL.datastoreName,'testCmHandle', 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >>
+            mockDmiDataOperations.getResourceDataFromDmi(cmResourceAddress, OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >>
                     new ResponseEntity<>('dmi-response', HttpStatus.OK)
-        when: 'get resource data operational for cm-handle is called'
-            def response = objectUnderTest.getResourceDataForCmHandle(PASSTHROUGH_OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
+        when: 'get resource data operational for the given cm resource address is called'
+            def response = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
         then: 'DMI returns a json response'
             assert response == 'dmi-response'
     }
 
-    def 'Get resource data for pass-through running from DMI.'() {
-        given: 'cpsDataService returns valid data node'
-            mockDataNode()
-        and: 'DMI returns valid response and data'
-            mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_RUNNING.datastoreName, 'testCmHandle', 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >>
-                    new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
-        when: 'get resource data is called'
-            def response = objectUnderTest.getResourceDataForCmHandle(PASSTHROUGH_RUNNING.datastoreName, 'testCmHandle', 'testResourceId', OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
-        then: 'get resource data returns expected response'
-            assert response == '{dmi-response}'
-    }
-
     def 'Get resource data for operational (cached) data.'() {
         given: 'CPS Data service returns some object(s)'
             mockCpsDataService.getDataNodes(OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId', FetchDescendantsOption.OMIT_DESCENDANTS) >> ['First Object', 'other Object']
+        and: 'a cm resource address for the same datastore, cm handle and resource id'
+            def cmResourceAddress = new CmResourceAddress(OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId')
         when: 'get resource data is called'
-            def response = objectUnderTest.getResourceDataForCmHandle(OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId', FetchDescendantsOption.OMIT_DESCENDANTS)
+            def response = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, FetchDescendantsOption.OMIT_DESCENDANTS)
         then: 'get resource data returns teh first object from the data service'
             assert response == 'First Object'
     }
index e154588..eb6c7a0 100644 (file)
@@ -28,6 +28,7 @@ import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException
 import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder
 import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext
 import org.onap.cps.ncmp.api.models.DataOperationRequest
+import org.onap.cps.ncmp.api.models.CmResourceAddress
 import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent
 import org.onap.cps.ncmp.utils.TestUtils
 import org.onap.cps.utils.JsonObjectMapper
@@ -81,8 +82,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
             mockDmiRestClient.postOperationWithJsonData(expectedUrl, expectedJson, READ, NO_AUTH_HEADER) >> responseFromDmi
             dmiServiceUrlBuilder.getDmiDatastoreUrl(_, _) >> expectedUrl
         when: 'get resource data is invoked'
-            def result = objectUnderTest.getResourceDataFromDmi(dataStore.datastoreName, cmHandleId, resourceIdentifier,
-                    options, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
+            def cmResourceAddress = new CmResourceAddress(dataStore.datastoreName, cmHandleId, resourceIdentifier)
+            def result = objectUnderTest.getResourceDataFromDmi(cmResourceAddress, options, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER)
         then: 'the result is the response from the DMI service'
             assert result == responseFromDmi
         where: 'the following parameters are used'
index 0eabaa1..1e84367 100644 (file)
@@ -80,7 +80,8 @@ class AlternateIdCheckerSpec extends Specification {
             assert result == expectedRejectedCmHandleIds
         where: 'the following alternate ids are used'
             scenario                          | alt1   | alt2   | altAlreadyInDb  || expectedRejectedCmHandleIds
-            'no alternate ids'                | ''     | ''     | ['dont matter'] || []
+            'blank alternate ids'             | ''     | ''     | ['dont matter'] || []
+            'null alternate ids'              | null   | null   | ['dont matter'] || []
             'new alternate ids'               | 'fdn1' | 'fdn2' | ['other fdn']   || []
             'one already used alternate id'   | 'fdn1' | 'fdn2' | ['fdn1']        || ['ch-1']
             'duplicate alternate id in batch' | 'fdn1' | 'fdn1' | ['dont matter'] || ['ch-2']
index 699bf3c..b6e12c0 100644 (file)
                         <dependency>
                             <groupId>com.github.spotbugs</groupId>
                             <artifactId>spotbugs</artifactId>
-                            <version>4.2.0</version>
+                            <version>4.2.3</version>
                         </dependency>
                         <dependency>
                             <groupId>${project.groupId}</groupId>