Update operation passthrough running - Service Layer 45/125645/3
authorniamhcore <niamh.core@est.tech>
Mon, 8 Nov 2021 16:40:28 +0000 (16:40 +0000)
committerniamhcore <niamh.core@est.tech>
Wed, 10 Nov 2021 13:09:41 +0000 (13:09 +0000)
Issue-ID: CPS-636
Signed-off-by: niamhcore <niamh.core@est.tech>
Change-Id: I13334df383a23e59b3368b8664c10e086b1eb4a8

cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.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/operation/DmiOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java
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/operation/DmiOperationsSpec.groovy

index 19b9a09..3e2bdd9 100755 (executable)
@@ -133,9 +133,11 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
     }
 
     @Override
-    public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String cmHandle,
-        final String resourceIdentifier, final String requestBody, final String contentType) {
-        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+    public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String resourceIdentifier,
+        final String cmHandle, final String requestBody, final String contentType) {
+        networkCmProxyDataService.updateResourceDataPassThroughRunningForCmHandle(cmHandle,
+            resourceIdentifier, requestBody, contentType);
+        return new ResponseEntity<>(HttpStatus.OK);
     }
 
     /**
index 4066fd3..cb3dc6f 100644 (file)
@@ -171,7 +171,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.contentAsString.contains('"leaf":"value"')
     }
 
-    def 'Get Resource Data from pass-through operational.' () {
+    def 'Get Resource Data from passthrough operational.' () {
         given: 'resource data url'
             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
                     "?resourceIdentifier=parent/child&options=(a=1,b=2)"
@@ -190,7 +190,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.status == HttpStatus.OK.value()
     }
 
-    def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.' () {
+    def 'Get Resource Data from passthrough 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)"
@@ -219,7 +219,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             '? needs to be encoded as %3F' | 'idWith%3F'
     }
 
-    def 'Create Resource Data from pass-through running with #scenario.' () {
+    def 'Create Resource Data from passthrough running with #scenario.' () {
         given: 'resource data url'
             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
                     "?resourceIdentifier=parent/child"
@@ -282,7 +282,7 @@ class NetworkCmProxyControllerSpec extends Specification {
             response.contentAsString == '{"cmHandles":null}'
     }
 
-    def 'Update resource data in passthrough-running datastore.' () {
+    def 'Update resource data from passthrough running.' () {
         given: 'update resource data url'
             def updateUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
                     "?resourceIdentifier=parent/child"
@@ -292,8 +292,11 @@ class NetworkCmProxyControllerSpec extends Specification {
                             .contentType(MediaType.APPLICATION_JSON_VALUE)
                             .accept(MediaType.APPLICATION_JSON_VALUE).content('some-request-body')
             ).andReturn().response
-        then: 'the response status is not implemented'
-            response.status == HttpStatus.NOT_IMPLEMENTED.value()
+        then: 'ncmp service method to update resource is called'
+            1 * mockNetworkCmProxyDataService.updateResourceDataPassThroughRunningForCmHandle('testCmHandle',
+                    'parent/child', 'some-request-body', 'application/json;charset=UTF-8')
+        and: 'the response status is OK'
+            response.status == HttpStatus.OK.value()
     }
 }
 
index e480a46..45d5bd9 100644 (file)
@@ -168,4 +168,15 @@ public interface NetworkCmProxyDataService {
      *         given module names
      */
     Collection<String> executeCmHandleHasAllModulesSearch(Collection<String> moduleNames);
+
+    /**
+     * Update resource data for data store pass-through running using dmi for the given cm-handle.
+     *
+     * @param cmHandle cm handle
+     * @param resourceIdentifier resource identifier
+     * @param requestBody request body to create resource
+     * @param contentType content type in body
+     */
+    void updateResourceDataPassThroughRunningForCmHandle(String cmHandle, String resourceIdentifier,
+        String requestBody, String contentType);
 }
index 94544f3..80cd297 100755 (executable)
@@ -49,6 +49,7 @@ import org.onap.cps.ncmp.api.impl.operation.DmiOperations;
 import org.onap.cps.ncmp.api.models.CmHandle;
 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.models.GenericRequestBody;
+import org.onap.cps.ncmp.api.models.GenericRequestBody.OperationEnum;
 import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
 import org.onap.cps.ncmp.api.models.PersistenceCmHandle.AdditionalProperty;
 import org.onap.cps.ncmp.api.models.PersistenceCmHandlesList;
@@ -228,7 +229,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
                         cmHandle,
                         resourceIdentifier,
                         dmiRequestBody);
-        handleResponseForPost(responseEntity);
+        handleResponseFromDmi(responseEntity, "Not able to create resource data.");
     }
 
     @Override
@@ -247,6 +248,36 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         return cpsAdminService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNames);
     }
 
+    /**
+     * Update resource data for data store pass-through running using dmi for given cm-handle.
+     *
+     * @param cmHandle           cm handle
+     * @param resourceIdentifier resource identifier
+     * @param requestBody        request body to create resource
+     * @param contentType        content type in body
+     */
+    @Override
+    public void updateResourceDataPassThroughRunningForCmHandle(final String cmHandle, final String resourceIdentifier,
+        final String requestBody, final String contentType) {
+        final DataNode cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle);
+        final String dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME));
+        final Collection<DataNode> cmHandlePropertiesAsDataNodes = cmHandleDataNode.getChildDataNodes();
+        final Map<String, String> cmHandlePropertiesAsMap = getCmHandlePropertiesAsMap(cmHandlePropertiesAsDataNodes);
+        final GenericRequestBody dmiRequestBodyObject = GenericRequestBody.builder()
+            .operation(OperationEnum.UPDATE)
+            .dataType(contentType)
+            .data(requestBody)
+            .cmHandleProperties(cmHandlePropertiesAsMap)
+            .build();
+        final String dmiRequestBody = prepareOperationBody(dmiRequestBodyObject);
+        final ResponseEntity<String> responseEntity = dmiOperations
+            .updateResourceDataPassThroughRunningFromDmi(dmiServiceName,
+                cmHandle,
+                resourceIdentifier,
+                dmiRequestBody);
+        handleResponseFromDmi(responseEntity, "Unable to replace resource data.");
+    }
+
     private DataNode fetchDataNodeFromDmiRegistryForCmHandle(final String cmHandle) {
         final String xpathForDmiRegistryToFetchCmHandle = "/dmi-registry/cm-handles[@id='" + cmHandle + "']";
         return cpsDataService.getDataNode(NCMP_DATASPACE_NAME,
@@ -301,11 +332,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
         }
     }
 
