From d21ba17ca15fb3be4d2728f14b4938dbd091824a Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Fri, 14 Jun 2024 10:01:56 +0100 Subject: [PATCH] Refactor and Move NCMP Data Request Handlers - Simplified NCMP Rest Request Handlers - Moved responsEntity wrapping to Controller so most handler methods can have clear return types - Moved NCMP Rest Request Handlers to Service Layer - Moved related exceptions and utils to Service Layer - Used Lombok for constructors - Improved related testware Issue-ID: CPS-2266 Change-Id: I0025fab1c92e0d613825093b6e4b43dae044c01a Signed-off-by: ToineSiebelink --- .../rest/controller/NetworkCmProxyController.java | 21 +++++---- .../NetworkCmProxyRestExceptionHandler.java | 3 ++ .../controller/NetworkCmProxyControllerSpec.groovy | 47 ++++++++++--------- .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 33 ++++++------- .../impl}/NcmpCachedResourceRequestHandler.java | 39 ++++------------ .../api/impl}/NcmpDatastoreRequestHandler.java | 22 ++++----- .../NcmpPassthroughResourceRequestHandler.java | 49 +++++++------------- .../ncmp}/exceptions/InvalidTopicException.java | 2 +- .../exceptions/OperationNotSupportedException.java | 2 +- .../ncmp}/exceptions/PayloadTooLargeException.java | 2 +- .../org/onap/cps/ncmp/utils}/TopicValidator.java | 4 +- .../impl}/NcmpDatastoreRequestHandlerSpec.groovy | 54 +++++++++++----------- .../onap/cps/ncmp/utils}/TopicValidatorSpec.groovy | 5 +- 13 files changed, 126 insertions(+), 157 deletions(-) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers => cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl}/NcmpCachedResourceRequestHandler.java (69%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers => cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl}/NcmpDatastoreRequestHandler.java (86%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers => cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl}/NcmpPassthroughResourceRequestHandler.java (75%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest => cps-ncmp-service/src/main/java/org/onap/cps/ncmp}/exceptions/InvalidTopicException.java (96%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest => cps-ncmp-service/src/main/java/org/onap/cps/ncmp}/exceptions/OperationNotSupportedException.java (96%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest => cps-ncmp-service/src/main/java/org/onap/cps/ncmp}/exceptions/PayloadTooLargeException.java (96%) rename {cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util => cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils}/TopicValidator.java (94%) rename {cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers => cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl}/NcmpDatastoreRequestHandlerSpec.groovy (81%) rename {cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util => cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils}/TopicValidatorSpec.groovy (92%) 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 5b54ac243..58d6ce710 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 @@ -39,6 +39,9 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; +import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler; +import org.onap.cps.ncmp.api.impl.NcmpDatastoreRequestHandler; +import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler; import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig; import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException; import org.onap.cps.ncmp.api.impl.inventory.CompositeState; @@ -48,9 +51,6 @@ import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; import org.onap.cps.ncmp.api.models.CmResourceAddress; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; -import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler; -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.DataOperationRequestMapper; import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; @@ -62,6 +62,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.spi.model.DataNode; import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.beans.factory.annotation.Qualifier; @@ -112,16 +113,18 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final String authorization) { final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName); final CmResourceAddress cmResourceAddress = new CmResourceAddress(datastoreName, cmHandle, resourceIdentifier); - return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, topicParamInQuery, - includeDescendants, authorization); + final Object result = ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, + topicParamInQuery, includeDescendants, authorization); + return ResponseEntity.ok(result); } @Override public ResponseEntity executeDataOperationForCmHandles(final String topicParamInQuery, final DataOperationRequest dataOperationRequest, final String authorization) { - return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery, + final Object result = ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery, dataOperationRequestMapper.toDataOperationRequest(dataOperationRequest), authorization); + return ResponseEntity.ok(result); } /** @@ -133,7 +136,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { * @param optionsParamInQuery options query parameter * @param topicParamInQuery topic query parameter * @param includeDescendants whether to include descendants or not - * @return {@code ResponseEntity} response from dmi plugin + * @return {@code ResponseEntity} response. Body contains a collection of DataNodes */ @Override @@ -144,7 +147,9 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final String topicParamInQuery, final Boolean includeDescendants) { validateDataStore(OPERATIONAL, datastoreName); - return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants); + final Collection dataNodes = ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, + includeDescendants); + return ResponseEntity.ok(dataNodes); } /** 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 726300089..ba39178c7 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 @@ -29,6 +29,9 @@ import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException; import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException; import org.onap.cps.ncmp.api.impl.exception.NcmpException; import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException; +import org.onap.cps.ncmp.exceptions.InvalidTopicException; +import org.onap.cps.ncmp.exceptions.OperationNotSupportedException; +import org.onap.cps.ncmp.exceptions.PayloadTooLargeException; import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController; import org.onap.cps.ncmp.rest.controller.NetworkCmProxyInventoryController; import org.onap.cps.ncmp.rest.model.DmiErrorMessage; 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 3a5748f00..34b9dbe95 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,42 +23,26 @@ package org.onap.cps.ncmp.rest.controller -import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores -import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_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 static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS -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 ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.core.read.ListAppender import com.fasterxml.jackson.databind.ObjectMapper +import groovy.json.JsonSlurper import org.mapstruct.factory.Mappers import org.onap.cps.TestUtils import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.NetworkCmProxyDataService import org.onap.cps.ncmp.api.NetworkCmProxyQueryService +import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler +import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler import org.onap.cps.ncmp.api.impl.inventory.CmHandleState import org.onap.cps.ncmp.api.impl.inventory.CompositeState import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel -import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.ncmp.api.models.CmResourceAddress -import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler -import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper import org.onap.cps.ncmp.rest.model.DataOperationDefinition @@ -75,15 +59,32 @@ 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.http.ResponseEntity import org.springframework.test.web.servlet.MockMvc +import reactor.core.publisher.Mono import spock.lang.Shared import spock.lang.Specification + import java.time.OffsetDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter -import groovy.json.JsonSlurper -import org.springframework.http.ResponseEntity -import reactor.core.publisher.Mono + +import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores +import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_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 static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS +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 @WebMvcTest(NetworkCmProxyController) class NetworkCmProxyControllerSpec extends Specification { 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 33eb48ffa..af8a8ea12 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 @@ -21,28 +21,17 @@ package org.onap.cps.ncmp.rest.exceptions -import static org.springframework.http.HttpStatus.BAD_GATEWAY -import static org.springframework.http.HttpStatus.BAD_REQUEST -import static org.springframework.http.HttpStatus.CONFLICT -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR -import static org.springframework.http.HttpStatus.NOT_FOUND -import static org.springframework.http.HttpStatus.PAYLOAD_TOO_LARGE -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.test.web.servlet.request.MockMvcRequestBuilders.get -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA - import groovy.json.JsonSlurper import org.mapstruct.factory.Mappers import org.onap.cps.TestUtils import org.onap.cps.ncmp.api.NetworkCmProxyDataService -import org.onap.cps.ncmp.api.impl.exception.DmiRequestException +import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler +import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException +import org.onap.cps.ncmp.api.impl.exception.DmiRequestException import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException +import org.onap.cps.ncmp.exceptions.PayloadTooLargeException import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper -import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler -import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper import org.onap.cps.ncmp.rest.util.DeprecationHelper @@ -60,6 +49,18 @@ import org.springframework.test.web.servlet.MockMvc import spock.lang.Shared import spock.lang.Specification +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA +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_GATEWAY +import static org.springframework.http.HttpStatus.BAD_REQUEST +import static org.springframework.http.HttpStatus.CONFLICT +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR +import static org.springframework.http.HttpStatus.NOT_FOUND +import static org.springframework.http.HttpStatus.PAYLOAD_TOO_LARGE +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post + @WebMvcTest class NetworkCmProxyRestExceptionHandlerSpec extends Specification { @@ -125,7 +126,7 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { 'Data Node Not Found' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | 'DataNode not found' 'Existing entry' | new AlreadyDefinedException('name',null) || CONFLICT | 'Already defined exception' | 'name already exists' 'Existing entries' | AlreadyDefinedException.forDataNodes(['A', 'B'], 'myAnchorName') || CONFLICT | 'Already defined exception' | '2 data node(s) already exist' - 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs' + 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs' } def 'Post request with exception returns correct HTTP Status.'() { diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java similarity index 69% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java index 80e1c442e..eb43718f0 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java @@ -18,36 +18,25 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.controller.handlers; +package org.onap.cps.ncmp.api.impl; import java.util.Collection; +import lombok.RequiredArgsConstructor; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; import org.onap.cps.ncmp.api.NetworkCmProxyQueryService; import org.onap.cps.ncmp.api.models.CmResourceAddress; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; -@Component +@Service +@RequiredArgsConstructor public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandler { private final NetworkCmProxyDataService networkCmProxyDataService; private final NetworkCmProxyQueryService networkCmProxyQueryService; - /** - * Constructor. - * - * @param networkCmProxyDataService @see org.onap.cps.ncmp.api.NetworkCmProxyDataService - * @param networkCmProxyQueryService @see org.onap.cps.ncmp.api.NetworkCmProxyQueryService - */ - public NcmpCachedResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService, - final NetworkCmProxyQueryService networkCmProxyQueryService) { - this.networkCmProxyDataService = networkCmProxyDataService; - this.networkCmProxyQueryService = networkCmProxyQueryService; - } - /** * Executes a synchronous query request for given cm handle. * Note. Currently only ncmp-datastore:operational supports query operations. @@ -55,13 +44,13 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle * @param cmHandleId the cm handle * @param resourceIdentifier the resource identifier * @param includeDescendants whether include descendants - * @return the response entity + * @return a collection of data nodes */ - public ResponseEntity executeRequest(final String cmHandleId, final String resourceIdentifier, + public Collection executeRequest(final String cmHandleId, final String resourceIdentifier, final boolean includeDescendants) { - final Collection dataNodes = getTaskSupplierForQueryRequest(cmHandleId, resourceIdentifier, - includeDescendants); - return ResponseEntity.ok(dataNodes); + final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants); + return networkCmProxyQueryService.queryResourceDataOperational(cmHandleId, resourceIdentifier, + fetchDescendantsOption); } @Override @@ -76,14 +65,6 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle () -> networkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, fetchDescendantsOption)); } - private Collection getTaskSupplierForQueryRequest(final String cmHandleId, - final String resourceIdentifier, - final boolean includeDescendants) { - final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants); - return networkCmProxyQueryService.queryResourceDataOperational(cmHandleId, resourceIdentifier, - fetchDescendantsOption); - } - private static FetchDescendantsOption getFetchDescendantsOption(final boolean includeDescendants) { return includeDescendants ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS; diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java similarity index 86% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java index 20059e20f..dbd2bb493 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java @@ -18,22 +18,19 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.controller.handlers; +package org.onap.cps.ncmp.api.impl; import java.util.Map; import java.util.UUID; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.models.CmResourceAddress; -import org.onap.cps.ncmp.rest.util.TopicValidator; +import org.onap.cps.ncmp.utils.TopicValidator; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; @Slf4j @Service -@RequiredArgsConstructor public abstract class NcmpDatastoreRequestHandler { private static final String NO_REQUEST_ID = null; @@ -52,9 +49,10 @@ public abstract class NcmpDatastoreRequestHandler { * @param topicParamInQuery the topic param in query * @param includeDescendants whether include descendants * @param authorization contents of Authorization header, or null if not present - * @return the response entity + * @return the result object, depends on use op topic. With topic a map object with request id is returned + * otherwise the result of the request. */ - public ResponseEntity executeRequest(final CmResourceAddress cmResourceAddress, + public Object executeRequest(final CmResourceAddress cmResourceAddress, final String optionsParamInQuery, final String topicParamInQuery, final boolean includeDescendants, @@ -72,14 +70,10 @@ public abstract class NcmpDatastoreRequestHandler { } final Mono resourceDataMono = getResourceDataForCmHandle(cmResourceAddress, optionsParamInQuery, NO_TOPIC, NO_REQUEST_ID, includeDescendants, authorization); - return fetchResourceDataSynchronously(resourceDataMono); + return resourceDataMono.block(); } - private ResponseEntity fetchResourceDataSynchronously(final Mono resourceDataMono) { - return ResponseEntity.ok(resourceDataMono.block()); - } - - private ResponseEntity fetchResourceDataAsynchronously(final CmResourceAddress cmResourceAddress, + private Map fetchResourceDataAsynchronously(final CmResourceAddress cmResourceAddress, final String optionsParamInQuery, final String topicParamInQuery, final boolean includeDescendants, @@ -93,7 +87,7 @@ public abstract class NcmpDatastoreRequestHandler { log.error("Async operation failed for request id {}: {}", requestId, error.getMessage())) .subscribe(); log.debug("Received Async request with id {}", requestId); - return ResponseEntity.ok(Map.of("requestId", requestId)); + return Map.of("requestId", requestId); } protected abstract Mono getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress, diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java similarity index 75% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java index 53e374d30..90d9a23d6 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java @@ -18,60 +18,55 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.controller.handlers; +package org.onap.cps.ncmp.api.impl; 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 lombok.RequiredArgsConstructor; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; 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.CmResourceAddress; import org.onap.cps.ncmp.api.models.DataOperationRequest; -import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException; -import org.onap.cps.ncmp.rest.exceptions.PayloadTooLargeException; -import org.onap.cps.ncmp.rest.util.TopicValidator; -import org.springframework.http.ResponseEntity; +import org.onap.cps.ncmp.exceptions.OperationNotSupportedException; +import org.onap.cps.ncmp.exceptions.PayloadTooLargeException; +import org.onap.cps.ncmp.utils.TopicValidator; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; @Service +@RequiredArgsConstructor public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestHandler { private final NetworkCmProxyDataService networkCmProxyDataService; private static final int MAXIMUM_CM_HANDLES_PER_OPERATION = 200; private static final String PAYLOAD_TOO_LARGE_TEMPLATE = "Operation '%s' affects too many (%d) cm handles"; - /** - * Constructor. - * - * @param networkCmProxyDataService @see org.onap.cps.ncmp.api.NetworkCmProxyDataService - */ - public NcmpPassthroughResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService) { - this.networkCmProxyDataService = networkCmProxyDataService; - } - /** * Executes asynchronous request for group of cm handles to resource data. * * @param topicParamInQuery the topic param in query * @param dataOperationRequest data operation request details for resource data * @param authorization contents of Authorization header, or null if not present - * @return the response entity + * @return a map with one entry of request Id for success or status and error when async feature is disabled */ - public ResponseEntity executeRequest(final String topicParamInQuery, - final DataOperationRequest dataOperationRequest, - final String authorization) { + public Map executeRequest(final String topicParamInQuery, + final DataOperationRequest dataOperationRequest, + final String authorization) { validateDataOperationRequest(topicParamInQuery, dataOperationRequest); if (!notificationFeatureEnabled) { - return ResponseEntity.ok(Map.of("status", - "Asynchronous request is unavailable as notification feature is currently disabled.")); + return Map.of("status", + "Asynchronous request is unavailable as notification feature is currently disabled."); } - return getRequestIdAndSendDataOperationRequestToDmiService(topicParamInQuery, dataOperationRequest, - authorization); + final String requestId = UUID.randomUUID().toString(); + networkCmProxyDataService.executeDataOperationForCmHandles(topicParamInQuery, dataOperationRequest, requestId, + authorization); + return Map.of("requestId", requestId); + } @Override @@ -85,16 +80,6 @@ public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestH topicParamInQuery, requestId, authorization); } - private ResponseEntity getRequestIdAndSendDataOperationRequestToDmiService( - final String topicParamInQuery, - final DataOperationRequest dataOperationRequest, - final String authorization) { - final String requestId = UUID.randomUUID().toString(); - networkCmProxyDataService.executeDataOperationForCmHandles(topicParamInQuery, dataOperationRequest, requestId, - authorization); - return ResponseEntity.ok(Map.of("requestId", requestId)); - } - private void validateDataOperationRequest(final String topicParamInQuery, final DataOperationRequest dataOperationRequest) { TopicValidator.validateTopicName(topicParamInQuery); diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java similarity index 96% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java index 6a52d5861..fcf2a28cc 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.exceptions; +package org.onap.cps.ncmp.exceptions; import lombok.Getter; diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java similarity index 96% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java index e1daf3df6..d75c0bd47 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.exceptions; +package org.onap.cps.ncmp.exceptions; public class OperationNotSupportedException extends RuntimeException { /** diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java similarity index 96% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java index cddbd0837..dc7057af7 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.exceptions; +package org.onap.cps.ncmp.exceptions; public class PayloadTooLargeException extends RuntimeException { diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java similarity index 94% rename from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java rename to cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java index 6a46fbd63..f9fed8d43 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java @@ -18,12 +18,12 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.util; +package org.onap.cps.ncmp.utils; import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException; +import org.onap.cps.ncmp.exceptions.InvalidTopicException; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class TopicValidator { diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy similarity index 81% rename from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy rename to cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy index 00b0cb04c..b73f9a46d 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy @@ -18,20 +18,20 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.controller.handlers +package org.onap.cps.ncmp.api.impl import org.onap.cps.ncmp.api.NetworkCmProxyDataService import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException import org.onap.cps.ncmp.api.impl.exception.InvalidOperationException +import org.onap.cps.ncmp.api.models.CmResourceAddress import org.onap.cps.ncmp.api.models.DataOperationDefinition import org.onap.cps.ncmp.api.models.DataOperationRequest -import org.onap.cps.ncmp.api.models.CmResourceAddress -import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException -import org.onap.cps.ncmp.rest.exceptions.PayloadTooLargeException +import org.onap.cps.ncmp.exceptions.OperationNotSupportedException +import org.onap.cps.ncmp.exceptions.PayloadTooLargeException import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity import reactor.core.publisher.Mono import spock.lang.Specification -import spock.util.concurrent.PollingConditions class NcmpDatastoreRequestHandlerSpec extends Specification { @@ -50,19 +50,26 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled and: 'a CM resource address' def cmResourceAddress = new CmResourceAddress('ds', 'ch1', 'resource1') - and: 'the (mocked) service is called with the correct parameters returns OK' - 1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >> Mono.just(HttpStatus.OK) + and: 'the (mocked) service when called with the correct parameters returns a response from dmi' + def resultFromDmi = new ResponseEntity('response from dmi',HttpStatus.I_AM_A_TEAPOT) + def synchronousResult = Mono.justOrEmpty(resultFromDmi) + mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >> synchronousResult when: 'get request is executed with topic = #topic' - def response= objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER) - then: 'a successful response with/without request id is returned' - assert response.statusCode.value == 200 - assert response.body instanceof Map == expectedResponseBodyIsMap + def response = objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER) + then: 'a successful result with/without request id is returned' + if (expectSynchronousResponse) { + assert response.toString().contains('response from dmi') + assert response.toString().contains("I'm a teapot") + } else { + // expect request id in a map + assert response.keySet()[0] == 'requestId' + } where: 'the following parameters are used' - scenario | notificationFeatureEnabled | topic || expectedCalls | expectedResponseBodyIsMap - 'feature on, valid topic' | true | 'valid' || 1 | true - 'feature on, no topic' | true | null || 0 | false - 'feature off, valid topic' | false | 'valid' || 0 | false - 'feature off, no topic' | false | null || 0 | false + scenario | notificationFeatureEnabled | topic || expectSynchronousResponse + 'feature on, valid topic' | true | 'valid' || false + 'feature on, no topic' | true | null || true + 'feature off, valid topic' | false | 'valid' || true + 'feature off, no topic' | false | null || true } def 'Attempt to execute async data operation request with feature #scenario.'() { @@ -86,21 +93,12 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { and: 'a data operation request with datastore: #datastore' def dataOperationDefinition = new DataOperationDefinition(operation: 'read', datastore: datastore) def dataOperationRequest = new DataOperationRequest(dataOperationDefinitions: [dataOperationDefinition]) - and: ' a flag to track the network service call' - def networkServiceMethodCalled = false - and: 'the (mocked) service will use the flag to indicate it is called' - mockNetworkCmProxyDataService.executeDataOperationForCmHandles('myTopic', dataOperationRequest, _, NO_AUTH_HEADER) >> { - networkServiceMethodCalled = true - } when: 'data operation request is executed' def response = objectUnderTest.executeRequest('myTopic', dataOperationRequest, NO_AUTH_HEADER) - and: 'a successful response with request id is returned' - assert response.statusCode.value == 200 - assert response.body.requestId != null + and: 'a map with request id is returned' + assert response.keySet()[0] == 'requestId' then: 'the network service is invoked' - new PollingConditions().within(1) { - assert networkServiceMethodCalled == true - } + 1 * mockNetworkCmProxyDataService.executeDataOperationForCmHandles('myTopic', dataOperationRequest, _, NO_AUTH_HEADER) where: 'the following datastores are used' datastore << ['ncmp-datastore:passthrough-running', 'ncmp-datastore:passthrough-operational'] } diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy similarity index 92% rename from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy rename to cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy index 15e2c1c6a..f96502984 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy @@ -18,9 +18,10 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.rest.util +package org.onap.cps.ncmp.utils -import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException +import org.onap.cps.ncmp.exceptions.InvalidTopicException +import org.onap.cps.ncmp.utils.TopicValidator import spock.lang.Specification class TopicValidatorSpec extends Specification { -- 2.16.6