From: niamhcore Date: Mon, 8 Nov 2021 16:40:28 +0000 (+0000) Subject: Update operation passthrough running - Service Layer X-Git-Tag: mr/823/126723/7~32^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?p=cps.git;a=commitdiff_plain;h=6c7791e04e43b056ab944c3f7935f182fcbb13fb Update operation passthrough running - Service Layer Issue-ID: CPS-636 Signed-off-by: niamhcore Change-Id: I13334df383a23e59b3368b8664c10e086b1eb4a8 --- diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java index 19b9a09da..3e2bdd928 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java @@ -133,9 +133,11 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } @Override - public ResponseEntity updateResourceDataRunningForCmHandle(final String cmHandle, - final String resourceIdentifier, final String requestBody, final String contentType) { - return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + public ResponseEntity updateResourceDataRunningForCmHandle(final String resourceIdentifier, + final String cmHandle, final String requestBody, final String contentType) { + networkCmProxyDataService.updateResourceDataPassThroughRunningForCmHandle(cmHandle, + resourceIdentifier, requestBody, contentType); + return new ResponseEntity<>(HttpStatus.OK); } /** diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy index 4066fd35e..cb3dc6f73 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy @@ -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() } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java index e480a46e0..45d5bd911 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java @@ -168,4 +168,15 @@ public interface NetworkCmProxyDataService { * given module names */ Collection executeCmHandleHasAllModulesSearch(Collection 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); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index 94544f389..80cd29728 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -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 cmHandlePropertiesAsDataNodes = cmHandleDataNode.getChildDataNodes(); + final Map 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 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 responseEntity) { + private static void handleResponseFromDmi(final @NotNull ResponseEntity 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()); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java index 562c33065..40a47ecf6 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java @@ -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 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, diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java index 4f6f0ef49..3e1ba4a97 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java @@ -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) { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 88277d3e9..b0c447ee1 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -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)) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy index 9405b6632..44d4f0ce2 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy @@ -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