-    private static void handleResponseForPost(final @NotNull ResponseEntity<String> responseEntity) {
+    private static void handleResponseFromDmi(final @NotNull ResponseEntity<String> responseEntity,
+        final String exceptionMessage) {
         if (!HttpStatus.valueOf(responseEntity.getStatusCodeValue()).is2xxSuccessful()) {
-            throw new NcmpException("Not able to create resource data.",
-                    "DMI status code: " + responseEntity.getStatusCodeValue()
-                            + ", DMI response body: " + responseEntity.getBody());
+            throw new NcmpException(exceptionMessage,
+                "DMI status code: " + responseEntity.getStatusCodeValue()
+                    + ", DMI response body: " + responseEntity.getBody());
         }
     }
 
index 562c330..40a47ec 100644 (file)
@@ -174,6 +174,23 @@ public class DmiOperations {
         return stringBuilder.toString();
     }
 
+    /**
+     * This method updates the resource data from pass-through running data store for the cm handle identifier on given
+     * resource using dmi client.
+     *
+     * @param dmiServiceName dmi service name
+     * @param cmHandle    network resource identifier
+     * @param resourceId  resource identifier
+     * @param jsonBody    json body for put operation
+     * @return {@code ResponseEntity} response entity
+     */
+    public ResponseEntity<String> updateResourceDataPassThroughRunningFromDmi(final String dmiServiceName,
+        final String cmHandle, final String resourceId, final String jsonBody) {
+        final StringBuilder stringBuilder =
+            getStringBuilderForPassThroughUrl(dmiServiceName, cmHandle, resourceId, DataStoreEnum.PASSTHROUGH_RUNNING);
+        return dmiRestClient.postOperationWithJsonData(stringBuilder.toString(), jsonBody, new HttpHeaders());
+    }
+
     private String getDmiDatastoreUrl(final String dmiServiceName,
                                       final String cmHandle,
                                       final String resourceId,
index 4f6f0ef..3e1ba4a 100644 (file)
@@ -33,7 +33,8 @@ import lombok.Getter;
 public class GenericRequestBody   {
     public enum OperationEnum {
         READ("read"),
-        CREATE("create");
+        CREATE("create"),
+        UPDATE("update");
         private String value;
 
         OperationEnum(final String value) {
index 88277d3..b0c447e 100644 (file)
@@ -457,6 +457,29 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             1 * mockCpsAdminService.queryAnchorNames('NFP-Operational', ['some-module-name'])
     }
 
+    def 'Update resource data for pass-through running from dmi using POST #scenario cm handle properties.'() {
+        given: 'data node representing cmHandle #scenario cm handle properties'
+            def cmHandleDataNode = getCmHandleDataNodeForTest(includeCmHandleProperties)
+        and: 'cpsDataService returns valid cm-handle datanode'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
+        when: 'update resource data is called'
+            objectUnderTest.updateResourceDataPassThroughRunningForCmHandle('testCmHandle',
+                    'testResourceId',
+                    '{some-json}', 'application/json')
+        then: 'dmi called with correct data'
+            1 * mockDmiOperations.updateResourceDataPassThroughRunningFromDmi('testDmiService',
+                    'testCmHandle',
+                    'testResourceId',
+                    '{"operation":"update","dataType":"application/json","data":"{some-json}","cmHandleProperties":'
+                            + expectedJsonForCmhandleProperties + '}')
+                    >> new ResponseEntity<>(HttpStatus.OK)
+        where:
+            scenario  | includeCmHandleProperties || expectedJsonForCmhandleProperties
+            'with'    | true                      || '{"testName":"testValue"}'
+            'without' | false                     || '{}'
+    }
+
     def getObjectUnderTestWithModelSyncDisabled() {
         def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsModuleService,
                 mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper))
index 9405b66..44d4f0c 100644 (file)
@@ -118,4 +118,19 @@ class DmiOperationsSpec extends Specification {
         then: 'the post operation is executed with the correct URL and json data'
             1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, requestBody, expectedHttpHeaders)
     }
+
+    def 'Update resource data for pass-through:running datastore from DMI.'() {
+        given: 'the expected url'
+            def cmHandle = 'some-cmhandle'
+            def resourceIdentifier = 'parent/child'
+            def expectedUrl = 'some-dmi-service-name/dmi/v1/ch/' + cmHandle + '/data/ds' +
+                    '/ncmp-datastore:passthrough-running?resourceIdentifier=' + resourceIdentifier
+        when: 'replace resource data is called for DMI'
+            objectUnderTest.updateResourceDataPassThroughRunningFromDmi('some-dmi-service-name',
+                    cmHandle,
+                    resourceIdentifier,
+                    'some-json-body')
+        then: 'the post operation is executed with the correct URL'
+            1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, 'some-json-body', _ as HttpHeaders)
+    }
 }
\ No newline at end of file