From f232f30bede7d35c71db2d0201695a1416e37323 Mon Sep 17 00:00:00 2001 From: sourabh_sourabh Date: Tue, 9 May 2023 14:34:59 +0100 Subject: NCMP: Update existing Batch endpoint (Moving url param into rest body) - NCMP batch endpoint is updated to accept details into request payload. - Removed unused code of previous impl. Issue-ID: CPS-1635 Signed-off-by: sourabh_sourabh Change-Id: Ic290b750557da06b861c5a4a9bb12debc495ec2e Signed-off-by: sourabh_sourabh --- .../rest/controller/NetworkCmProxyController.java | 43 ++++++------ .../handlers/NcmpDatastoreRequestHandler.java | 81 +++++++++++++--------- .../NcmpPassthroughResourceRequestHandler.java | 20 +++--- .../handlers/TaskManagementDefaultHandler.java | 14 ++-- .../NetworkCmProxyRestExceptionHandler.java | 2 +- .../exceptions/OperationNotSupportedException.java | 32 +++++++++ .../mapper/ResourceDataBatchRequestMapper.java | 41 +++++++++++ 7 files changed, 158 insertions(+), 75 deletions(-) create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/ResourceDataBatchRequestMapper.java (limited to 'cps-ncmp-rest/src/main/java/org/onap') 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 fca1d6310f..1b78fa0343 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 @@ -23,10 +23,12 @@ package org.onap.cps.ncmp.rest.controller; -import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.CREATE; -import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.DELETE; -import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.PATCH; -import static org.onap.cps.ncmp.api.impl.operations.OperationEnum.UPDATE; +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL; +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE; import java.util.Collection; import java.util.List; @@ -44,8 +46,10 @@ import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandl import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreRequestHandler; import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler; import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper; +import org.onap.cps.ncmp.rest.mapper.ResourceDataBatchRequestMapper; import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; +import org.onap.cps.ncmp.rest.model.ResourceDataBatchRequest; import org.onap.cps.ncmp.rest.model.RestModuleDefinition; import org.onap.cps.ncmp.rest.model.RestModuleReference; import org.onap.cps.ncmp.rest.model.RestOutputCmHandle; @@ -72,6 +76,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { private final CmHandleStateMapper cmHandleStateMapper; private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler; private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler; + private final ResourceDataBatchRequestMapper resourceDataBatchRequestMapper; /** * Get resource data from datastore. @@ -100,19 +105,11 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } @Override - public ResponseEntity getResourceDataForCmHandleBatch(final String resourceIdentifier, - final String topicParamInQuery, - final String datastoreName, - final Object requestBody, - final String optionsParamInQuery, - final Boolean includeDescendants) { - - final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName); - - final List cmHandleIds = jsonObjectMapper.convertJsonString(jsonObjectMapper.asJsonString(requestBody), - List.class); - return ncmpDatastoreRequestHandler.executeRequest(datastoreName, cmHandleIds, resourceIdentifier, - optionsParamInQuery, topicParamInQuery, includeDescendants); + public ResponseEntity getResourceDataForCmHandleBatch(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest) { + return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery, + resourceDataBatchRequestMapper.toResourceDataBatchRequest(resourceDataBatchRequest)); } /** @@ -134,7 +131,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final String optionsParamInQuery, final String topicParamInQuery, final Boolean includeDescendants) { - validateDataStore(DatastoreType.OPERATIONAL, datastoreName); + validateDataStore(OPERATIONAL, datastoreName); return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants); } @@ -156,7 +153,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final Object requestBody, final String contentType) { - validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName); + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); final Object responseObject = networkCmProxyDataService .writeResourceDataPassThroughRunningForCmHandle( @@ -182,7 +179,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final Object requestBody, final String contentType) { - validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName); + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType); @@ -206,7 +203,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final String cmHandle, final Object requestBody, final String contentType) { - validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName); + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType); @@ -228,7 +225,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final String resourceIdentifier, final String contentType) { - validateDataStore(DatastoreType.PASSTHROUGH_RUNNING, datastoreName); + validateDataStore(PASSTHROUGH_RUNNING, datastoreName); networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, DELETE, NO_BODY, contentType); @@ -381,7 +378,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) { - if (DatastoreType.OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) { + if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) { return ncmpCachedResourceRequestHandler; } return ncmpPassthroughResourceRequestHandler; diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java index a32c462e76..a8ca13a752 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java @@ -20,12 +20,19 @@ package org.onap.cps.ncmp.rest.controller.handlers; -import java.util.List; +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ; + 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.impl.exception.InvalidDatastoreException; +import org.onap.cps.ncmp.api.impl.operations.DatastoreType; +import org.onap.cps.ncmp.api.impl.operations.OperationType; +import org.onap.cps.ncmp.api.models.ResourceDataBatchRequest; +import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException; import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor; import org.onap.cps.ncmp.rest.util.TopicValidator; import org.springframework.beans.factory.annotation.Value; @@ -67,7 +74,7 @@ public class NcmpDatastoreRequestHandler implements TaskManagementDefaultHandler final boolean asyncResponseRequested = topicParamInQuery != null; if (asyncResponseRequested && notificationFeatureEnabled) { return executeAsyncTaskAndGetResponseEntity(datastoreName, cmHandleId, resourceIdentifier, - optionsParamInQuery, topicParamInQuery, includeDescendants, false); + optionsParamInQuery, topicParamInQuery, includeDescendants); } if (asyncResponseRequested) { @@ -98,26 +105,21 @@ public class NcmpDatastoreRequestHandler implements TaskManagementDefaultHandler } /** - * Executes synchronous/asynchronous request for batch of cm handles. + * Executes asynchronous request for batch of cm handles to resource data. * - * @param datastoreName the name of the datastore - * @param cmHandleIds list of cm handles - * @param resourceIdentifier the resource identifier - * @param optionsParamInQuery the options param in query - * @param topicParamInQuery the topic param in query - * @param includeDescendants whether to include descendants or not + * @param topicParamInQuery the topic param in query + * @param resourceDataBatchRequest batch request details for resource data * @return the response entity */ - public ResponseEntity executeRequest(final String datastoreName, - final List cmHandleIds, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final boolean includeDescendants) { - - return executeAsyncTaskAndGetResponseEntity(datastoreName, cmHandleIds, resourceIdentifier, optionsParamInQuery, - topicParamInQuery, includeDescendants, true); - + public ResponseEntity executeRequest(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest) { + validateBatchRequest(topicParamInQuery, resourceDataBatchRequest); + if (!notificationFeatureEnabled) { + return ResponseEntity.ok(Map.of("status", + "Asynchronous request is unavailable as notification feature is currently disabled.")); + } + return getRequestIdAndSendBatchRequestToDmiService(topicParamInQuery, resourceDataBatchRequest); } protected ResponseEntity executeTaskAsync(final String topicParamInQuery, @@ -127,7 +129,6 @@ public class NcmpDatastoreRequestHandler implements TaskManagementDefaultHandler TopicValidator.validateTopicName(topicParamInQuery); log.debug("Received Async request with id {}", requestId); cpsNcmpTaskExecutor.executeTask(taskSupplier, timeOutInMilliSeconds); - return ResponseEntity.ok(Map.of("requestId", requestId)); } @@ -136,25 +137,43 @@ public class NcmpDatastoreRequestHandler implements TaskManagementDefaultHandler } private ResponseEntity executeAsyncTaskAndGetResponseEntity(final String datastoreName, - final Object targetObject, + final String cmHandleId, final String resourceIdentifier, final String optionsParamInQuery, final String topicParamInQuery, - final boolean includeDescendants, - final boolean isBulkRequest) { + final boolean includeDescendants) { final String requestId = UUID.randomUUID().toString(); - final Supplier taskSupplier; - if (isBulkRequest) { - taskSupplier = getTaskSupplierForBulkRequest(datastoreName, (List) targetObject, - resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId, includeDescendants); - } else { - taskSupplier = getTaskSupplierForGetRequest(datastoreName, targetObject.toString(), resourceIdentifier, - optionsParamInQuery, topicParamInQuery, requestId, includeDescendants); - } + final Supplier taskSupplier = getTaskSupplierForGetRequest(datastoreName, cmHandleId, + resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId, includeDescendants); if (taskSupplier == NO_OBJECT_SUPPLIER) { return new ResponseEntity<>(Map.of("status", "Unable to execute request as " + "datastore is not implemented."), HttpStatus.NOT_IMPLEMENTED); } return executeTaskAsync(topicParamInQuery, requestId, taskSupplier); } + + private ResponseEntity getRequestIdAndSendBatchRequestToDmiService(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest) { + final String requestId = UUID.randomUUID().toString(); + sendResourceDataBatchRequestAsynchronously(topicParamInQuery, resourceDataBatchRequest, requestId); + return ResponseEntity.ok(Map.of("requestId", requestId)); + } + + private void validateBatchRequest(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest) { + TopicValidator.validateTopicName(topicParamInQuery); + resourceDataBatchRequest.getBatchOperationDefinitions().forEach(batchOperationDetail -> { + if (OperationType.fromOperationName(batchOperationDetail.getOperation()) != READ) { + throw new OperationNotSupportedException( + batchOperationDetail.getOperation() + " operation not yet supported for target ids :" + + batchOperationDetail.getCmHandleIds()); + } else if (DatastoreType.fromDatastoreName(batchOperationDetail.getDatastore()) == OPERATIONAL) { + throw new InvalidDatastoreException(batchOperationDetail.getDatastore() + + " datastore is not supported for target ids : " + + batchOperationDetail.getCmHandleIds()); + } + }); + } } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java index 18e5a9f5ac..5c35818a3a 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java @@ -20,10 +20,11 @@ package org.onap.cps.ncmp.rest.controller.handlers; -import java.util.List; import java.util.function.Supplier; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; +import org.onap.cps.ncmp.api.models.ResourceDataBatchRequest; import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component @@ -56,17 +57,14 @@ public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestH datastoreName, cmHandleId, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId); } + @Async @Override - public Supplier getTaskSupplierForBulkRequest(final String datastoreName, - final List cmHandleIds, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId, - final boolean includeDescendants) { + public void sendResourceDataBatchRequestAsynchronously(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest, + final String requestId) { + networkCmProxyDataService.requestResourceDataForCmHandleBatch(topicParamInQuery, resourceDataBatchRequest, + requestId); - return () -> networkCmProxyDataService.getResourceDataForCmHandleBatch( - datastoreName, cmHandleIds, resourceIdentifier, optionsParamInQuery, topicParamInQuery, requestId); } - } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/TaskManagementDefaultHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/TaskManagementDefaultHandler.java index 6d68f76802..937935bec4 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/TaskManagementDefaultHandler.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/TaskManagementDefaultHandler.java @@ -20,8 +20,8 @@ package org.onap.cps.ncmp.rest.controller.handlers; -import java.util.List; import java.util.function.Supplier; +import org.onap.cps.ncmp.api.models.ResourceDataBatchRequest; import org.onap.cps.spi.FetchDescendantsOption; public interface TaskManagementDefaultHandler { @@ -46,14 +46,10 @@ public interface TaskManagementDefaultHandler { return NO_OBJECT_SUPPLIER; } - default Supplier getTaskSupplierForBulkRequest(final String datastoreName, - final List cmHandleIds, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId, - final boolean includeDescendant) { - return NO_OBJECT_SUPPLIER; + default void sendResourceDataBatchRequestAsynchronously(final String topicParamInQuery, + final ResourceDataBatchRequest + resourceDataBatchRequest, + final String requestId) { } static FetchDescendantsOption getFetchDescendantsOption(final boolean includeDescendants) { 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 5faeee69fc..f459acec25 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 @@ -77,7 +77,7 @@ public class NetworkCmProxyRestExceptionHandler { return wrapDmiErrorResponse(HttpStatus.BAD_GATEWAY, httpClientRequestException); } - @ExceptionHandler({DmiRequestException.class, DataValidationException.class, + @ExceptionHandler({DmiRequestException.class, DataValidationException.class, OperationNotSupportedException.class, HttpMessageNotReadableException.class, InvalidTopicException.class, InvalidDatastoreException.class}) public static ResponseEntity handleDmiRequestExceptions(final Exception exception) { return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java new file mode 100644 index 0000000000..e1daf3df6f --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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; + +public class OperationNotSupportedException extends RuntimeException { + /** + * Instantiates a new not implemented operation exception. + * + * @param message the message + */ + public OperationNotSupportedException(final String message) { + super(message); + } +} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/ResourceDataBatchRequestMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/ResourceDataBatchRequestMapper.java new file mode 100644 index 0000000000..d045e31610 --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/ResourceDataBatchRequestMapper.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.onap.cps.ncmp.api.models.BatchOperationDefinition; +import org.onap.cps.ncmp.api.models.ResourceDataBatchRequest; + +@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) +public interface ResourceDataBatchRequestMapper { + + @Mapping(source = "operations", target = "batchOperationDefinitions") + ResourceDataBatchRequest toResourceDataBatchRequest( + org.onap.cps.ncmp.rest.model.ResourceDataBatchRequest resourceDataBatchRequest); + + @Mapping(source = "targetIds", target = "cmHandleIds") + BatchOperationDefinition toBatchOperationDefinition( + org.onap.cps.ncmp.rest.model.BatchOperationDefinition batchOperationDefinition); +} -- cgit 1.2.3-korg