aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-rest
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ncmp-rest')
-rw-r--r--cps-ncmp-rest/docs/openapi/components.yaml108
-rwxr-xr-xcps-ncmp-rest/docs/openapi/ncmp.yml42
-rwxr-xr-xcps-ncmp-rest/docs/openapi/openapi.yml4
-rw-r--r--cps-ncmp-rest/pom.xml3
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java163
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/DatastoreType.java53
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java55
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java51
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java50
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java92
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java64
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java40
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java1
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java44
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy277
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy20
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy14
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy47
18 files changed, 823 insertions, 305 deletions
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index 427f083698..7ca09ceedb 100644
--- a/cps-ncmp-rest/docs/openapi/components.yaml
+++ b/cps-ncmp-rest/docs/openapi/components.yaml
@@ -86,7 +86,7 @@ components:
type: array
items:
type: string
- example: [my-cm-handle1, my-cm-handle2, my-cm-handle3]
+ example: [ my-cm-handle1, my-cm-handle2, my-cm-handle3 ]
DmiPluginRegistrationErrorResponse:
type: object
properties:
@@ -124,14 +124,14 @@ components:
type: string
example: my-cm-handle
cmHandleProperties:
- $ref: '#/components/schemas/RestCmHandleProperties'
+ $ref: '#/components/schemas/RestCmHandleProperties'
publicCmHandleProperties:
- $ref: '#/components/schemas/RestCmHandleProperties'
+ $ref: '#/components/schemas/RestCmHandleProperties'
RestCmHandleProperties:
- type: object
- additionalProperties:
- type: string
- example: my-property
+ type: object
+ additionalProperties:
+ type: string
+ example: my-property
#Response Schemas
RestModuleReference:
@@ -288,21 +288,21 @@ components:
examples:
dataSampleRequest:
- summary: Sample request
- description: Sample request body
- value:
- test:bookstore:
- bookstore-name: Chapters
- categories:
- - code: '01'
- name: SciFi
- books:
+ summary: Sample request
+ description: Sample request body
+ value:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: '01'
+ name: SciFi
+ books:
- authors:
- Iain M. Banks
- Ursula K. Le Guin
- - code: '02'
- name: kids
- books:
+ - code: '02'
+ name: kids
+ books:
- authors:
- Philip Pullman
@@ -351,22 +351,22 @@ components:
- Philip Pullman
dataSampleResponse:
- summary: Sample response
- description: Sample response for selecting 'sample 1'.
- value:
- bookstore:
- categories:
- - code: '01'
- books:
- - authors:
- - Iain M. Banks
- - Ursula K. Le Guin
- name: SciFi
- - code: '02'
- books:
- - authors:
- - Philip Pullman
- name: kids
+ summary: Sample response
+ description: Sample response for selecting 'sample 1'.
+ value:
+ bookstore:
+ categories:
+ - code: '01'
+ books:
+ - authors:
+ - Iain M. Banks
+ - Ursula K. Le Guin
+ name: SciFi
+ - code: '02'
+ books:
+ - authors:
+ - Philip Pullman
+ name: kids
allCmHandleQueryParameters:
value:
@@ -448,7 +448,7 @@ components:
includeDescendantsOptionInQuery:
name: include-descendants
in: query
- description: include-descendants
+ description: Determines if descendants are included in response
required: false
schema:
type: boolean
@@ -526,6 +526,14 @@ components:
type: string
default: application/json
example: application/yang-data+json
+ datastoreName:
+ name: ncmp-datastore-name
+ in: path
+ description: The type of the requested data
+ required: true
+ schema:
+ type: string
+ example: ncmp-datastore:operational
responses:
NotFound:
@@ -555,9 +563,9 @@ components:
schema:
$ref: '#/components/schemas/ErrorMessage'
example:
- status: 403
- message: Forbidden error message
- details: Forbidden error details
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
BadRequest:
description: Bad Request
content:
@@ -565,9 +573,9 @@ components:
schema:
$ref: '#/components/schemas/ErrorMessage'
example:
- status: 400 BAD_REQUEST
- message: Bad request error message
- details: Bad request error details
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
Conflict:
description: Conflict
content:
@@ -575,9 +583,9 @@ components:
schema:
$ref: '#/components/schemas/ErrorMessage'
example:
- status: 409 CONFLICT
- message: Conflict error message
- details: Conflict error details
+ status: 409 CONFLICT
+ message: Conflict error message
+ details: Conflict error details
NotImplemented:
description: The given path has not been implemented
content:
@@ -585,9 +593,9 @@ components:
schema:
$ref: '#/components/schemas/ErrorMessage'
example:
- status: 501
- message: Not implemented error message
- details: Not implemented error details
+ status: 501
+ message: Not implemented error message
+ details: Not implemented error details
Ok:
description: OK
content:
@@ -596,10 +604,10 @@ components:
type: object
Created:
description: Created
- content: {}
+ content: { }
NoContent:
description: No Content
- content: {}
+ content: { }
InternalServerError:
description: Internal Server Error
content:
diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml
index 4266fc4152..5e22f773aa 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp.yml
@@ -17,18 +17,21 @@
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=========================================================
-getResourceDataForPassthroughOperational:
+
+getResourceDataForCmHandle:
get:
tags:
- network-cm-proxy
- summary: Get resource data from pass-through operational for cm handle
- description: Get resource data from pass-through operational for given cm handle
- operationId: getResourceDataOperationalForCmHandle
+ summary: Get resource data for cm handle
+ description: Get resource data for given cm handle
+ operationId: getResourceDataForCmHandle
parameters:
+ - $ref: 'components.yaml#/components/parameters/datastoreName'
- $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery'
- $ref: 'components.yaml#/components/parameters/optionsParamInQuery'
- $ref: 'components.yaml#/components/parameters/topicParamInQuery'
+ - $ref: 'components.yaml#/components/parameters/includeDescendantsOptionInQuery'
responses:
200:
description: OK
@@ -51,37 +54,6 @@ getResourceDataForPassthroughOperational:
$ref: 'components.yaml#/components/responses/BadGateway'
resourceDataForPassthroughRunning:
- get:
- tags:
- - network-cm-proxy
- summary: Get resource data from pass-through running for cm handle
- description: Get resource data from pass-through running for given cm handle
- operationId: getResourceDataRunningForCmHandle
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery'
- - $ref: 'components.yaml#/components/parameters/optionsParamInQuery'
- - $ref: 'components.yaml#/components/parameters/topicParamInQuery'
- responses:
- 200:
- description: OK
- content:
- application/json:
- schema:
- type: object
- examples:
- dataSampleResponse:
- $ref: 'components.yaml#/components/examples/dataSampleResponse'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 500:
- $ref: 'components.yaml#/components/responses/InternalServerError'
- 502:
- $ref: 'components.yaml#/components/responses/BadGateway'
post:
tags:
- network-cm-proxy
diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml
index 8e020668a0..ed15fcd628 100755
--- a/cps-ncmp-rest/docs/openapi/openapi.yml
+++ b/cps-ncmp-rest/docs/openapi/openapi.yml
@@ -26,8 +26,8 @@ info:
servers:
- url: /ncmp
paths:
- /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
- $ref: 'ncmp.yml#/getResourceDataForPassthroughOperational'
+ /v1/ch/{cm-handle}/data/ds/{ncmp-datastore-name}:
+ $ref: 'ncmp.yml#/getResourceDataForCmHandle'
/v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running:
$ref: 'ncmp.yml#/resourceDataForPassthroughRunning'
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index 6a700c3e12..b3021d2410 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -185,7 +185,8 @@
<goal>copy-resources</goal>
</goals>
<configuration>
- <outputDirectory>${project.basedir}/target/classes/static/api-docs/cps-ncmp</outputDirectory>
+ <outputDirectory>${project.basedir}/target/classes/static/api-docs/cps-ncmp
+ </outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/target/generated-sources/swagger/</directory>
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 d2ed393794..9aa8263fc5 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
@@ -29,21 +29,18 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import java.util.stream.Collectors;
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.impl.exception.InvalidTopicException;
import org.onap.cps.ncmp.api.inventory.CompositeState;
import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
-import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.onap.cps.ncmp.rest.controller.handlers.DatastoreType;
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandler;
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandlerFactory;
import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper;
import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters;
@@ -53,9 +50,7 @@ import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState;
import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
import org.onap.cps.ncmp.rest.util.DeprecationHelper;
-import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -68,94 +63,50 @@ import org.springframework.web.bind.annotation.RestController;
public class NetworkCmProxyController implements NetworkCmProxyApi {
private static final String NO_BODY = null;
- private static final String NO_REQUEST_ID = null;
- private static final String NO_TOPIC = null;
private final NetworkCmProxyDataService networkCmProxyDataService;
private final JsonObjectMapper jsonObjectMapper;
-
private final DeprecationHelper deprecationHelper;
private final NcmpRestInputMapper ncmpRestInputMapper;
private final CmHandleStateMapper cmHandleStateMapper;
- private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
- @Value("${notification.async.executor.time-out-value-in-ms:2000}")
- private int timeOutInMilliSeconds;
- @Value("${notification.enabled:true}")
- private boolean asyncEnabled;
+ private final NcmpDatastoreResourceRequestHandlerFactory ncmpDatastoreResourceRequestHandlerFactory;
/**
- * Get resource data from operational datastore.
+ * Get resource data from datastore.
*
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier
+ * @param datastoreName name of the datastore
+ * @param cmHandle cm handle identifier
+ * @param resourceIdentifier resource identifier
* @param optionsParamInQuery options query parameter
- * @param topicParamInQuery topic query parameter
+ * @param topicParamInQuery topic query parameter
+ * @param includeDescendants whether include descendants
* @return {@code ResponseEntity} response from dmi plugin
*/
- @Override
- public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle,
- final @NotNull @Valid String resourceIdentifier,
- final @Valid String optionsParamInQuery,
- final @Valid String topicParamInQuery) {
- if (asyncEnabled && isValidTopic(topicParamInQuery)) {
- final String requestId = UUID.randomUUID().toString();
- log.info("Received Async passthrough-operational request with id {}", requestId);
- cpsNcmpTaskExecutor.executeTask(() ->
- networkCmProxyDataService.getResourceDataOperationalForCmHandle(
- cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId
- ), timeOutInMilliSeconds
- );
- return ResponseEntity.ok(Map.of("requestId", requestId));
- } else {
- log.warn("Asynchronous messaging is currently disabled for passthrough-operational."
- + " Will use synchronous operation.");
- }
- final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(
- cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID);
-
- return ResponseEntity.ok(responseObject);
- }
-
- /**
- * Get resource data from pass-through running datastore.
- *
- * @param cmHandle cm handle identifier
- * @param resourceIdentifier resource identifier
- * @param optionsParamInQuery options query parameter
- * @param topicParamInQuery topic query parameter
- * @return {@code ResponseEntity} response from dmi plugin
- */
@Override
- public ResponseEntity<Object> getResourceDataRunningForCmHandle(final String cmHandle,
- final @NotNull @Valid String resourceIdentifier,
- final @Valid String optionsParamInQuery,
- final @Valid String topicParamInQuery) {
- if (asyncEnabled && isValidTopic(topicParamInQuery)) {
- final String requestId = UUID.randomUUID().toString();
- log.info("Received Async passthrough-running request with id {}", requestId);
- cpsNcmpTaskExecutor.executeTask(() ->
- networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
- cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId
- ), timeOutInMilliSeconds
- );
- return ResponseEntity.ok(Map.of("requestId", requestId));
- } else {
- log.warn("Asynchronous messaging is currently disabled for passthrough-running."
- + " Will use synchronous operation.");
- }
+ public ResponseEntity<Object> getResourceDataForCmHandle(final String datastoreName,
+ final String cmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final Boolean includeDescendants) {
- final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
- cmHandle, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID);
+ final NcmpDatastoreResourceRequestHandler ncmpDatastoreResourceRequestHandler =
+ ncmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceRequestHandler(
+ DatastoreType.fromDatastoreName(datastoreName));
- return ResponseEntity.ok(responseObject);
+ return ncmpDatastoreResourceRequestHandler.getResourceData(cmHandle, resourceIdentifier,
+ optionsParamInQuery, topicParamInQuery, includeDescendants);
}
@Override
public ResponseEntity<Object> patchResourceDataRunningForCmHandle(final String resourceIdentifier,
- final String cmHandle,
- final Object requestBody, final String contentType) {
- final Object responseObject = networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier, PATCH, jsonObjectMapper.asJsonString(requestBody), contentType);
+ final String cmHandle,
+ final Object requestBody,
+ final String contentType) {
+ final Object responseObject = networkCmProxyDataService
+ .writeResourceDataPassThroughRunningForCmHandle(
+ cmHandle, resourceIdentifier, PATCH,
+ jsonObjectMapper.asJsonString(requestBody), contentType);
return ResponseEntity.ok(responseObject);
}
@@ -163,14 +114,16 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Create resource data in datastore pass-through running for given cm-handle.
*
* @param resourceIdentifier resource identifier
- * @param cmHandle cm handle identifier
- * @param requestBody the request body
- * @param contentType content type of body
+ * @param cmHandle cm handle identifier
+ * @param requestBody the request body
+ * @param contentType content type of body
* @return {@code ResponseEntity} response from dmi plugin
*/
@Override
public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String resourceIdentifier,
- final String cmHandle, final Object requestBody, final String contentType) {
+ final String cmHandle,
+ final Object requestBody,
+ final String contentType) {
networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType);
return new ResponseEntity<>(HttpStatus.CREATED);
@@ -180,9 +133,9 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Update resource data in datastore pass-through running for given cm-handle.
*
* @param resourceIdentifier resource identifier
- * @param cmHandle cm handle identifier
- * @param requestBody the request body
- * @param contentType content type of the body
+ * @param cmHandle cm handle identifier
+ * @param requestBody the request body
+ * @param contentType content type of the body
* @return response entity
*/
@Override
@@ -197,11 +150,11 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
/**
- * Delete resource data in datastore pass-through running for a given cm-handle.
+ * Delete resource data in datastore pass-through running for a given cm-handle.
*
* @param resourceIdentifier resource identifier
- * @param cmHandle cm handle identifier
- * @param contentType content type of the body
+ * @param cmHandle cm handle identifier
+ * @param contentType content type of the body
* @return response entity no content if request is successful
*/
@Override
@@ -209,7 +162,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final String resourceIdentifier,
final String contentType) {
networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier, DELETE, NO_BODY, contentType);
+ resourceIdentifier, DELETE, NO_BODY, contentType);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@@ -240,7 +193,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
*/
@Override
public ResponseEntity<List<String>> searchCmHandleIds(
- final CmHandleQueryParameters cmHandleQueryParameters) {
+ final CmHandleQueryParameters cmHandleQueryParameters) {
final CmHandleQueryApiParameters cmHandleQueryApiParameters =
jsonObjectMapper.convertToValueType(cmHandleQueryParameters, CmHandleQueryApiParameters.class);
final Set<String> cmHandleIds = networkCmProxyDataService.executeCmHandleIdSearch(cmHandleQueryApiParameters);
@@ -249,6 +202,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
/**
* Search for Cm Handle and Properties by Name.
+ *
* @param cmHandleId cm-handle identifier
* @return cm handle and its properties
*/
@@ -261,33 +215,35 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
/**
* Get Cm Handle Properties by Cm Handle Id.
+ *
* @param cmHandleId cm-handle identifier
* @return cm handle properties
*/
@Override
public ResponseEntity<RestOutputCmHandlePublicProperties> getCmHandlePublicPropertiesByCmHandleId(
- final String cmHandleId) {
+ final String cmHandleId) {
final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId));
final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties =
- new RestOutputCmHandlePublicProperties();
+ new RestOutputCmHandlePublicProperties();
restOutputCmHandlePublicProperties.setPublicCmHandleProperties(cmHandlePublicProperties);
return ResponseEntity.ok(restOutputCmHandlePublicProperties);
}
/**
* Get Cm Handle State by Cm Handle Id.
+ *
* @param cmHandleId cm-handle identifier
* @return cm handle state
*/
@Override
public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(
- final String cmHandleId) {
+ final String cmHandleId) {
final CompositeState cmHandleState = networkCmProxyDataService.getCmHandleCompositeState(cmHandleId);
final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState =
- new RestOutputCmHandleCompositeState();
+ new RestOutputCmHandleCompositeState();
restOutputCmHandleCompositeState.setState(
- cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason(cmHandleState));
+ cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason(cmHandleState));
return ResponseEntity.ok(restOutputCmHandleCompositeState);
}
@@ -314,22 +270,22 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
*/
public ResponseEntity<List<RestModuleReference>> getModuleReferencesByCmHandle(final String cmHandle) {
final List<RestModuleReference> restModuleReferences =
- networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream()
- .map(ncmpRestInputMapper::toRestModuleReference)
- .collect(Collectors.toList());
+ networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream()
+ .map(ncmpRestInputMapper::toRestModuleReference)
+ .collect(Collectors.toList());
return new ResponseEntity<>(restModuleReferences, HttpStatus.OK);
}
/**
* Set the data sync enabled flag, along with the data sync state for the specified cm handle.
*
- * @param cmHandleId cm handle id
+ * @param cmHandleId cm handle id
* @param dataSyncEnabledFlag data sync enabled flag
* @return response entity ok if request is successful
*/
@Override
public ResponseEntity<Object> setDataSyncEnabledFlagForCmHandle(final String cmHandleId,
- final Boolean dataSyncEnabledFlag) {
+ final Boolean dataSyncEnabledFlag) {
networkCmProxyDataService.setDataSyncEnabled(cmHandleId, dataSyncEnabledFlag);
return new ResponseEntity<>(HttpStatus.OK);
}
@@ -345,15 +301,6 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
return restOutputCmHandle;
}
- private static boolean isValidTopic(final String topicName) {
- if (topicName == null) {
- return false;
- }
- if (CpsValidator.validateTopicName(topicName)) {
- return true;
- }
- throw new InvalidTopicException("Topic name " + topicName + " is invalid", "invalid topic");
- }
}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/DatastoreType.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/DatastoreType.java
new file mode 100644
index 0000000000..959c85d141
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/DatastoreType.java
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Getter;
+
+@Getter
+public enum DatastoreType {
+
+ OPERATIONAL("ncmp-datastore:operational"),
+ PASSTHROUGH_RUNNING("ncmp-datastore:passthrough-running"),
+ PASSTHROUGH_OPERATIONAL("ncmp-datastore:passthrough-operational");
+
+ DatastoreType(final String datastoreName) {
+ this.datastoreName = datastoreName;
+ }
+
+ private final String datastoreName;
+ private static final Map<String, DatastoreType> datastoreNameToDatastoreType = new HashMap<>();
+
+ static {
+ Arrays.stream(DatastoreType.values()).forEach(
+ type -> datastoreNameToDatastoreType.put(type.getDatastoreName(), type));
+ }
+
+ public static DatastoreType fromDatastoreName(final String datastoreName) {
+ return datastoreNameToDatastoreType.get(datastoreName);
+ }
+
+}
+
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java
new file mode 100644
index 0000000000..6ed9b8c4d1
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreOperationalResourceRequestHandler.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+import java.util.function.Supplier;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.onap.cps.spi.FetchDescendantsOption;
+
+@Slf4j
+public class NcmpDatastoreOperationalResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+
+ public NcmpDatastoreOperationalResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService,
+ final CpsNcmpTaskExecutor cpsNcmpTaskExecutor,
+ final int timeOutInMilliSeconds,
+ final boolean notificationFeatureEnabled) {
+ super(networkCmProxyDataService, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ }
+
+ @Override
+ public Supplier<Object> getTask(final String cmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final Boolean includeDescendant) {
+
+ final FetchDescendantsOption fetchDescendantsOption =
+ Boolean.TRUE.equals(includeDescendant) ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+ : FetchDescendantsOption.OMIT_DESCENDANTS;
+
+ return () -> networkCmProxyDataService.getResourceDataOperational(cmHandle, resourceIdentifier,
+ fetchDescendantsOption);
+ }
+
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java
new file mode 100644
index 0000000000..196e5bd33d
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughOperationalResourceRequestHandler.java
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+import java.util.function.Supplier;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+
+@Slf4j
+public class NcmpDatastorePassthroughOperationalResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+
+ public NcmpDatastorePassthroughOperationalResourceRequestHandler(
+ final NetworkCmProxyDataService networkCmProxyDataService,
+ final CpsNcmpTaskExecutor cpsNcmpTaskExecutor,
+ final int timeOutInMilliSeconds,
+ final boolean notificationFeatureEnabled) {
+ super(networkCmProxyDataService, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ }
+
+ @Override
+ public Supplier<Object> getTask(final String cmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final Boolean includeDescendant) {
+
+ return () -> networkCmProxyDataService.getResourceDataOperationalForCmHandle(
+ cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId);
+ }
+
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java
new file mode 100644
index 0000000000..5bf16b7499
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastorePassthroughRunningResourceRequestHandler.java
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+import java.util.function.Supplier;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+
+@Slf4j
+public class NcmpDatastorePassthroughRunningResourceRequestHandler extends NcmpDatastoreResourceRequestHandler {
+
+ public NcmpDatastorePassthroughRunningResourceRequestHandler(
+ final NetworkCmProxyDataService networkCmProxyDataService,
+ final CpsNcmpTaskExecutor cpsNcmpTaskExecutor,
+ final int timeOutInMilliSeconds,
+ final boolean notificationFeatureEnabled) {
+ super(networkCmProxyDataService, cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ }
+
+ @Override
+ public Supplier<Object> getTask(final String cmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final Boolean includeDescendant) {
+
+ return () -> networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(
+ cmHandle, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId);
+ }
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java
new file mode 100644
index 0000000000..a6d313b05f
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandler.java
@@ -0,0 +1,92 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.onap.cps.ncmp.rest.util.TopicValidator;
+import org.springframework.http.ResponseEntity;
+
+@RequiredArgsConstructor
+@Slf4j
+public abstract class NcmpDatastoreResourceRequestHandler {
+
+ private static final String NO_REQUEST_ID = null;
+ private static final String NO_TOPIC = null;
+
+ protected final NetworkCmProxyDataService networkCmProxyDataService;
+ protected final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
+ protected final int timeOutInMilliSeconds;
+ protected final boolean notificationFeatureEnabled;
+
+ protected abstract Supplier<Object> getTask(final String cmHandle,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final String requestId,
+ final Boolean includeDescendant);
+
+
+ /**
+ * Get resource data from datastore.
+ *
+ * @param cmHandleId the cm handle
+ * @param resourceIdentifier the resource identifier
+ * @param optionsParamInQuery the options param in query
+ * @param topicParamInQuery the topic param in query
+ * @param includeDescendants whether include descendants
+ * @return the response entity
+ */
+ public ResponseEntity<Object> getResourceData(final String cmHandleId,
+ final String resourceIdentifier,
+ final String optionsParamInQuery,
+ final String topicParamInQuery,
+ final Boolean includeDescendants) {
+
+ final String requestId = UUID.randomUUID().toString();
+ final boolean asyncResponseRequested = topicParamInQuery != null;
+
+ if (asyncResponseRequested && notificationFeatureEnabled) {
+ TopicValidator.validateTopicName(topicParamInQuery);
+ log.debug("Received Async request with id {}", requestId);
+ cpsNcmpTaskExecutor.executeTask(
+ getTask(cmHandleId, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId,
+ includeDescendants), timeOutInMilliSeconds);
+
+ return ResponseEntity.ok(Map.of("requestId", requestId));
+ }
+
+ if (asyncResponseRequested) {
+ log.warn("Asynchronous messaging is currently disabled, will use synchronous operation.");
+ }
+
+ final Object responseObject =
+ getTask(cmHandleId, resourceIdentifier, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID,
+ includeDescendants).get();
+
+ return ResponseEntity.ok(responseObject);
+ }
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java
new file mode 100644
index 0000000000..35bd578ce2
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactory.java
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.controller.handlers;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class NcmpDatastoreResourceRequestHandlerFactory {
+
+ private final NetworkCmProxyDataService networkCmProxyDataService;
+ private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor;
+
+ @Value("${notification.async.executor.time-out-value-in-ms:2000}")
+ private int timeOutInMilliSeconds;
+ @Value("${notification.enabled:true}")
+ private boolean notificationFeatureEnabled;
+
+ /**
+ * Gets ncmp datastore handler.
+ *
+ * @param datastoreType the datastore type
+ * @return the ncmp datastore handler
+ */
+ public NcmpDatastoreResourceRequestHandler getNcmpDatastoreResourceRequestHandler(
+ final DatastoreType datastoreType) {
+
+ switch (datastoreType) {
+ case OPERATIONAL:
+ return new NcmpDatastoreOperationalResourceRequestHandler(networkCmProxyDataService,
+ cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ case PASSTHROUGH_RUNNING:
+ return new NcmpDatastorePassthroughRunningResourceRequestHandler(networkCmProxyDataService,
+ cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ case PASSTHROUGH_OPERATIONAL:
+ return new NcmpDatastorePassthroughOperationalResourceRequestHandler(networkCmProxyDataService,
+ cpsNcmpTaskExecutor, timeOutInMilliSeconds, notificationFeatureEnabled);
+ default:
+ return null;
+ }
+ }
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java
new file mode 100644
index 0000000000..6a52d5861e
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.exceptions;
+
+import lombok.Getter;
+
+public class InvalidTopicException extends RuntimeException {
+
+ @Getter
+ final String details;
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public InvalidTopicException(final String message, final String details) {
+ super(message);
+ this.details = details;
+ }
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
index c72373344d..98d7f6fd1d 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
@@ -25,7 +25,6 @@ import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.exception.DmiRequestException;
import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
-import org.onap.cps.ncmp.api.impl.exception.InvalidTopicException;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController;
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java
new file mode 100644
index 0000000000..313e7bc012
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java
@@ -0,0 +1,44 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.util;
+
+import java.util.regex.Pattern;
+import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException;
+
+public class TopicValidator {
+
+ private static final Pattern TOPIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9]([._-](?![._-])|"
+ + "[a-zA-Z0-9]){0,120}[a-zA-Z0-9]$");
+
+ /**
+ * Validate kafka topic name pattern.
+ *
+ * @param topicName name of the topic to be validated
+ *
+ * @throws InvalidTopicException if the topic is not valid
+ */
+ public static void validateTopicName(final String topicName) {
+ if (!TOPIC_NAME_PATTERN.matcher(topicName).matches()) {
+ throw new InvalidTopicException("Topic name " + topicName + " is invalid", "invalid topic");
+ }
+ }
+
+}
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 d568a5a925..6e461fa59e 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
@@ -23,51 +23,59 @@
package org.onap.cps.ncmp.rest.controller
+import com.fasterxml.jackson.databind.ObjectMapper
import org.mapstruct.factory.Mappers
+import org.onap.cps.TestUtils
+import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.inventory.CmHandleState
import org.onap.cps.ncmp.api.inventory.CompositeState
-import org.onap.cps.ncmp.api.inventory.LockReasonCategory
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
+import org.onap.cps.ncmp.api.inventory.LockReasonCategory
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
-import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
+import org.onap.cps.ncmp.rest.controller.handlers.DatastoreType
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreOperationalResourceRequestHandler
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastorePassthroughOperationalResourceRequestHandler
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastorePassthroughRunningResourceRequestHandler
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandlerFactory
import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
+import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
import org.onap.cps.ncmp.rest.util.DeprecationHelper
+import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.ModuleDefinition
+import org.onap.cps.spi.model.ModuleReference
+import org.onap.cps.utils.JsonObjectMapper
+import org.spockframework.spring.SpringBean
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
+import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
+import org.springframework.test.web.servlet.MockMvc
import spock.lang.Shared
+import spock.lang.Specification
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
-import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
import static org.onap.cps.ncmp.api.inventory.CompositeState.DataStores
import static org.onap.cps.ncmp.api.inventory.CompositeState.Operational
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
+import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import org.onap.cps.TestUtils
-import org.onap.cps.spi.model.ModuleReference
-import org.onap.cps.utils.JsonObjectMapper
-import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.spockframework.spring.SpringBean
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.beans.factory.annotation.Value
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
-import org.springframework.http.HttpStatus
-import org.springframework.http.MediaType
-import org.springframework.test.web.servlet.MockMvc
-import spock.lang.Specification
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
@WebMvcTest(NetworkCmProxyController)
class NetworkCmProxyControllerSpec extends Specification {
+ public static final int TIMEOUT_IN_MS = 2000
+ public static final boolean NOTIFICATION_ENABLED = true
+
@Autowired
MockMvc mvc
@@ -92,6 +100,9 @@ class NetworkCmProxyControllerSpec extends Specification {
@SpringBean
DeprecationHelper stubbedDeprecationHelper = Stub()
+ @SpringBean
+ NcmpDatastoreResourceRequestHandlerFactory stubbedNcmpDatastoreResourceRequestHandlerFactory = Stub()
+
@Value('${rest.api.ncmp-base-path}/v1')
def ncmpBasePathV1
@@ -104,21 +115,38 @@ class NetworkCmProxyControllerSpec extends Specification {
def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC))
+ void setup() {
+ stubbedNcmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceRequestHandler(
+ DatastoreType.OPERATIONAL) >>
+ new NcmpDatastoreOperationalResourceRequestHandler(
+ mockNetworkCmProxyDataService, spiedCpsTaskExecutor, TIMEOUT_IN_MS, NOTIFICATION_ENABLED)
+
+ stubbedNcmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceRequestHandler(
+ DatastoreType.PASSTHROUGH_OPERATIONAL) >>
+ new NcmpDatastorePassthroughOperationalResourceRequestHandler(
+ mockNetworkCmProxyDataService, spiedCpsTaskExecutor, TIMEOUT_IN_MS, NOTIFICATION_ENABLED)
+
+ stubbedNcmpDatastoreResourceRequestHandlerFactory.getNcmpDatastoreResourceRequestHandler(
+ DatastoreType.PASSTHROUGH_RUNNING) >>
+ new NcmpDatastorePassthroughRunningResourceRequestHandler(
+ mockNetworkCmProxyDataService, spiedCpsTaskExecutor, TIMEOUT_IN_MS, NOTIFICATION_ENABLED)
+ }
+
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)"
+ "?resourceIdentifier=parent/child&options=(a=1,b=2)"
when: 'get data resource request is performed'
def response = mvc.perform(
- get(getUrl)
- .contentType(MediaType.APPLICATION_JSON)
+ get(getUrl)
+ .contentType(MediaType.APPLICATION_JSON)
).andReturn().response
then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle'
1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle',
- 'parent/child',
- '(a=1,b=2)',
- NO_TOPIC,
- NO_REQUEST_ID)
+ 'parent/child',
+ '(a=1,b=2)',
+ NO_TOPIC,
+ NO_REQUEST_ID)
and: 'response status is Ok'
response.status == HttpStatus.OK.value()
}
@@ -126,22 +154,22 @@ class NetworkCmProxyControllerSpec extends Specification {
def 'Get Resource Data from #datastoreInUrl with #scenario.'() {
given: 'resource data url'
def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastoreInUrl}" +
- "?resourceIdentifier=parent/child&options=(a=1,b=2)${topicQueryParam}"
+ "?resourceIdentifier=parent/child&options=(a=1,b=2)${topicQueryParam}"
when: 'get data resource request is performed'
def response = mvc.perform(
- get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
+ get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
then: 'task executor is called appropriate number of times'
- expectedNumberOfExecutorExecutions * spiedCpsTaskExecutor.executeTask(_, 2000)
+ expectedNumberOfExecutorExecutions * spiedCpsTaskExecutor.executeTask(_, TIMEOUT_IN_MS)
and: 'response status is expected'
response.status == HttpStatus.OK.value()
where: 'the following parameters are used'
- scenario | datastoreInUrl | topicQueryParam || expectedTopicName | expectedNumberOfExecutorExecutions
- 'url with valid topic' | 'passthrough-operational' | '&topic=my-topic-name' || 'my-topic-name' | 1
- 'no topic in url' | 'passthrough-operational' | '' || NO_TOPIC | 0
- 'null topic in url' | 'passthrough-operational' | '&topic=null' || 'null' | 1
- 'url with valid topic' | 'passthrough-running' | '&topic=my-topic-name' || 'my-topic-name' | 1
- 'no topic in url' | 'passthrough-running' | '' || NO_TOPIC | 0
- 'null topic in url' | 'passthrough-running' | '&topic=null' || 'null' | 1
+ scenario | datastoreInUrl | topicQueryParam || expectedTopicName | expectedNumberOfExecutorExecutions
+ 'url with valid topic' | 'passthrough-operational' | '&topic=my-topic-name' || 'my-topic-name' | 1
+ 'no topic in url' | 'passthrough-operational' | '' || NO_TOPIC | 0
+ 'null topic in url' | 'passthrough-operational' | '&topic=null' || 'null' | 1
+ 'url with valid topic' | 'passthrough-running' | '&topic=my-topic-name' || 'my-topic-name' | 1
+ 'no topic in url' | 'passthrough-running' | '' || NO_TOPIC | 0
+ 'null topic in url' | 'passthrough-running' | '&topic=null' || 'null' | 1
}
def 'Fail to get Resource Data from #datastoreInUrl when #scenario.'() {
@@ -168,17 +196,17 @@ class NetworkCmProxyControllerSpec extends Specification {
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)"
+ "?resourceIdentifier=" + resourceIdentifier + "&options=(a=1,b=2)"
and: 'ncmp service returns json object'
mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
- resourceIdentifier,
- '(a=1,b=2)',
- NO_TOPIC,
- NO_REQUEST_ID) >> '{valid-json}'
+ resourceIdentifier,
+ '(a=1,b=2)',
+ NO_TOPIC,
+ NO_REQUEST_ID) >> '{valid-json}'
when: 'get data resource request is performed'
def response = mvc.perform(
- get(getUrl)
- .contentType(MediaType.APPLICATION_JSON)
+ get(getUrl)
+ .contentType(MediaType.APPLICATION_JSON)
).andReturn().response
then: 'response status is Ok'
response.status == HttpStatus.OK.value()
@@ -194,7 +222,7 @@ class NetworkCmProxyControllerSpec extends Specification {
'? needs to be encoded as %3F' | 'idWith%3F'
}
- def 'Update resource data from pass-through running.' () {
+ 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"
@@ -210,15 +238,15 @@ class NetworkCmProxyControllerSpec extends Specification {
response.status == HttpStatus.OK.value()
}
- def 'Create Resource Data from pass-through running with #scenario.' () {
+ 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"
+ "?resourceIdentifier=parent/child"
def requestBody = '{"some-key":"some-value"}'
when: 'create resource request is performed'
def response = mvc.perform(
- post(url)
- .contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
+ post(url)
+ .contentType(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
).andReturn().response
then: 'ncmp service method to create resource called'
1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
@@ -227,14 +255,14 @@ class NetworkCmProxyControllerSpec extends Specification {
response.status == HttpStatus.CREATED.value()
}
- def 'Get module references for the given dataspace and cm handle.' () {
+ def 'Get module references for the given dataspace and cm handle.'() {
given: 'get module references url'
def getUrl = "$ncmpBasePathV1/ch/some-cmhandle/modules"
when: 'get module resource request is performed'
- def response =mvc.perform(get(getUrl)).andReturn().response
+ 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')]
+ >> [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'
@@ -248,15 +276,15 @@ class NetworkCmProxyControllerSpec extends Specification {
and: 'the service method is invoked with module names and returns two cm handles'
def cmHandle1 = new NcmpServiceCmHandle()
cmHandle1.cmHandleId = 'some-cmhandle-id1'
- cmHandle1.publicProperties = [color:'yellow']
+ cmHandle1.publicProperties = [color: 'yellow']
def cmHandle2 = new NcmpServiceCmHandle()
cmHandle2.cmHandleId = 'some-cmhandle-id2'
- cmHandle2.publicProperties = [color:'green']
+ cmHandle2.publicProperties = [color: 'green']
mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandle1, cmHandle2]
when: 'the searches api is invoked'
def response = mvc.perform(post(searchesEndpoint)
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonString)).andReturn().response
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(jsonString)).andReturn().response
then: 'response status returns OK'
response.status == HttpStatus.OK.value()
and: 'the expected response content is returned'
@@ -268,14 +296,15 @@ class NetworkCmProxyControllerSpec extends Specification {
def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/some-cm-handle"
and: 'an existing ncmp service cm handle'
def cmHandleId = 'some-cm-handle'
- def dmiProperties = [ prop:'some DMI property' ]
- def publicProperties = [ "public prop":'some public property' ]
+ def dmiProperties = [prop: 'some DMI property']
+ def publicProperties = ["public prop": 'some public property']
def compositeState = compositeStateTestObject()
def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState)
and: 'the service method is invoked with the cm handle id'
1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('some-cm-handle') >> ncmpServiceCmHandle
when: 'the cm handle details api is invoked'
- def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response
+ def response = mvc.perform(
+ get(cmHandleDetailsEndpoint)).andReturn().response
then: 'the correct response is returned'
response.status == HttpStatus.OK.value()
and: 'the response contains the public properties'
@@ -286,30 +315,34 @@ class NetworkCmProxyControllerSpec extends Specification {
!response.contentAsString.contains("some DMI property")
}
- def 'Get Cm Handle public properties by Cm Handle id.' () {
+ def 'Get Cm Handle public properties by Cm Handle id.'() {
given: 'a cm handle properties endpoint'
def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/properties"
and: 'some cm handle public properties'
- def publicProperties = [ 'public prop':'some public property' ]
+ 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()
and: 'the response contains the public properties'
assertContainsPublicProperties(response)
}
- def 'Get Cm Handle composite state by Cm Handle id.' () {
+ def 'Get Cm Handle composite state by Cm Handle id.'() {
given: 'a cm handle state endpoint'
def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/state"
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'
@@ -323,13 +356,14 @@ class NetworkCmProxyControllerSpec extends Specification {
and: 'the service method is invoked with module names and returns two cm handles'
def cmHandel1 = new NcmpServiceCmHandle()
cmHandel1.cmHandleId = 'some-cmhandle-id1'
- cmHandel1.publicProperties = [color:'yellow']
+ cmHandel1.publicProperties = [color: 'yellow']
def cmHandel2 = new NcmpServiceCmHandle()
cmHandel2.cmHandleId = 'some-cmhandle-id2'
- cmHandel2.publicProperties = [color:'green']
+ cmHandel2.publicProperties = [color: 'green']
mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandel1, cmHandel2]
when: 'the searches api is invoked'
- def response = mvc.perform(post(searchesEndpoint)
+ def response = mvc.perform(
+ post(searchesEndpoint)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString)).andReturn().response
then: 'an empty cm handle identifier is returned'
@@ -342,9 +376,10 @@ class NetworkCmProxyControllerSpec extends Specification {
and: 'the service method is invoked with module names and returns cm handle ids'
1 * mockNetworkCmProxyDataService.executeCmHandleIdSearch(_) >> ['some-cmhandle-id1', 'some-cmhandle-id2']
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 == '["some-cmhandle-id1","some-cmhandle-id2"]'
}
@@ -353,37 +388,39 @@ class NetworkCmProxyControllerSpec extends Specification {
when: 'the searches api is invoked'
def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches"
def invalidInputData = '{invalidJson}'
- def response = mvc.perform(post(searchesEndpoint)
+ def response = mvc.perform(
+ post(searchesEndpoint)
.contentType(MediaType.APPLICATION_JSON)
.content(invalidInputData)).andReturn().response
then: 'BAD_REQUEST is returned'
response.getStatus() == 400
}
- def 'Patch resource data in pass-through running datastore.' () {
+ 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"
+ "?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)
+ 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')
+ 'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8')
and: 'the response status is OK'
response.status == HttpStatus.OK.value()
}
- def 'Delete resource data in pass-through running datastore.' () {
+ 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"
+ "?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
+ 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')
@@ -394,12 +431,12 @@ class NetworkCmProxyControllerSpec extends Specification {
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"
+ "?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)
+ get(getUrl)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON_VALUE)
).andReturn().response
then: 'async request id is generated'
assert response.contentAsString.contains("requestId")
@@ -409,32 +446,68 @@ class NetworkCmProxyControllerSpec extends Specification {
':passthrough-running' | 'passthrough-running'
}
- def 'Get module definitions based on cmHandleId.' () {
+ def 'Get module definitions based on cmHandleId.'() {
when: 'get module definition request is performed'
- def response = mvc.perform(get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions"))
- .andReturn().response
+ def response = mvc.perform(
+ get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions"))
+ .andReturn().response
then: 'ncmp service method to get module definitions is called'
mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleId('some-cmhandle')
- >> [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()
}
- def 'Set the data sync enabled based on the cm handle id and the data sync flag is #scenario' () {
+ def 'Set the data sync enabled based on the cm handle id and the data sync flag is #scenario'() {
when: 'the set data sync enabled request is invoked'
- def response = mvc.perform(put("$ncmpBasePathV1/ch/some-cm-handle-id/data-sync?dataSyncEnabled=" + dataSyncEnabledFlag))
- .andReturn().response
+ def response = mvc.perform(
+ put("$ncmpBasePathV1/ch/some-cm-handle-id/data-sync?dataSyncEnabled=" + dataSyncEnabledFlag))
+ .andReturn().response
then: 'method to set data sync enabled is called'
1 * mockNetworkCmProxyDataService.setDataSyncEnabled('some-cm-handle-id', dataSyncEnabledFlag)
and: 'the response returns an OK http code'
response.status == HttpStatus.OK.value()
where: 'the following parameters are used'
- scenario | dataSyncEnabledFlag
- 'enabled' | true
- 'disabled' | false
+ scenario | dataSyncEnabledFlag
+ 'enabled' | true
+ 'disabled' | false
+ }
+
+ def 'Get Resource Data from operational without descendants.'() {
+ given: 'resource data url'
+ def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational" +
+ "?resourceIdentifier=parent/child&include-descendants=false"
+ 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 getResourceDataOperational'
+ 1 * mockNetworkCmProxyDataService.getResourceDataOperational('testCmHandle',
+ 'parent/child',
+ FetchDescendantsOption.OMIT_DESCENDANTS)
+ and: 'response status is Ok'
+ response.status == HttpStatus.OK.value()
+ }
+
+ def 'Get Resource Data from operational including descendants.'() {
+ given: 'resource data url'
+ def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:operational" +
+ "?resourceIdentifier=parent/child&include-descendants=true"
+ 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 getResourceDataOperational'
+ 1 * mockNetworkCmProxyDataService.getResourceDataOperational('testCmHandle',
+ 'parent/child',
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS)
+ and: 'response status is Ok'
+ response.status == HttpStatus.OK.value()
}
def dataStores() {
@@ -453,7 +526,7 @@ class NetworkCmProxyControllerSpec extends Specification {
}
def assertContainsAll(response, assertContent) {
- assertContent.forEach( string -> { assert(response.contentAsString.contains(string)) })
+ assertContent.forEach(string -> { assert (response.contentAsString.contains(string)) })
return void
}
@@ -476,8 +549,8 @@ class NetworkCmProxyControllerSpec extends Specification {
def assertContainsPublicProperties(response) {
def expectedContent = [
- '"publicCmHandleProperties":' ,
- '"public prop"' ,
+ '"publicCmHandleProperties":',
+ '"public prop"',
'"some public property"'
]
return assertContainsAll(response, expectedContent)
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy
new file mode 100644
index 0000000000..3f7a8a5ce2
--- /dev/null
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreResourceRequestHandlerFactorySpec.groovy
@@ -0,0 +1,20 @@
+package org.onap.cps.ncmp.rest.controller.handlers
+
+import spock.lang.Specification
+
+class NcmpDatastoreResourceRequestHandlerFactorySpec extends Specification {
+
+ def objectUnderTest = new NcmpDatastoreResourceRequestHandlerFactory(null, null)
+
+ def 'Creating ncmp datastore request handlers.'() {
+ when: 'a ncmp datastore request handler is created for #datastoreType'
+ def result = objectUnderTest.getNcmpDatastoreResourceRequestHandler(datastoreType)
+ then: 'the result is of the expected class'
+ result.class == expectedClass
+ where: 'the following type of datastore is used'
+ datastoreType || expectedClass
+ DatastoreType.OPERATIONAL || NcmpDatastoreOperationalResourceRequestHandler
+ DatastoreType.PASSTHROUGH_OPERATIONAL || NcmpDatastorePassthroughOperationalResourceRequestHandler
+ DatastoreType.PASSTHROUGH_RUNNING || NcmpDatastorePassthroughRunningResourceRequestHandler
+ }
+} \ No newline at end of file
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
index ce908e7547..b8b7fe3bc6 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -29,8 +29,9 @@ import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper
-import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
+import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreResourceRequestHandlerFactory
import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
+import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
import org.onap.cps.ncmp.rest.util.DeprecationHelper
import org.onap.cps.spi.exceptions.CpsException
import org.onap.cps.spi.exceptions.DataNodeNotFoundException
@@ -48,9 +49,7 @@ import spock.lang.Specification
import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP
import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY
-import static org.springframework.http.HttpStatus.BAD_REQUEST
-import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
-import static org.springframework.http.HttpStatus.NOT_FOUND
+import static org.springframework.http.HttpStatus.*
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
@@ -78,6 +77,9 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@SpringBean
DeprecationHelper stubbedDeprecationHelper = Stub()
+ @SpringBean
+ NcmpDatastoreResourceRequestHandlerFactory mockedNcmpDatastoreResourceRequestHandlerFactory = Mock()
+
@Value('${rest.api.ncmp-base-path}')
def basePathNcmp
@@ -125,7 +127,7 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
def 'Failing DMI Request - passthrough scenario'() {
given: 'failing DMI request'
- setupTestException(new HttpClientRequestException('Error Message Details NCMP', 'Bad Request from DMI', 400) , NCMP)
+ setupTestException(new HttpClientRequestException('Error Message Details NCMP', 'Bad Request from DMI', 400), NCMP)
when: 'the DMI request is executed'
def response = performTestRequest(NCMP)
then: 'NCMP service responds with 502 Bad Gateway status'
@@ -150,7 +152,7 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
return mvc.perform(post("$dataNodeBaseEndpointNcmpInventory/ch").contentType(MediaType.APPLICATION_JSON).content(jsonData)).andReturn().response
}
- static void assertTestResponse(response, expectedStatus , expectedErrorMessage , expectedErrorDetails) {
+ static void assertTestResponse(response, expectedStatus, expectedErrorMessage, expectedErrorDetails) {
assert response.status == expectedStatus.value()
def content = new JsonSlurper().parseText(response.contentAsString)
assert content['status'].toString().contains(expectedStatus.toString())
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy
new file mode 100644
index 0000000000..e626e1505d
--- /dev/null
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy
@@ -0,0 +1,47 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.rest.util
+
+import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException
+import spock.lang.Specification
+
+class TopicValidatorSpec extends Specification {
+
+ def 'Valid topic name validation.'() {
+ when: 'a valid topic name is validated'
+ TopicValidator.validateTopicName('my-valid-topic')
+ then: 'no exception is thrown'
+ noExceptionThrown()
+ }
+
+ def 'Validating invalid topic names.'() {
+ when: 'the invalid topic name is validated'
+ TopicValidator.validateTopicName(topicName)
+ then: 'boolean response will be returned for #scenario'
+ thrown(InvalidTopicException)
+ where: 'the following names are used'
+ scenario | topicName
+ 'empty topic' | ''
+ 'blank topic' | ' '
+ 'invalid non empty topic' | '1_5_*_#'
+ }
+
+}