diff options
9 files changed, 165 insertions, 15 deletions
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 075b451603..449a4344dd 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<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); } /** 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 cca62b9ec0..e96b27df8d 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":[]}' } - 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 e480a46e08..45d5bd911a 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<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); } 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 94544f389f..80cd297280 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<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()); } } 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 562c330657..40a47ecf66 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<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, 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 4f6f0ef491..3e1ba4a971 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 88277d3e97..b0c447ee18 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 9405b66325..44d4f0ce27 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 diff --git a/docs/release-notes.rst b/docs/release-notes.rst index ebcdeb55cb..fdb0b004ba 100755 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -16,6 +16,52 @@ CPS Release Notes .. .. ======================== +.. * * * JAKARTA * * * +.. ======================== + +Version: 2.1.0-SNAPSHOT +======================= + +This section lists the main changes & fixes merged into master (snapshot) version of CPS-NCMP. This information is here to assist developers that want experiment/test using our latest code bases directly. Stability of this is not guaranteed. + +Features +-------- + - `CPS-636 <https://jira.onap.org/browse/CPS-636>`_ Update operation for datastore pass through running + - `CPS-638 <https://jira.onap.org/browse/CPS-638>`_ Delete operation for datastore pass through running + - `CPS-741 <https://jira.onap.org/browse/CPS-741>`_ Re sync after removing cm handles + +Bug Fixes +--------- + + - `CPS-762 <https://jira.onap.org/browse/CPS-762>`_ Query cm handles for module names returns incorrect cm handle identifiers + +Known Limitations, Issues and Workarounds +----------------------------------------- + +*System Limitations* + +None + +*Known Vulnerabilities* + +None + +*Workarounds* + +None + +Security Notes +-------------- + +*Fixed Security Issues* + +None + +*Known Security Issues* + +None + +.. ======================== .. * * * ISTANBUL * * * .. ======================== |