From d5b8ee8070ced23a44315bcf0cb73298f4eb08a8 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Thu, 27 Jun 2024 09:06:31 +0100 Subject: Simplify package structure cps-ncmp-rest Issue-ID: CPS-2294 Change-Id: Idc3605c1b877be13a8d344875612da6bef791fc7 Signed-off-by: ToineSiebelink --- .../ncmp/rest/controller/NcmpRestInputMapper.java | 74 --------- .../rest/controller/NetworkCmProxyController.java | 5 +- .../NetworkCmProxyInventoryController.java | 1 + .../NetworkCmProxyRestExceptionHandler.java | 131 +++++++++++++++ .../NetworkCmProxyRestExceptionHandler.java | 133 --------------- .../cps/ncmp/rest/mapper/CmHandleStateMapper.java | 89 ---------- .../rest/mapper/DataOperationRequestMapper.java | 41 ----- .../cps/ncmp/rest/util/CmHandleStateMapper.java | 89 ++++++++++ .../ncmp/rest/util/DataOperationRequestMapper.java | 41 +++++ .../cps/ncmp/rest/util/NcmpRestInputMapper.java | 74 +++++++++ .../rest/controller/NcmpRestInputMapperSpec.groovy | 134 --------------- .../controller/NetworkCmProxyControllerSpec.groovy | 5 +- .../NetworkCmProxyInventoryControllerSpec.groovy | 1 + .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 182 +++++++++++++++++++++ .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 182 --------------------- .../rest/mapper/CmHandleStateMapperSpec.groovy | 84 ---------- .../ncmp/rest/util/CmHandleStateMapperSpec.groovy | 84 ++++++++++ .../ncmp/rest/util/NcmpRestInputMapperSpec.groovy | 134 +++++++++++++++ 18 files changed, 743 insertions(+), 741 deletions(-) delete mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java delete mode 100755 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java delete mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java delete mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/DataOperationRequestMapper.java create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/CmHandleStateMapper.java create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DataOperationRequestMapper.java create mode 100644 cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/NcmpRestInputMapper.java delete mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy create mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy delete mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy delete mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy create mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/CmHandleStateMapperSpec.groovy create mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/NcmpRestInputMapperSpec.groovy diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java deleted file mode 100644 index 7f46c92ec7..0000000000 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapper.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-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.controller; - -import org.mapstruct.InheritConfiguration; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.NullValueCheckStrategy; -import org.mapstruct.NullValuePropertyMappingStrategy; -import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters; -import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration; -import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle; -import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; -import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration; -import org.onap.cps.ncmp.rest.model.RestInputCmHandle; -import org.onap.cps.ncmp.rest.model.RestModuleDefinition; -import org.onap.cps.ncmp.rest.model.RestModuleReference; -import org.onap.cps.spi.model.ModuleDefinition; -import org.onap.cps.spi.model.ModuleReference; - -@Mapper(componentModel = "spring") -public interface NcmpRestInputMapper { - - @Mapping(source = "createdCmHandles", target = "createdCmHandles", - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) - @Mapping(source = "updatedCmHandles", target = "updatedCmHandles", - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) - @Mapping(source = "removedCmHandles", target = "removedCmHandles", - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) - @Mapping(source = "upgradedCmHandles", target = "upgradedCmHandles", - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) - DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration); - - @Mapping(source = "cmHandle", target = "cmHandleId") - @Mapping(source = "cmHandleProperties", target = "dmiProperties") - @Mapping(source = "publicCmHandleProperties", target = "publicProperties") - @Mapping(source = "trustLevel", target = "registrationTrustLevel") - NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle); - - RestModuleReference toRestModuleReference( - final ModuleReference moduleReference); - - @InheritConfiguration(name = "toRestModuleReference") - RestModuleDefinition toRestModuleDefinition( - final ModuleDefinition moduleDefinition); - - @Mapping(source = "cmHandleQueryParameters", target = "cmHandleQueryParameters", - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) - CmHandleQueryServiceParameters toCmHandleQueryServiceParameters( - final CmHandleQueryParameters cmHandleQueryParameters); -} 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 11252b7504..f09b9c67de 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 @@ -46,8 +46,6 @@ import org.onap.cps.ncmp.api.inventory.models.CompositeState; import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.api.models.CmResourceAddress; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; -import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper; -import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper; import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; import org.onap.cps.ncmp.rest.model.DataOperationRequest; @@ -56,7 +54,10 @@ import org.onap.cps.ncmp.rest.model.RestModuleReference; 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.CmHandleStateMapper; +import org.onap.cps.ncmp.rest.util.DataOperationRequestMapper; import org.onap.cps.ncmp.rest.util.DeprecationHelper; +import org.onap.cps.ncmp.rest.util.NcmpRestInputMapper; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.utils.JsonObjectMapper; diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java index 113ee02aa1..8aa86ade36 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java @@ -37,6 +37,7 @@ import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; import org.onap.cps.ncmp.rest.model.CmHandlerRegistrationErrorResponse; import org.onap.cps.ncmp.rest.model.DmiPluginRegistrationErrorResponse; import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration; +import org.onap.cps.ncmp.rest.util.NcmpRestInputMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java new file mode 100644 index 0000000000..6d51f3c7f5 --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java @@ -0,0 +1,131 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2021-2024 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; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +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.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.model.DmiErrorMessage; +import org.onap.cps.ncmp.rest.model.DmiErrorMessageDmiResponse; +import org.onap.cps.ncmp.rest.model.ErrorMessage; +import org.onap.cps.spi.exceptions.AlreadyDefinedException; +import org.onap.cps.spi.exceptions.CpsException; +import org.onap.cps.spi.exceptions.DataNodeNotFoundException; +import org.onap.cps.spi.exceptions.DataValidationException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * Exception handler with error message return. + */ +@Slf4j +@RestControllerAdvice(assignableTypes = {NetworkCmProxyController.class, NetworkCmProxyInventoryController.class}) +@NoArgsConstructor(access = AccessLevel.PACKAGE) +public class NetworkCmProxyRestExceptionHandler { + + private static final String CHECK_LOGS_FOR_DETAILS = "Check logs for details."; + + /** + * Default exception handler. + * + * @param exception the exception to handle + * @return response with response code 500. + */ + @ExceptionHandler + public static ResponseEntity handleInternalServerErrorExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); + } + + @ExceptionHandler({CpsException.class, ServerNcmpException.class}) + public static ResponseEntity handleAnyOtherCpsExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); + } + + @ExceptionHandler({DmiClientRequestException.class}) + public static ResponseEntity handleClientRequestExceptions( + final DmiClientRequestException dmiClientRequestException) { + return wrapDmiErrorResponse(dmiClientRequestException); + } + + @ExceptionHandler({DmiRequestException.class, DataValidationException.class, OperationNotSupportedException.class, + HttpMessageNotReadableException.class, InvalidTopicException.class, InvalidDatastoreException.class, + InvalidDmiResourceUrlException.class}) + public static ResponseEntity handleDmiRequestExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); + } + + @ExceptionHandler({AlreadyDefinedException.class}) + public static ResponseEntity handleAlreadyDefinedExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.CONFLICT, exception); + } + + @ExceptionHandler({DataNodeNotFoundException.class}) + public static ResponseEntity handleNotFoundExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.NOT_FOUND, exception); + } + + @ExceptionHandler({PayloadTooLargeException.class}) + public static ResponseEntity handlePayloadTooLargeExceptions(final Exception exception) { + return buildErrorResponse(HttpStatus.PAYLOAD_TOO_LARGE, exception); + } + + private static ResponseEntity buildErrorResponse(final HttpStatus status, final Exception exception) { + if (exception.getCause() != null || !(exception instanceof CpsException)) { + log.error("Exception occurred", exception); + } + final var errorMessage = new ErrorMessage(); + errorMessage.setStatus(status.toString()); + errorMessage.setMessage(exception.getMessage()); + if (exception instanceof CpsException) { + errorMessage.setDetails(((CpsException) exception).getDetails()); + } else if (exception instanceof NcmpException) { + errorMessage.setDetails(((NcmpException) exception).getDetails()); + } else { + errorMessage.setDetails(CHECK_LOGS_FOR_DETAILS); + } + errorMessage.setDetails( + exception instanceof CpsException ? ((CpsException) exception).getDetails() : CHECK_LOGS_FOR_DETAILS); + return new ResponseEntity<>(errorMessage, status); + } + + private static ResponseEntity wrapDmiErrorResponse(final DmiClientRequestException + dmiClientRequestException) { + final var dmiErrorMessage = new DmiErrorMessage(); + final var dmiErrorResponse = new DmiErrorMessageDmiResponse(); + dmiErrorResponse.setHttpCode(dmiClientRequestException.getHttpStatusCode()); + dmiErrorResponse.setBody(dmiClientRequestException.getResponseBodyAsString()); + dmiErrorMessage.setMessage(dmiClientRequestException.getMessage()); + dmiErrorMessage.setDmiResponse(dmiErrorResponse); + return new ResponseEntity<>(dmiErrorMessage, HttpStatus.BAD_GATEWAY); + } +} 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 deleted file mode 100755 index ba39178c7b..0000000000 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2024 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.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; -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.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; -import org.onap.cps.ncmp.rest.model.DmiErrorMessageDmiResponse; -import org.onap.cps.ncmp.rest.model.ErrorMessage; -import org.onap.cps.spi.exceptions.AlreadyDefinedException; -import org.onap.cps.spi.exceptions.CpsException; -import org.onap.cps.spi.exceptions.DataNodeNotFoundException; -import org.onap.cps.spi.exceptions.DataValidationException; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -/** - * Exception handler with error message return. - */ -@Slf4j -@RestControllerAdvice(assignableTypes = {NetworkCmProxyController.class, NetworkCmProxyInventoryController.class}) -@NoArgsConstructor(access = AccessLevel.PACKAGE) -public class NetworkCmProxyRestExceptionHandler { - - private static final String CHECK_LOGS_FOR_DETAILS = "Check logs for details."; - - /** - * Default exception handler. - * - * @param exception the exception to handle - * @return response with response code 500. - */ - @ExceptionHandler - public static ResponseEntity handleInternalServerErrorExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); - } - - @ExceptionHandler({CpsException.class, ServerNcmpException.class}) - public static ResponseEntity handleAnyOtherCpsExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); - } - - @ExceptionHandler({DmiClientRequestException.class}) - public static ResponseEntity handleClientRequestExceptions( - final DmiClientRequestException dmiClientRequestException) { - return wrapDmiErrorResponse(dmiClientRequestException); - } - - @ExceptionHandler({DmiRequestException.class, DataValidationException.class, OperationNotSupportedException.class, - HttpMessageNotReadableException.class, InvalidTopicException.class, InvalidDatastoreException.class, - InvalidDmiResourceUrlException.class}) - public static ResponseEntity handleDmiRequestExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); - } - - @ExceptionHandler({AlreadyDefinedException.class}) - public static ResponseEntity handleAlreadyDefinedExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.CONFLICT, exception); - } - - @ExceptionHandler({DataNodeNotFoundException.class}) - public static ResponseEntity handleNotFoundExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.NOT_FOUND, exception); - } - - @ExceptionHandler({PayloadTooLargeException.class}) - public static ResponseEntity handlePayloadTooLargeExceptions(final Exception exception) { - return buildErrorResponse(HttpStatus.PAYLOAD_TOO_LARGE, exception); - } - - private static ResponseEntity buildErrorResponse(final HttpStatus status, final Exception exception) { - if (exception.getCause() != null || !(exception instanceof CpsException)) { - log.error("Exception occurred", exception); - } - final var errorMessage = new ErrorMessage(); - errorMessage.setStatus(status.toString()); - errorMessage.setMessage(exception.getMessage()); - if (exception instanceof CpsException) { - errorMessage.setDetails(((CpsException) exception).getDetails()); - } else if (exception instanceof NcmpException) { - errorMessage.setDetails(((NcmpException) exception).getDetails()); - } else { - errorMessage.setDetails(CHECK_LOGS_FOR_DETAILS); - } - errorMessage.setDetails( - exception instanceof CpsException ? ((CpsException) exception).getDetails() : CHECK_LOGS_FOR_DETAILS); - return new ResponseEntity<>(errorMessage, status); - } - - private static ResponseEntity wrapDmiErrorResponse(final DmiClientRequestException - dmiClientRequestException) { - final var dmiErrorMessage = new DmiErrorMessage(); - final var dmiErrorResponse = new DmiErrorMessageDmiResponse(); - dmiErrorResponse.setHttpCode(dmiClientRequestException.getHttpStatusCode()); - dmiErrorResponse.setBody(dmiClientRequestException.getResponseBodyAsString()); - dmiErrorMessage.setMessage(dmiClientRequestException.getMessage()); - dmiErrorMessage.setDmiResponse(dmiErrorResponse); - return new ResponseEntity<>(dmiErrorMessage, HttpStatus.BAD_GATEWAY); - } -} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java deleted file mode 100644 index 3f44ee8528..0000000000 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-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 static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.LOCKED_MISBEHAVING; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Named; -import org.mapstruct.NullValueCheckStrategy; -import org.mapstruct.NullValuePropertyMappingStrategy; -import org.onap.cps.ncmp.api.inventory.models.CompositeState; -import org.onap.cps.ncmp.rest.model.CmHandleCompositeState; -import org.onap.cps.ncmp.rest.model.DataStores; -import org.onap.cps.ncmp.rest.model.LockReason; -import org.onap.cps.ncmp.rest.model.SyncState; - -@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) -public interface CmHandleStateMapper { - - @Mapping(target = "dataSyncState", source = "dataStores", qualifiedByName = "dataStoreToDataSyncState") - @Mapping(target = "lockReason", source = "lockReason", qualifiedByName = "toExternalLockReason") - CmHandleCompositeState toCmHandleCompositeStateExternalLockReason(CompositeState compositeState); - - /** - * Convert from CompositeState datastore to RestOutput Datastores. - * - * @param compositeStateDataStore Composite State data stores - * @return DataStores - */ - @Named("dataStoreToDataSyncState") - static DataStores toDataStores(CompositeState.DataStores compositeStateDataStore) { - - if (compositeStateDataStore == null) { - return null; - } - - final DataStores dataStores = new DataStores(); - - if (compositeStateDataStore.getOperationalDataStore() != null) { - final SyncState operationalSyncState = new SyncState(); - operationalSyncState.setSyncState(compositeStateDataStore.getOperationalDataStore() - .getDataStoreSyncState().name()); - operationalSyncState.setLastSyncTime(compositeStateDataStore.getOperationalDataStore().getLastSyncTime()); - dataStores.setOperational(operationalSyncState); - } - - return dataStores; - } - - /** - * Convert Internal Lock Reason to External Lock Reason. - * - * @param internalLockReason Internal Lock Reason - * - * @return externalLockReason - */ - @Named("toExternalLockReason") - static LockReason toExternalLockReason(CompositeState.LockReason internalLockReason) { - final LockReason externalLockReason = new LockReason(); - if (internalLockReason.getLockReasonCategory() == null) { - externalLockReason.setReason(LOCKED_MISBEHAVING.name()); - } else { - externalLockReason.setReason(internalLockReason.getLockReasonCategory().name()); - } - externalLockReason.setDetails(internalLockReason.getDetails()); - return externalLockReason; - } - -} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/DataOperationRequestMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/DataOperationRequestMapper.java deleted file mode 100644 index 51ee8ca174..0000000000 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/DataOperationRequestMapper.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ============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.DataOperationDefinition; -import org.onap.cps.ncmp.api.models.DataOperationRequest; - -@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, - nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) -public interface DataOperationRequestMapper { - - @Mapping(source = "operations", target = "dataOperationDefinitions") - DataOperationRequest toDataOperationRequest( - org.onap.cps.ncmp.rest.model.DataOperationRequest dataOperationRequest); - - @Mapping(source = "targetIds", target = "cmHandleIds") - DataOperationDefinition toDataOperationDefinition( - org.onap.cps.ncmp.rest.model.DataOperationDefinition dataOperationDefinition); -} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/CmHandleStateMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/CmHandleStateMapper.java new file mode 100644 index 0000000000..4abcb72308 --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/CmHandleStateMapper.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-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.util; + +import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.LOCKED_MISBEHAVING; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.onap.cps.ncmp.api.inventory.models.CompositeState; +import org.onap.cps.ncmp.rest.model.CmHandleCompositeState; +import org.onap.cps.ncmp.rest.model.DataStores; +import org.onap.cps.ncmp.rest.model.LockReason; +import org.onap.cps.ncmp.rest.model.SyncState; + +@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) +public interface CmHandleStateMapper { + + @Mapping(target = "dataSyncState", source = "dataStores", qualifiedByName = "dataStoreToDataSyncState") + @Mapping(target = "lockReason", source = "lockReason", qualifiedByName = "toExternalLockReason") + CmHandleCompositeState toCmHandleCompositeStateExternalLockReason(CompositeState compositeState); + + /** + * Convert from CompositeState datastore to RestOutput Datastores. + * + * @param compositeStateDataStore Composite State data stores + * @return DataStores + */ + @Named("dataStoreToDataSyncState") + static DataStores toDataStores(CompositeState.DataStores compositeStateDataStore) { + + if (compositeStateDataStore == null) { + return null; + } + + final DataStores dataStores = new DataStores(); + + if (compositeStateDataStore.getOperationalDataStore() != null) { + final SyncState operationalSyncState = new SyncState(); + operationalSyncState.setSyncState(compositeStateDataStore.getOperationalDataStore() + .getDataStoreSyncState().name()); + operationalSyncState.setLastSyncTime(compositeStateDataStore.getOperationalDataStore().getLastSyncTime()); + dataStores.setOperational(operationalSyncState); + } + + return dataStores; + } + + /** + * Convert Internal Lock Reason to External Lock Reason. + * + * @param internalLockReason Internal Lock Reason + * + * @return externalLockReason + */ + @Named("toExternalLockReason") + static LockReason toExternalLockReason(CompositeState.LockReason internalLockReason) { + final LockReason externalLockReason = new LockReason(); + if (internalLockReason.getLockReasonCategory() == null) { + externalLockReason.setReason(LOCKED_MISBEHAVING.name()); + } else { + externalLockReason.setReason(internalLockReason.getLockReasonCategory().name()); + } + externalLockReason.setDetails(internalLockReason.getDetails()); + return externalLockReason; + } + +} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DataOperationRequestMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DataOperationRequestMapper.java new file mode 100644 index 0000000000..b84660a095 --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/DataOperationRequestMapper.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.util; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.onap.cps.ncmp.api.models.DataOperationDefinition; +import org.onap.cps.ncmp.api.models.DataOperationRequest; + +@Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) +public interface DataOperationRequestMapper { + + @Mapping(source = "operations", target = "dataOperationDefinitions") + DataOperationRequest toDataOperationRequest( + org.onap.cps.ncmp.rest.model.DataOperationRequest dataOperationRequest); + + @Mapping(source = "targetIds", target = "cmHandleIds") + DataOperationDefinition toDataOperationDefinition( + org.onap.cps.ncmp.rest.model.DataOperationDefinition dataOperationDefinition); +} diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/NcmpRestInputMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/NcmpRestInputMapper.java new file mode 100644 index 0000000000..b9a814dce4 --- /dev/null +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/NcmpRestInputMapper.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-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.util; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters; +import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration; +import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle; +import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; +import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration; +import org.onap.cps.ncmp.rest.model.RestInputCmHandle; +import org.onap.cps.ncmp.rest.model.RestModuleDefinition; +import org.onap.cps.ncmp.rest.model.RestModuleReference; +import org.onap.cps.spi.model.ModuleDefinition; +import org.onap.cps.spi.model.ModuleReference; + +@Mapper(componentModel = "spring") +public interface NcmpRestInputMapper { + + @Mapping(source = "createdCmHandles", target = "createdCmHandles", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + @Mapping(source = "updatedCmHandles", target = "updatedCmHandles", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + @Mapping(source = "removedCmHandles", target = "removedCmHandles", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + @Mapping(source = "upgradedCmHandles", target = "upgradedCmHandles", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration); + + @Mapping(source = "cmHandle", target = "cmHandleId") + @Mapping(source = "cmHandleProperties", target = "dmiProperties") + @Mapping(source = "publicCmHandleProperties", target = "publicProperties") + @Mapping(source = "trustLevel", target = "registrationTrustLevel") + NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle); + + RestModuleReference toRestModuleReference( + final ModuleReference moduleReference); + + @InheritConfiguration(name = "toRestModuleReference") + RestModuleDefinition toRestModuleDefinition( + final ModuleDefinition moduleDefinition); + + @Mapping(source = "cmHandleQueryParameters", target = "cmHandleQueryParameters", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + CmHandleQueryServiceParameters toCmHandleQueryServiceParameters( + final CmHandleQueryParameters cmHandleQueryParameters); +} diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy deleted file mode 100644 index 41521f6398..0000000000 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NcmpRestInputMapperSpec.groovy +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 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 - -import org.mapstruct.factory.Mappers -import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters -import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle -import org.onap.cps.ncmp.api.inventory.models.TrustLevel -import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters -import org.onap.cps.ncmp.rest.model.ConditionProperties -import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration -import org.onap.cps.ncmp.rest.model.RestInputCmHandle -import org.onap.cps.ncmp.rest.model.RestModuleDefinition -import org.onap.cps.ncmp.rest.model.RestModuleReference -import org.onap.cps.spi.model.ModuleDefinition -import org.onap.cps.spi.model.ModuleReference -import spock.lang.Specification - -class NcmpRestInputMapperSpec extends Specification { - - def objectUnderTest = Mappers.getMapper(NcmpRestInputMapper.class) - - def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() { - given: 'a rest cm handle input' - def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: registrationDmiProperties, - publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel, alternateId: 'my-alternate-id', moduleSetTag: 'my-module-set-tag', dataProducerIdentifier: 'my-data-producer-identifier') - def restDmiPluginRegistration = new RestDmiPluginRegistration( - createdCmHandles: [inputRestCmHandle]) - when: 'to plugin dmi registration is called' - def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) - then: 'the result returns the correct number of cm handles' - result.createdCmHandles.size() == 1 - and: 'the converted cm handle has the same id' - result.createdCmHandles[0].cmHandleId == 'example-id' - and: '(empty) properties are converted correctly' - result.createdCmHandles[0].dmiProperties == mappedDmiProperties - result.createdCmHandles[0].publicProperties == mappedPublicProperties - and: 'other fields are mapped correctly' - result.createdCmHandles[0].alternateId == 'my-alternate-id' - result.createdCmHandles[0].moduleSetTag == 'my-module-set-tag' - result.createdCmHandles[0].registrationTrustLevel == mappedTrustLevel - result.createdCmHandles[0].dataProducerIdentifier == 'my-data-producer-identifier' - where: 'the following parameters are used' - scenario | registrationDmiProperties | registrationPublicProperties | registrationTrustLevel || mappedDmiProperties | mappedPublicProperties | mappedTrustLevel - 'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | 'COMPLETE' || ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | TrustLevel.COMPLETE - 'no properties' | null | null | null || [:] | [:] | null - } - - def 'Handling empty dmi registration'() { - given: 'a rest cm handle input without any cm handles' - def restDmiPluginRegistration = new RestDmiPluginRegistration() - when: 'to plugin dmi registration is called' - def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) - then: 'unspecified lists remain as empty lists' - assert result.createdCmHandles == [] - assert result.updatedCmHandles == [] - assert result.removedCmHandles == [] - } - - def 'Handling non-empty dmi registration'() { - given: 'a rest cm handle input with cm handles' - def restDmiPluginRegistration = new RestDmiPluginRegistration( - createdCmHandles: [new RestInputCmHandle()], - updatedCmHandles: [new RestInputCmHandle()], - removedCmHandles: ["some-cmHandle"] - ) - when: 'to dmi plugin registration is called' - def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) - then: 'Lists contain values' - assert result.createdCmHandles[0].class == NcmpServiceCmHandle.class - assert result.updatedCmHandles[0].class == NcmpServiceCmHandle.class - assert result.removedCmHandles == ["some-cmHandle"] - } - - def 'Convert a ModuleReference to a RestModuleReference'() { - given: 'a ModuleReference' - def moduleReference = new ModuleReference() - when: 'toRestModuleReference is called' - def result = objectUnderTest.toRestModuleReference(moduleReference) - then: 'the result is of the correct class RestModuleReference' - result.class == RestModuleReference.class - } - - def 'Convert a ModuleDefinition to a RestModuleDefinition'() { - given: 'a ModuleDefinition' - def moduleDefinition = new ModuleDefinition('moduleName','revision', 'content') - when: 'toRestModuleDefinition is called' - def result = objectUnderTest.toRestModuleDefinition(moduleDefinition) - then: 'the result is of the correct class RestModuleDefinition' - result.class == RestModuleDefinition.class - and: 'all contents are mapped correctly' - result.toString()=='class RestModuleDefinition {\n' + - ' moduleName: moduleName\n' + - ' revision: revision\n' + - ' content: content\n' + - '}' - } - - def 'Convert a CmHandle REST query to CmHandle query service parameters.'() { - given: 'a CmHandle REST query with two conditions' - def conditionParameter1 = new ConditionProperties(conditionName: 'some condition', conditionParameters: [[p1:1]] ) - def conditionParameter2 = new ConditionProperties(conditionName: 'other condition', conditionParameters: [[p2:2]] ) - def cmHandleQuery = new CmHandleQueryParameters() - cmHandleQuery.cmHandleQueryParameters = [conditionParameter1, conditionParameter2] - when: 'it is converted into CmHandle query service parameters' - def result = objectUnderTest.toCmHandleQueryServiceParameters(cmHandleQuery) - then: 'the result is of the correct class' - assert result instanceof CmHandleQueryServiceParameters - and: 'the result has the same conditions' - assert result.cmHandleQueryParameters.size() == 2 - assert result.cmHandleQueryParameters[0].conditionName == 'some condition' - assert result.cmHandleQueryParameters[0].conditionParameters == [[p1:1]] - assert result.cmHandleQueryParameters[1].conditionName == 'other condition' - assert result.cmHandleQueryParameters[1].conditionParameters == [[p2:2]] - } -} 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 65d6d8ca76..ddf041631c 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 @@ -41,11 +41,12 @@ import org.onap.cps.ncmp.api.models.CmResourceAddress import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState import org.onap.cps.ncmp.impl.inventory.models.CmHandleState import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory -import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper -import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper import org.onap.cps.ncmp.rest.model.DataOperationDefinition import org.onap.cps.ncmp.rest.model.DataOperationRequest +import org.onap.cps.ncmp.rest.util.CmHandleStateMapper +import org.onap.cps.ncmp.rest.util.DataOperationRequestMapper import org.onap.cps.ncmp.rest.util.DeprecationHelper +import org.onap.cps.ncmp.rest.util.NcmpRestInputMapper import org.onap.cps.spi.model.ModuleDefinition import org.onap.cps.spi.model.ModuleReference import org.onap.cps.utils.JsonObjectMapper diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy index 244ecfaea7..97c68f08f3 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy @@ -32,6 +32,7 @@ import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters import org.onap.cps.ncmp.rest.model.CmHandlerRegistrationErrorResponse import org.onap.cps.ncmp.rest.model.DmiPluginRegistrationErrorResponse import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration +import org.onap.cps.ncmp.rest.util.NcmpRestInputMapper import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy new file mode 100644 index 0000000000..b1ccf8092a --- /dev/null +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy @@ -0,0 +1,182 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 highstreet technologies GmbH + * Modifications Copyright (C) 2021-2024 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 + +import groovy.json.JsonSlurper +import org.mapstruct.factory.Mappers +import org.onap.cps.TestUtils +import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler +import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler +import org.onap.cps.ncmp.api.impl.NetworkCmProxyFacade +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.api.inventory.NetworkCmProxyInventoryFacade +import org.onap.cps.ncmp.exceptions.PayloadTooLargeException +import org.onap.cps.ncmp.rest.util.CmHandleStateMapper +import org.onap.cps.ncmp.rest.util.DataOperationRequestMapper +import org.onap.cps.ncmp.rest.util.DeprecationHelper +import org.onap.cps.ncmp.rest.util.NcmpRestInputMapper +import org.onap.cps.spi.exceptions.AlreadyDefinedException +import org.onap.cps.spi.exceptions.CpsException +import org.onap.cps.spi.exceptions.DataNodeNotFoundException +import org.onap.cps.spi.exceptions.DataValidationException +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.MediaType +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.controller.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP +import static org.onap.cps.ncmp.rest.controller.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 { + + @Autowired + MockMvc mvc + + @SpringBean + NetworkCmProxyFacade mockNetworkCmProxyFacade = Mock() + + @SpringBean + NetworkCmProxyInventoryFacade mockNetworkCmProxyInventoryFacade = Mock() + + @SpringBean + JsonObjectMapper stubbedJsonObjectMapper = Stub() + + @SpringBean + NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper) + + @SpringBean + CmHandleStateMapper cmHandleStateMapper = Mappers.getMapper(CmHandleStateMapper) + + @SpringBean + DataOperationRequestMapper dataOperationRequestMapper = Mappers.getMapper(DataOperationRequestMapper) + + @SpringBean + DeprecationHelper stubbedDeprecationHelper = Stub() + + @SpringBean + NcmpCachedResourceRequestHandler stubbedNcmpCachedResourceRequestHandler = Stub() + + @SpringBean + NcmpPassthroughResourceRequestHandler StubbedNcmpPassthroughResourceRequestHandler = Stub() + + @Value('${rest.api.ncmp-base-path}') + def basePathNcmp + + @Value('${rest.api.ncmp-inventory-base-path}') + def basePathNcmpInventory + + def dataNodeBaseEndpointNcmp + def dataNodeBaseEndpointNcmpInventory + + @Shared + def sampleErrorMessage = 'some error message' + @Shared + def sampleErrorDetails = 'some error details' + + def setup() { + dataNodeBaseEndpointNcmp = "$basePathNcmp/v1" + dataNodeBaseEndpointNcmpInventory = "$basePathNcmpInventory/v1" + } + + def 'Get request with #scenario exception returns correct HTTP Status with #scenario'() { + when: 'an exception is thrown by the service' + setupTestException(exception, NCMP) + def response = performTestRequest(NCMP) + then: 'an HTTP response is returned with correct message and details' + assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails) + where: + scenario | exception || expectedErrorCode | expectedErrorMessage | expectedErrorDetails + 'CPS' | new CpsException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | sampleErrorDetails + 'NCMP-server' | new ServerNcmpException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null + 'NCMP-client' | new DmiRequestException(sampleErrorMessage, sampleErrorDetails) || BAD_REQUEST | sampleErrorMessage | null + 'DataNode Validation' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | null + 'other' | new IllegalStateException(sampleErrorMessage) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null + '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' + } + + def 'Post request with exception returns correct HTTP Status.'() { + given: 'the service throws data validation exception' + def exception = new DataValidationException(sampleErrorMessage, sampleErrorDetails) + setupTestException(exception, NCMPINVENTORY) + when: 'the HTTP request is made' + def response = performTestRequest(NCMPINVENTORY) + then: 'an HTTP response is returned with correct message and details' + assertTestResponse(response, BAD_REQUEST, sampleErrorMessage, sampleErrorDetails) + } + + def 'Failing DMI Request - passthrough scenario'() { + given: 'failing DMI request' + setupTestException(new DmiClientRequestException(400, 'Error Message Details NCMP', 'Bad Request from DMI', UNABLE_TO_READ_RESOURCE_DATA), NCMP) + when: 'the DMI request is executed' + def response = performTestRequest(NCMP) + then: 'NCMP service responds with 502 Bad Gateway status' + response.status == BAD_GATEWAY.value() + and: 'the NCMP response also contains the original DMI response details' + response.contentAsString.contains('400') + response.contentAsString.contains('Bad Request from DMI') + } + + def setupTestException(exception, apiType) { + if (NCMP == apiType) { + mockNetworkCmProxyInventoryFacade.getYangResourcesModuleReferences(*_) >> { throw exception } + } + mockNetworkCmProxyInventoryFacade.updateDmiRegistrationAndSyncModule(*_) >> { throw exception } + } + + def performTestRequest(apiType) { + if (NCMP == apiType) { + return mvc.perform(get("$dataNodeBaseEndpointNcmp/ch/testCmHandle/modules")).andReturn().response + } + def jsonData = TestUtils.getResourceFileContent('dmi_registration_all_singing_and_dancing.json') + return mvc.perform(post("$dataNodeBaseEndpointNcmpInventory/ch").contentType(MediaType.APPLICATION_JSON).content(jsonData)).andReturn().response + } + + 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()) + assert expectedErrorMessage == null || content['message'].toString().contains(expectedErrorMessage) + assert expectedErrorDetails == null || content['details'].toString().contains(expectedErrorDetails) + } + + enum ApiType { NCMP, NCMPINVENTORY } +} 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 deleted file mode 100644 index 10452b8469..0000000000 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy +++ /dev/null @@ -1,182 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 highstreet technologies GmbH - * Modifications Copyright (C) 2021-2024 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 groovy.json.JsonSlurper -import org.mapstruct.factory.Mappers -import org.onap.cps.TestUtils -import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler -import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler -import org.onap.cps.ncmp.api.impl.NetworkCmProxyFacade -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.api.inventory.NetworkCmProxyInventoryFacade -import org.onap.cps.ncmp.exceptions.PayloadTooLargeException -import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper -import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper -import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper -import org.onap.cps.ncmp.rest.util.DeprecationHelper -import org.onap.cps.spi.exceptions.AlreadyDefinedException -import org.onap.cps.spi.exceptions.CpsException -import org.onap.cps.spi.exceptions.DataNodeNotFoundException -import org.onap.cps.spi.exceptions.DataValidationException -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.MediaType -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 { - - @Autowired - MockMvc mvc - - @SpringBean - NetworkCmProxyFacade mockNetworkCmProxyFacade = Mock() - - @SpringBean - NetworkCmProxyInventoryFacade mockNetworkCmProxyInventoryFacade = Mock() - - @SpringBean - JsonObjectMapper stubbedJsonObjectMapper = Stub() - - @SpringBean - NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper) - - @SpringBean - CmHandleStateMapper cmHandleStateMapper = Mappers.getMapper(CmHandleStateMapper) - - @SpringBean - DataOperationRequestMapper dataOperationRequestMapper = Mappers.getMapper(DataOperationRequestMapper) - - @SpringBean - DeprecationHelper stubbedDeprecationHelper = Stub() - - @SpringBean - NcmpCachedResourceRequestHandler stubbedNcmpCachedResourceRequestHandler = Stub() - - @SpringBean - NcmpPassthroughResourceRequestHandler StubbedNcmpPassthroughResourceRequestHandler = Stub() - - @Value('${rest.api.ncmp-base-path}') - def basePathNcmp - - @Value('${rest.api.ncmp-inventory-base-path}') - def basePathNcmpInventory - - def dataNodeBaseEndpointNcmp - def dataNodeBaseEndpointNcmpInventory - - @Shared - def sampleErrorMessage = 'some error message' - @Shared - def sampleErrorDetails = 'some error details' - - def setup() { - dataNodeBaseEndpointNcmp = "$basePathNcmp/v1" - dataNodeBaseEndpointNcmpInventory = "$basePathNcmpInventory/v1" - } - - def 'Get request with #scenario exception returns correct HTTP Status with #scenario'() { - when: 'an exception is thrown by the service' - setupTestException(exception, NCMP) - def response = performTestRequest(NCMP) - then: 'an HTTP response is returned with correct message and details' - assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails) - where: - scenario | exception || expectedErrorCode | expectedErrorMessage | expectedErrorDetails - 'CPS' | new CpsException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | sampleErrorDetails - 'NCMP-server' | new ServerNcmpException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null - 'NCMP-client' | new DmiRequestException(sampleErrorMessage, sampleErrorDetails) || BAD_REQUEST | sampleErrorMessage | null - 'DataNode Validation' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | null - 'other' | new IllegalStateException(sampleErrorMessage) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null - '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' - } - - def 'Post request with exception returns correct HTTP Status.'() { - given: 'the service throws data validation exception' - def exception = new DataValidationException(sampleErrorMessage, sampleErrorDetails) - setupTestException(exception, NCMPINVENTORY) - when: 'the HTTP request is made' - def response = performTestRequest(NCMPINVENTORY) - then: 'an HTTP response is returned with correct message and details' - assertTestResponse(response, BAD_REQUEST, sampleErrorMessage, sampleErrorDetails) - } - - def 'Failing DMI Request - passthrough scenario'() { - given: 'failing DMI request' - setupTestException(new DmiClientRequestException(400, 'Error Message Details NCMP', 'Bad Request from DMI', UNABLE_TO_READ_RESOURCE_DATA), NCMP) - when: 'the DMI request is executed' - def response = performTestRequest(NCMP) - then: 'NCMP service responds with 502 Bad Gateway status' - response.status == BAD_GATEWAY.value() - and: 'the NCMP response also contains the original DMI response details' - response.contentAsString.contains('400') - response.contentAsString.contains('Bad Request from DMI') - } - - def setupTestException(exception, apiType) { - if (NCMP == apiType) { - mockNetworkCmProxyInventoryFacade.getYangResourcesModuleReferences(*_) >> { throw exception } - } - mockNetworkCmProxyInventoryFacade.updateDmiRegistrationAndSyncModule(*_) >> { throw exception } - } - - def performTestRequest(apiType) { - if (NCMP == apiType) { - return mvc.perform(get("$dataNodeBaseEndpointNcmp/ch/testCmHandle/modules")).andReturn().response - } - def jsonData = TestUtils.getResourceFileContent('dmi_registration_all_singing_and_dancing.json') - return mvc.perform(post("$dataNodeBaseEndpointNcmpInventory/ch").contentType(MediaType.APPLICATION_JSON).content(jsonData)).andReturn().response - } - - 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()) - assert expectedErrorMessage == null || content['message'].toString().contains(expectedErrorMessage) - assert expectedErrorDetails == null || content['details'].toString().contains(expectedErrorDetails) - } - - enum ApiType { NCMP, NCMPINVENTORY } -} diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy deleted file mode 100644 index 8d5e91147f..0000000000 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperSpec.groovy +++ /dev/null @@ -1,84 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022-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.factory.Mappers -import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder -import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState -import org.onap.cps.ncmp.impl.inventory.models.CmHandleState -import org.onap.cps.ncmp.rest.model.CmHandleCompositeState -import spock.lang.Specification - -import java.time.OffsetDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter - -import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.LOCKED_MISBEHAVING -import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.MODULE_SYNC_FAILED - -class CmHandleStateMapperSpec 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)) - def objectUnderTest = Mappers.getMapper(CmHandleStateMapper) - - def 'Composite State to CmHandleCompositeState'() { - given: 'a composite state model' - def compositeState = new CompositeStateBuilder() - .withCmHandleState(CmHandleState.ADVISED) - .withLastUpdatedTime(formattedDateAndTime.toString()) - .withLockReason(MODULE_SYNC_FAILED, 'locked details') - .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, formattedDateAndTime).build() - compositeState.setDataSyncEnabled(false) - when: 'mapper is called' - def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) - then: 'result is of the correct type' - assert result.class == CmHandleCompositeState.class - and: 'mapped result should have correct values' - assert !result.dataSyncEnabled - assert result.lastUpdateTime == formattedDateAndTime - assert result.lockReason.reason == MODULE_SYNC_FAILED.name() - assert result.lockReason.details == 'locked details' - assert result.cmHandleState == 'ADVISED' - assert result.dataSyncState.operational.getSyncState() != null - } - - def 'Handling null state.'() { - expect: 'converting null returns null' - CmHandleStateMapper.toDataStores(null) == null - } - - def 'Internal to External Lock Reason Mapping of #scenario'() { - given: 'a LOCKED composite state with locked reason of #scenario' - def compositeState = new CompositeStateBuilder() - .withCmHandleState(CmHandleState.LOCKED) - .withLockReason(lockReason, '').build() - when: 'the composite state is mapped to a CMHandle composite state' - def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) - then: 'the composite state contains the expected lock Reason and details' - result.getLockReason().getReason() == (expectedExternalLockReason as String) - where: - scenario | lockReason || expectedExternalLockReason - 'MODULE_SYNC_FAILED' | MODULE_SYNC_FAILED || MODULE_SYNC_FAILED - 'null value' | null || LOCKED_MISBEHAVING - } - -} diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/CmHandleStateMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/CmHandleStateMapperSpec.groovy new file mode 100644 index 0000000000..24f45ad8a1 --- /dev/null +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/CmHandleStateMapperSpec.groovy @@ -0,0 +1,84 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-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.util + +import org.mapstruct.factory.Mappers +import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder +import org.onap.cps.ncmp.impl.inventory.DataStoreSyncState +import org.onap.cps.ncmp.impl.inventory.models.CmHandleState +import org.onap.cps.ncmp.rest.model.CmHandleCompositeState +import spock.lang.Specification + +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter + +import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.LOCKED_MISBEHAVING +import static org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory.MODULE_SYNC_FAILED + +class CmHandleStateMapperSpec 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)) + def objectUnderTest = Mappers.getMapper(CmHandleStateMapper) + + def 'Composite State to CmHandleCompositeState'() { + given: 'a composite state model' + def compositeState = new CompositeStateBuilder() + .withCmHandleState(CmHandleState.ADVISED) + .withLastUpdatedTime(formattedDateAndTime.toString()) + .withLockReason(MODULE_SYNC_FAILED, 'locked details') + .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, formattedDateAndTime).build() + compositeState.setDataSyncEnabled(false) + when: 'mapper is called' + def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) + then: 'result is of the correct type' + assert result.class == CmHandleCompositeState.class + and: 'mapped result should have correct values' + assert !result.dataSyncEnabled + assert result.lastUpdateTime == formattedDateAndTime + assert result.lockReason.reason == MODULE_SYNC_FAILED.name() + assert result.lockReason.details == 'locked details' + assert result.cmHandleState == 'ADVISED' + assert result.dataSyncState.operational.getSyncState() != null + } + + def 'Handling null state.'() { + expect: 'converting null returns null' + CmHandleStateMapper.toDataStores(null) == null + } + + def 'Internal to External Lock Reason Mapping of #scenario'() { + given: 'a LOCKED composite state with locked reason of #scenario' + def compositeState = new CompositeStateBuilder() + .withCmHandleState(CmHandleState.LOCKED) + .withLockReason(lockReason, '').build() + when: 'the composite state is mapped to a CMHandle composite state' + def result = objectUnderTest.toCmHandleCompositeStateExternalLockReason(compositeState) + then: 'the composite state contains the expected lock Reason and details' + result.getLockReason().getReason() == (expectedExternalLockReason as String) + where: + scenario | lockReason || expectedExternalLockReason + 'MODULE_SYNC_FAILED' | MODULE_SYNC_FAILED || MODULE_SYNC_FAILED + 'null value' | null || LOCKED_MISBEHAVING + } + +} diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/NcmpRestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/NcmpRestInputMapperSpec.groovy new file mode 100644 index 0000000000..3fd7e40345 --- /dev/null +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/NcmpRestInputMapperSpec.groovy @@ -0,0 +1,134 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022-2024 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.mapstruct.factory.Mappers +import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters +import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle +import org.onap.cps.ncmp.api.inventory.models.TrustLevel +import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters +import org.onap.cps.ncmp.rest.model.ConditionProperties +import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration +import org.onap.cps.ncmp.rest.model.RestInputCmHandle +import org.onap.cps.ncmp.rest.model.RestModuleDefinition +import org.onap.cps.ncmp.rest.model.RestModuleReference +import org.onap.cps.spi.model.ModuleDefinition +import org.onap.cps.spi.model.ModuleReference +import spock.lang.Specification + +class NcmpRestInputMapperSpec extends Specification { + + def objectUnderTest = Mappers.getMapper(NcmpRestInputMapper.class) + + def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() { + given: 'a rest cm handle input' + def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: registrationDmiProperties, + publicCmHandleProperties: registrationPublicProperties, trustLevel: registrationTrustLevel, alternateId: 'my-alternate-id', moduleSetTag: 'my-module-set-tag', dataProducerIdentifier: 'my-data-producer-identifier') + def restDmiPluginRegistration = new RestDmiPluginRegistration( + createdCmHandles: [inputRestCmHandle]) + when: 'to plugin dmi registration is called' + def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) + then: 'the result returns the correct number of cm handles' + result.createdCmHandles.size() == 1 + and: 'the converted cm handle has the same id' + result.createdCmHandles[0].cmHandleId == 'example-id' + and: '(empty) properties are converted correctly' + result.createdCmHandles[0].dmiProperties == mappedDmiProperties + result.createdCmHandles[0].publicProperties == mappedPublicProperties + and: 'other fields are mapped correctly' + result.createdCmHandles[0].alternateId == 'my-alternate-id' + result.createdCmHandles[0].moduleSetTag == 'my-module-set-tag' + result.createdCmHandles[0].registrationTrustLevel == mappedTrustLevel + result.createdCmHandles[0].dataProducerIdentifier == 'my-data-producer-identifier' + where: 'the following parameters are used' + scenario | registrationDmiProperties | registrationPublicProperties | registrationTrustLevel || mappedDmiProperties | mappedPublicProperties | mappedTrustLevel + 'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | 'COMPLETE' || ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] | TrustLevel.COMPLETE + 'no properties' | null | null | null || [:] | [:] | null + } + + def 'Handling empty dmi registration'() { + given: 'a rest cm handle input without any cm handles' + def restDmiPluginRegistration = new RestDmiPluginRegistration() + when: 'to plugin dmi registration is called' + def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) + then: 'unspecified lists remain as empty lists' + assert result.createdCmHandles == [] + assert result.updatedCmHandles == [] + assert result.removedCmHandles == [] + } + + def 'Handling non-empty dmi registration'() { + given: 'a rest cm handle input with cm handles' + def restDmiPluginRegistration = new RestDmiPluginRegistration( + createdCmHandles: [new RestInputCmHandle()], + updatedCmHandles: [new RestInputCmHandle()], + removedCmHandles: ["some-cmHandle"] + ) + when: 'to dmi plugin registration is called' + def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration) + then: 'Lists contain values' + assert result.createdCmHandles[0].class == NcmpServiceCmHandle.class + assert result.updatedCmHandles[0].class == NcmpServiceCmHandle.class + assert result.removedCmHandles == ["some-cmHandle"] + } + + def 'Convert a ModuleReference to a RestModuleReference'() { + given: 'a ModuleReference' + def moduleReference = new ModuleReference() + when: 'toRestModuleReference is called' + def result = objectUnderTest.toRestModuleReference(moduleReference) + then: 'the result is of the correct class RestModuleReference' + result.class == RestModuleReference.class + } + + def 'Convert a ModuleDefinition to a RestModuleDefinition'() { + given: 'a ModuleDefinition' + def moduleDefinition = new ModuleDefinition('moduleName','revision', 'content') + when: 'toRestModuleDefinition is called' + def result = objectUnderTest.toRestModuleDefinition(moduleDefinition) + then: 'the result is of the correct class RestModuleDefinition' + result.class == RestModuleDefinition.class + and: 'all contents are mapped correctly' + result.toString()=='class RestModuleDefinition {\n' + + ' moduleName: moduleName\n' + + ' revision: revision\n' + + ' content: content\n' + + '}' + } + + def 'Convert a CmHandle REST query to CmHandle query service parameters.'() { + given: 'a CmHandle REST query with two conditions' + def conditionParameter1 = new ConditionProperties(conditionName: 'some condition', conditionParameters: [[p1:1]] ) + def conditionParameter2 = new ConditionProperties(conditionName: 'other condition', conditionParameters: [[p2:2]] ) + def cmHandleQuery = new CmHandleQueryParameters() + cmHandleQuery.cmHandleQueryParameters = [conditionParameter1, conditionParameter2] + when: 'it is converted into CmHandle query service parameters' + def result = objectUnderTest.toCmHandleQueryServiceParameters(cmHandleQuery) + then: 'the result is of the correct class' + assert result instanceof CmHandleQueryServiceParameters + and: 'the result has the same conditions' + assert result.cmHandleQueryParameters.size() == 2 + assert result.cmHandleQueryParameters[0].conditionName == 'some condition' + assert result.cmHandleQueryParameters[0].conditionParameters == [[p1:1]] + assert result.cmHandleQueryParameters[1].conditionName == 'other condition' + assert result.cmHandleQueryParameters[1].conditionParameters == [[p2:2]] + } +} -- cgit 1.2.3-korg