diff options
8 files changed, 89 insertions, 7 deletions
diff --git a/cps-rest/docs/openapi/cpsData.yml b/cps-rest/docs/openapi/cpsData.yml index ca21df53d..2b65ae440 100644 --- a/cps-rest/docs/openapi/cpsData.yml +++ b/cps-rest/docs/openapi/cpsData.yml @@ -103,6 +103,7 @@ listElementByDataspaceAndAnchor: delete: description: Delete one or all list element(s) for a given anchor and dataspace + deprecated: true tags: - cps-data summary: Delete one or all list element(s) @@ -177,6 +178,28 @@ nodesByDataspaceAndAnchor: '403': $ref: 'components.yml#/components/responses/Forbidden' + delete: + description: Delete a datanode for a given dataspace and anchor given a node xpath. + tags: + - cps-data + summary: Delete a data node + operationId: deleteDataNode + parameters: + - $ref: 'components.yml#/components/parameters/dataspaceNameInPath' + - $ref: 'components.yml#/components/parameters/anchorNameInPath' + - $ref: 'components.yml#/components/parameters/xpathInQuery' + - $ref: 'components.yml#/components/parameters/observedTimestampInQuery' + responses: + '204': + $ref: 'components.yml#/components/responses/NoContent' + '400': + $ref: 'components.yml#/components/responses/BadRequest' + '401': + $ref: 'components.yml#/components/responses/Unauthorized' + '403': + $ref: 'components.yml#/components/responses/Forbidden' + + put: description: Replace a node with descendants for a given dataspace, anchor and a parent node xpath tags: diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java index f29ead9e9..e57fb3c8c 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java @@ -60,6 +60,14 @@ public class DataRestController implements CpsDataApi { } @Override + public ResponseEntity<Void> deleteDataNode(final String dataspaceName, final String anchorName, + final String xpath, final String observedTimestamp) { + cpsDataService.deleteDataNode(dataspaceName, anchorName, xpath, + toOffsetDateTime(observedTimestamp)); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Override public ResponseEntity<String> addListElements(final String parentNodeXpath, final String dataspaceName, final String anchorName, final String jsonData, final String observedTimestamp) { cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonData, diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy index 06f2f5795..2c288344c 100755 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy @@ -342,4 +342,26 @@ class DataRestControllerSpec extends Specification { 'without observed-timestamp' | null || 1 | HttpStatus.NO_CONTENT 'with invalid observed-timestamp' | 'invalid' || 0 | HttpStatus.BAD_REQUEST } + + def 'Delete data node #scenario.'() { + given: 'data node xpath' + def dataNodeXpath = '/dataNodeXpath' + when: 'delete data node endpoint is invoked' + def deleteDataNodeRequest = delete( "$dataNodeBaseEndpoint/anchors/$anchorName/nodes") + .param('xpath', dataNodeXpath) + and: 'observed timestamp is added to the parameters' + if (observedTimestamp != null) + deleteDataNodeRequest.param('observed-timestamp', observedTimestamp) + def response = mvc.perform(deleteDataNodeRequest).andReturn().response + then: 'a successful response is returned' + response.status == expectedHttpStatus.value() + and: 'the api is called with the correct parameters' + expectedApiCount * mockCpsDataService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath, + { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) + where: + scenario | observedTimestamp || expectedApiCount | expectedHttpStatus + 'with observed timestamp' | '2021-03-03T23:59:59.999-0400' || 1 | HttpStatus.NO_CONTENT + 'without observed timestamp' | null || 1 | HttpStatus.NO_CONTENT + 'with invalid observed timestamp' | 'invalid' || 0 | HttpStatus.BAD_REQUEST + } } diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java index e6cb65fa7..f455e47ef 100644 --- a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java @@ -120,6 +120,17 @@ public interface CpsDataService { @NonNull String jsonData, OffsetDateTime observedTimestamp); /** + * Deletes data node for given anchor and dataspace. + * + * @param dataspaceName dataspace name + * @param anchorName anchor name + * @param dataNodeXpath data node xpath + * @param observedTimestamp observed timestamp + */ + void deleteDataNode(@NonNull String dataspaceName, @NonNull String anchorName, @NonNull String dataNodeXpath, + OffsetDateTime observedTimestamp); + + /** * Deletes a list or a list-element under given anchor and dataspace. * * @param dataspaceName dataspace name diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java index 44a17f89d..1445ccadf 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java @@ -134,6 +134,13 @@ public class CpsDataServiceImpl implements CpsDataService { } @Override + public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath, + final OffsetDateTime observedTimestamp) { + cpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath); + processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp); + } + + @Override public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath, final OffsetDateTime observedTimestamp) { cpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, listNodeXpath); diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy index 2bd44824a..ba9c156d7 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy @@ -227,6 +227,17 @@ class CpsDataServiceImplSpec extends Specification { 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp) } + def 'Delete data node under anchor and dataspace.'() { + given: 'schema set for given anchor and dataspace references test tree model' + setupSchemaSetMocks('test-tree.yang') + when: 'delete data node method is invoked with correct parameters' + objectUnderTest.deleteDataNode(dataspaceName, anchorName, '/data-node', observedTimestamp) + then: 'the persistence service method is invoked with the correct parameters' + 1 * mockCpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, '/data-node') + and: 'data updated event is sent to notification service' + 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp) + } + def setupSchemaSetMocks(String... yangResources) { def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build() mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor diff --git a/docker-compose/README.md b/docker-compose/README.md index 3e6ab8367..623968f33 100644 --- a/docker-compose/README.md +++ b/docker-compose/README.md @@ -86,7 +86,7 @@ Then CPS can be started either using a Java Archive previously built or directly Following command starts the application using JAR file: ```bash -DB_HOST=localhost DB_USERNAME=cps DB_PASSWORD=cps CPS_USERNAME=cpsuser CPS_PASSWORD=cpsr0cks! \ +DB_HOST=localhost DB_USERNAME=cps DB_PASSWORD=cps CPS_CORE_USERNAME=cpsuser CPS_CORE_PASSWORD=cpsr0cks! \ java -jar cps-application/target/cps-application-x.y.z-SNAPSHOT.jar ``` @@ -97,7 +97,7 @@ Here are the steps to run or debug the application from Intellij: 1. Enable the desired maven profile form Maven Tool Window 2. Run a configuration from `Run -> Edit configurations` with following settings: * `Environment variables`: `DB_HOST=localhost;DB_USERNAME=cps;DB_PASSWORD=cps - CPS_USERNAME=cpsuser CPS_PASSWORD=cpsr0cks!` + CPS_CORE_USERNAME=cpsuser CPS_CORE_PASSWORD=cpsr0cks!` ## Accessing services diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index 5bdff9d79..d0a157e89 100755 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -30,8 +30,8 @@ services: # - "8881:8080" # - "8887:8081" # environment: - # CPS_USERNAME: ${CPS_USERNAME:-cpsuser} - # CPS_PASSWORD: ${CPS_PASSWORD:-cpsr0cks!} + # CPS_USERNAME: ${CPS_CORE_USERNAME:-cpsuser} + # CPS_PASSWORD: ${CPS_CORE_PASSWORD:-cpsr0cks!} # DB_HOST: dbpostgresql # DB_USERNAME: ${DB_USERNAME:-cps} # DB_PASSWORD: ${DB_PASSWORD:-cps} @@ -49,8 +49,8 @@ services: # - "8882:8080" # - "8887:8081" # environment: - # CPS_USERNAME: ${CPS_USERNAME:-cpsuser} - # CPS_PASSWORD: ${CPS_PASSWORD:-cpsr0cks!} + # CPS_USERNAME: ${CPS_CORE_USERNAME:-cpsuser} + # CPS_PASSWORD: ${CPS_CORE_PASSWORD:-cpsr0cks!} # DB_HOST: dbpostgresql # DB_USERNAME: ${DB_USERNAME:-cps} # DB_PASSWORD: ${DB_PASSWORD:-cps} @@ -104,7 +104,7 @@ services: environment: CPS_USERNAME: ${CPS_CORE_USERNAME:-cpsuser} CPS_PASSWORD: ${CPS_CORE_PASSWORD:-cpsr0cks!} - DB_HOST: ${DB_HOST} + DB_HOST: ${DB_HOST:-dbpostgresql} DB_USERNAME: ${DB_USERNAME:-cps} DB_PASSWORD: ${DB_PASSWORD:-cps} DMI_USERNAME: ${DMI_USERNAME:-cpsuser} |