From 735cc72cdf706de32e4b55848da1d5242ba1be26 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Tue, 9 Jul 2024 12:41:59 +0100 Subject: Refactor remaining classes package structure -Introduced org.onap.cps.ncmp.config for all config type classes like http, kafka etc. -Introduced org.onap.cps.ncmp.impl.dmi for dmi specif classes like DmiRestClient etc. -Moved most exception classes to org.onap.cps.ncmp.api.exceptions (only two were 'internal' i.e. NOT used in REST so left in org.onap.cps.ncmp.exceptions) -Deleted unused DateNodeHelper class (and related testware) -Moved some classes to org.onap.cps.ncmp.impl.utils -Moved messaging test base classes to org.onap.cps.ncmp.impl.utils.events -All imports were reorganised automatically by IntelliJ -did NOT update any copyright dates (seems incorrect to me anyway) Issue-ID: CPS-2257 Change-Id: Ie28b1777ea278064b46c6a1c3a28f4d0696565e2 Signed-off-by: ToineSiebelink --- .../ncmp/api/impl/DataJobServiceImplSpec.groovy | 86 ----------- .../api/impl/DmiSubJobRequestHandlerSpec.groovy | 41 ----- .../ncmp/api/impl/WriteRequestExaminerSpec.groovy | 63 -------- .../ncmp/api/impl/client/DmiRestClientSpec.groovy | 168 --------------------- .../ncmp/api/impl/config/DmiPropertiesSpec.groovy | 37 ----- .../config/DmiWebClientConfigurationSpec.groovy | 75 --------- .../impl/config/HttpClientConfigurationSpec.groovy | 74 --------- ...etryCmNotificationSubscriptionConfigSpec.groovy | 81 ---------- .../api/impl/config/kafka/KafkaConfigSpec.groovy | 64 -------- .../ncmp/api/impl/utils/DataNodeBaseSpec.groovy | 54 ------- .../ncmp/api/impl/utils/DataNodeHelperSpec.groovy | 85 ----------- .../impl/utils/EventDateTimeFormatterSpec.groovy | 45 ------ .../utils/context/CpsApplicationContextSpec.groovy | 39 ----- .../DmiServiceUrlTemplateBuilderSpec.groovy | 63 -------- .../cps/ncmp/api/kafka/ConsumerBaseSpec.groovy | 43 ------ .../cps/ncmp/api/kafka/MessagingBaseSpec.groovy | 75 --------- .../ncmp/config/CpsApplicationContextSpec.groovy | 39 +++++ .../ncmp/config/HttpClientConfigurationSpec.groovy | 75 +++++++++ .../onap/cps/ncmp/config/KafkaConfigSpec.groovy | 64 ++++++++ ...etryCmNotificationSubscriptionConfigSpec.groovy | 81 ++++++++++ .../cps/ncmp/impl/DmiOperationsBaseSpec.groovy | 76 ---------- .../cache/DmiCacheHandlerSpec.groovy | 2 +- .../cmavc/CmAvcEventConsumerSpec.groovy | 2 +- .../dmi/DmiOutEventConsumerSpec.groovy | 2 +- .../ncmp/NcmpInEventConsumerSpec.groovy | 2 +- .../ncmp/impl/data/DmiDataOperationsSpec.groovy | 10 +- .../data/NcmpDatastoreRequestHandlerSpec.groovy | 2 +- ...AsyncRequestResponseEventIntegrationSpec.groovy | 2 +- .../async/DataOperationEventConsumerSpec.groovy | 2 +- .../async/FilterStrategiesIntegrationSpec.groovy | 4 +- .../data/async/SerializationIntegrationSpec.groovy | 4 +- .../data/utils/DmiDataOperationsHelperSpec.groovy | 4 +- .../impl/datajobs/DataJobServiceImplSpec.groovy | 83 ++++++++++ .../datajobs/DmiSubJobRequestHandlerSpec.groovy | 40 +++++ .../impl/datajobs/WriteRequestExaminerSpec.groovy | 63 ++++++++ .../cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy | 75 +++++++++ .../cps/ncmp/impl/dmi/DmiPropertiesSpec.groovy | 38 +++++ .../cps/ncmp/impl/dmi/DmiRestClientSpec.groovy | 166 ++++++++++++++++++++ .../dmi/DmiServiceUrlTemplateBuilderSpec.groovy | 64 ++++++++ .../impl/dmi/DmiWebClientConfigurationSpec.groovy | 77 ++++++++++ .../CmHandleRegistrationServiceSpec.groovy | 2 +- .../inventory/sync/DmiModelOperationsSpec.groovy | 6 +- .../sync/lcm/LcmEventsPublisherSpec.groovy | 2 +- .../DmiPluginTrustLevelWatchDogSpec.groovy | 4 +- .../impl/utils/EventDateTimeFormatterSpec.groovy | 46 ++++++ .../cps/ncmp/init/AbstractModelLoaderSpec.groovy | 6 +- .../init/CmDataSubscriptionModelLoaderSpec.groovy | 2 +- .../utils/events/CmAvcEventPublisherSpec.groovy | 3 +- .../cps/ncmp/utils/events/ConsumerBaseSpec.groovy | 44 ++++++ .../cps/ncmp/utils/events/MessagingBaseSpec.groovy | 75 +++++++++ .../ncmp/utils/events/TopicValidatorSpec.groovy | 2 +- 51 files changed, 1061 insertions(+), 1201 deletions(-) delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DataJobServiceImplSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DmiSubJobRequestHandlerSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/WriteRequestExaminerSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiPropertiesSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfigurationSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfigSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatterSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/url/builder/DmiServiceUrlTemplateBuilderSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/ConsumerBaseSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/MessagingBaseSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/CpsApplicationContextSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/KafkaConfigSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy delete mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/DmiOperationsBaseSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImplSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandlerSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiPropertiesSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatterSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/ConsumerBaseSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/MessagingBaseSpec.groovy (limited to 'cps-ncmp-service/src/test') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DataJobServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DataJobServiceImplSpec.groovy deleted file mode 100644 index 9cee2bdbad..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DataJobServiceImplSpec.groovy +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 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.api.impl - -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 org.onap.cps.ncmp.impl.datajobs.DataJobServiceImpl -import org.onap.cps.ncmp.impl.datajobs.DmiSubJobRequestHandler -import org.onap.cps.ncmp.impl.datajobs.WriteRequestExaminer -import org.slf4j.LoggerFactory -import org.onap.cps.ncmp.api.datajobs.models.DataJobReadRequest -import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest -import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata -import org.onap.cps.ncmp.api.datajobs.models.ReadOperation -import org.onap.cps.ncmp.api.datajobs.models.WriteOperation -import spock.lang.Specification - -class DataJobServiceImplSpec extends Specification { - - def mockWriteRequestExaminer = Mock(WriteRequestExaminer) - def mockDmiSubJobRequestHandler = Mock(DmiSubJobRequestHandler) - - def objectUnderTest = new DataJobServiceImpl(mockDmiSubJobRequestHandler, mockWriteRequestExaminer) - - def myDataJobMetadata = new DataJobMetadata('', '', '') - - def logger = Spy(ListAppender) - - def setup() { - setupLogger() - } - - def cleanup() { - ((Logger) LoggerFactory.getLogger(DataJobServiceImpl.class)).detachAndStopAllAppenders() - } - - def 'Read data job request.'() { - when: 'read data job request is processed' - def readOperation = new ReadOperation('', '', '', [], [], '', '', 1) - objectUnderTest.readDataJob('my-job-id', myDataJobMetadata, new DataJobReadRequest([readOperation])) - then: 'the data job id is correctly logged' - def loggingEvent = logger.list[0] - assert loggingEvent.level == Level.INFO - assert loggingEvent.formattedMessage.contains('data job id for read operation is: my-job-id') - } - - def 'Write data-job request.'() { - given: 'data job metadata and write request' - def dataJobWriteRequest = new DataJobWriteRequest([new WriteOperation('', '', '', null)]) - and: 'a map of producer key and dmi 3gpp write operation' - def dmiWriteOperationsPerProducerKey = [:] - when: 'write data job request is processed' - objectUnderTest.writeDataJob('my-job-id', myDataJobMetadata, dataJobWriteRequest) - then: 'the examiner service is called and a map is returned' - 1 * mockWriteRequestExaminer.splitDmiWriteOperationsFromRequest('my-job-id', dataJobWriteRequest) >> dmiWriteOperationsPerProducerKey - and: 'the dmi request handler is called with the result from the examiner' - 1 * mockDmiSubJobRequestHandler.sendRequestsToDmi('my-job-id', myDataJobMetadata, dmiWriteOperationsPerProducerKey) - } - - def setupLogger() { - def setupLogger = ((Logger) LoggerFactory.getLogger(DataJobServiceImpl.class)) - setupLogger.setLevel(Level.DEBUG) - setupLogger.addAppender(logger) - logger.start() - } -} \ No newline at end of file diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DmiSubJobRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DmiSubJobRequestHandlerSpec.groovy deleted file mode 100644 index 6dcd022c0a..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/DmiSubJobRequestHandlerSpec.groovy +++ /dev/null @@ -1,41 +0,0 @@ -package org.onap.cps.ncmp.api.impl - -import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.ncmp.api.data.models.OperationType -import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata -import org.onap.cps.ncmp.api.datajobs.models.DmiWriteOperation -import org.onap.cps.ncmp.api.datajobs.models.ProducerKey -import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse -import org.onap.cps.ncmp.api.impl.client.DmiRestClient -import org.onap.cps.ncmp.api.impl.config.DmiProperties -import org.onap.cps.ncmp.impl.datajobs.DmiSubJobRequestHandler -import org.onap.cps.ncmp.impl.models.RequiredDmiService -import org.onap.cps.utils.JsonObjectMapper -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import spock.lang.Specification - -class DmiSubJobRequestHandlerSpec extends Specification { - - def mockDmiRestClient = Mock(DmiRestClient) - def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) - def mockDmiProperties = Mock(DmiProperties) - def static NO_AUTH = null - def objectUnderTest = new DmiSubJobRequestHandler(mockDmiRestClient, mockDmiProperties, jsonObjectMapper) - - def 'Send a sub-job request to the DMI Plugin.'() { - given: 'a data job id, metadata and a map of producer keys and write operations to create a request' - def dataJobId = 'some-job-id' - def dataJobMetadata = new DataJobMetadata('', '', '') - def dmiWriteOperation = new DmiWriteOperation('', '', '', null, '', [:]) - def dmiWriteOperationsPerProducerKey = [new ProducerKey('', ''): [dmiWriteOperation]] - def response = new ResponseEntity<>(new SubJobWriteResponse('my-sub-job-id', '', ''), HttpStatus.OK) - when: 'sending request to DMI invoked' - objectUnderTest.sendRequestsToDmi(dataJobId, dataJobMetadata, dmiWriteOperationsPerProducerKey) - then: 'the dmi rest client is called' - 1 * mockDmiRestClient.synchronousPostOperationWithJsonData(RequiredDmiService.DATA, _, _, OperationType.CREATE, NO_AUTH) >> response - and: 'the result contains the expected sub-job write responses' - def result = response.body - assert result.subJobId() == 'my-sub-job-id' - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/WriteRequestExaminerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/WriteRequestExaminerSpec.groovy deleted file mode 100644 index 84eb78b751..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/WriteRequestExaminerSpec.groovy +++ /dev/null @@ -1,63 +0,0 @@ - -package org.onap.cps.ncmp.impl.datajobs - -import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest -import org.onap.cps.ncmp.api.datajobs.models.WriteOperation -import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher -import org.onap.cps.spi.model.DataNode -import spock.lang.Specification - -class WriteRequestExaminerSpec extends Specification { - - def mockAlternateIdMatcher = Mock(AlternateIdMatcher) - def objectUnderTest = new WriteRequestExaminer(mockAlternateIdMatcher) - - def setup() { - def ch1 = new DataNode(leaves: [id: 'ch1', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p1']) - def ch2 = new DataNode(leaves: [id: 'ch2', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p1']) - def ch3 = new DataNode(leaves: [id: 'ch3', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p2']) - def ch4 = new DataNode(leaves: [id: 'ch4', 'dmi-service-name': 'dmiB', 'data-producer-identifier': 'p1']) - mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn1', '/') >> ch1 - mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn2', '/') >> ch2 - mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn3', '/') >> ch3 - mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn4', '/') >> ch4 - } - - def 'Create a map of dmi write requests per producer key with #scenario.'() { - given: 'a write request with some write operations' - def writeOperations = writeOperationFdns.collect { - new WriteOperation(it, '', '', null) - } - and: 'operations are wrapped in a write request' - def dataJobWriteRequest = new DataJobWriteRequest(writeOperations) - when: 'the DMI write operations are split from the request' - def dmiWriteOperationsPerProducerKey = objectUnderTest.splitDmiWriteOperationsFromRequest('some id', dataJobWriteRequest) - then: 'we get the expected number of keys and values.' - def producerKeysAsStrings = dmiWriteOperationsPerProducerKey.keySet().collect { - it.toString() - } - assert producerKeysAsStrings.size() == expectedKeys.size() - assert expectedKeys.containsAll(producerKeysAsStrings) - where: - scenario | writeOperationFdns || expectedKeys - 'one fdn' | ['fdn1'] || ['dmiA#p1'] - 'a duplicated target' | ['fdn1','fdn1'] || ['dmiA#p1'] - 'two different targets' | ['fdn1','fdn2'] || ['dmiA#p1'] - 'two different targets and different producer keys' | ['fdn1','fdn3'] || ['dmiA#p1', 'dmiA#p2'] - 'two different targets and different DMI services' | ['fdn1','fdn4'] || ['dmiA#p1', 'dmiB#p1'] - 'many targets with different dmi service names and producer keys' | ['fdn1', 'fdn2', 'fdn3', 'fdn4'] || ['dmiA#p1', 'dmiA#p2', 'dmiB#p1'] - } - - def 'Validate the ordering of the created sub jobs.'() { - given: 'a few write operations for the same producer' - def writeOperations = (1..3).collect { - new WriteOperation('fdn1', '', it.toString(), null) - } - and: 'operation is wrapped in a write request' - def dataJobWriteRequest = new DataJobWriteRequest(writeOperations) - when: 'the DMI write operations are split from the request' - def dmiWriteOperations = objectUnderTest.splitDmiWriteOperationsFromRequest('some id', dataJobWriteRequest).values().iterator().next() - then: 'we get the operation ids in the expected order.' - assert dmiWriteOperations.operationId == ['1', '2', '3'] - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy deleted file mode 100644 index a935d70ce6..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy +++ /dev/null @@ -1,168 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation - * Modifications Copyright (C) 2022 Bell Canada - * ================================================================================ - * 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.api.impl.client - -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.ObjectNode -import org.onap.cps.ncmp.api.impl.config.DmiProperties -import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException -import org.onap.cps.ncmp.api.impl.utils.url.builder.UrlTemplateParameters -import org.onap.cps.ncmp.utils.TestUtils -import org.onap.cps.utils.JsonObjectMapper -import org.springframework.http.HttpHeaders -import org.springframework.http.HttpStatus -import org.springframework.http.HttpStatusCode -import org.springframework.http.ResponseEntity -import org.springframework.web.client.HttpServerErrorException -import org.springframework.web.reactive.function.client.WebClient -import org.springframework.web.reactive.function.client.WebClientRequestException -import org.springframework.web.reactive.function.client.WebClientResponseException -import reactor.core.publisher.Mono -import spock.lang.Specification - -import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR -import static org.onap.cps.ncmp.api.data.models.OperationType.READ -import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA -import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL - -class DmiRestClientSpec extends Specification { - - static final NO_AUTH_HEADER = null - static final BASIC_AUTH_HEADER = 'Basic c29tZSB1c2VyOnNvbWUgcGFzc3dvcmQ=' - static final BEARER_AUTH_HEADER = 'Bearer my-bearer-token' - static final urlTemplateParameters = new UrlTemplateParameters('/{pathParam1}/{pathParam2}', ['pathParam1': 'my', 'pathParam2': 'url']) - - def mockDataServicesWebClient = Mock(WebClient) - def mockModelServicesWebClient = Mock(WebClient) - def mockHealthChecksWebClient = Mock(WebClient) - - def mockRequestBody = Mock(WebClient.RequestBodyUriSpec) - def mockResponse = Mock(WebClient.ResponseSpec) - - def mockDmiProperties = Mock(DmiProperties) - - JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) - - DmiRestClient objectUnderTest = new DmiRestClient(mockDmiProperties, jsonObjectMapper, mockDataServicesWebClient, mockModelServicesWebClient, mockHealthChecksWebClient) - - def setup() { - mockRequestBody.uri(_,_) >> mockRequestBody - mockRequestBody.headers(_) >> mockRequestBody - mockRequestBody.body(_) >> mockRequestBody - mockRequestBody.retrieve() >> mockResponse - } - - def 'DMI POST Operation with JSON for DMI Data Service '() { - given: 'the Data web client returns a valid response entity for the expected parameters' - mockDataServicesWebClient.post() >> mockRequestBody - mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Data service', HttpStatus.I_AM_A_TEAPOT)) - when: 'POST operation is invoked fro Data Service' - def response = objectUnderTest.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) - then: 'the output of the method is equal to the output from the test template' - assert response.statusCode == HttpStatus.I_AM_A_TEAPOT - assert response.body == 'from Data service' - } - - def 'DMI POST Operation with JSON for DMI Model Service '() { - given: 'the Model web client returns a valid response entity for the expected parameters' - mockModelServicesWebClient.post() >> mockRequestBody - mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Model service', HttpStatus.I_AM_A_TEAPOT)) - when: 'POST operation is invoked for Model Service' - def response = objectUnderTest.synchronousPostOperationWithJsonData(MODEL, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) - then: 'the output of the method is equal to the output from the test template' - assert response.statusCode == HttpStatus.I_AM_A_TEAPOT - assert response.body == 'from Model service' - } - - def 'Dmi service sends client error response when #scenario'() { - given: 'the web client unable to return response entity but error' - mockDataServicesWebClient.post() >> mockRequestBody - mockResponse.toEntity(Object.class) >> Mono.error(exceptionType) - when: 'POST operation is invoked' - objectUnderTest.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) - then: 'a http client exception is thrown' - def thrown = thrown(DmiClientRequestException) - and: 'the exception has the relevant details from the error response' - assert thrown.ncmpResponseStatus == expectedNcmpResponseStatusCode - assert thrown.httpStatusCode == httpStatusCode - where: 'the following errors occur' - scenario | httpStatusCode | exceptionType || expectedNcmpResponseStatusCode - 'dmi service unavailable' | 503 | new WebClientRequestException(new RuntimeException('some-error'), null, null, new HttpHeaders()) || DMI_SERVICE_NOT_RESPONDING - 'dmi request timeout' | 408 | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null) || DMI_SERVICE_NOT_RESPONDING - 'dmi server error' | 500 | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null) || UNABLE_TO_READ_RESOURCE_DATA - 'dmi service unavailable' | 503 | new HttpServerErrorException(HttpStatusCode.valueOf(503)) || DMI_SERVICE_NOT_RESPONDING - 'unknown error' | 500 | new Throwable('message') || UNKNOWN_ERROR - } - - def 'Dmi trust level is determined by spring boot health status'() { - given: 'a health check response' - def dmiPluginHealthCheckResponseJsonData = TestUtils.getResourceFileContent('dmiPluginHealthCheckResponse.json') - def jsonNode = jsonObjectMapper.convertJsonString(dmiPluginHealthCheckResponseJsonData, JsonNode.class) - ((ObjectNode) jsonNode).put('status', 'my status') - mockHealthChecksWebClient.get() >> mockRequestBody - mockResponse.onStatus(_,_)>> mockResponse - mockResponse.bodyToMono(JsonNode.class) >> Mono.just(jsonNode) - when: 'get trust level of the dmi plugin' - def urlTemplateParameters = new UrlTemplateParameters('some url', [:]) - def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block() - then: 'the status value from the json is returned' - assert result == 'my status' - } - - def 'Failing to get dmi plugin health status #scenario'() { - given: 'web client instance with #scenario' - mockHealthChecksWebClient.get() >> mockRequestBody - mockResponse.onStatus(_, _) >> mockResponse - mockResponse.bodyToMono(_) >> Mono.error(exceptionType) - when: 'attempt to get health status of the dmi plugin' - def urlTemplateParameters = new UrlTemplateParameters('some url', [:]) - def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block() - then: 'result will be empty' - assert result == '' - where: 'the following responses are used' - scenario | exceptionType - 'dmi request timeout' | new WebClientResponseException('some-message', 408, 'some-text', null, null, null) - 'dmi service unavailable' | new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE) - } - - def 'DMI auth header #scenario'() { - when: 'Specific dmi properties are provided' - mockDmiProperties.dmiBasicAuthEnabled >> authEnabled - mockDmiProperties.authUsername >> 'some user' - mockDmiProperties.authPassword >> 'some password' - then: 'http headers to conditionally have Authorization header' - def httpHeaders = new HttpHeaders() - objectUnderTest.configureHttpHeaders(httpHeaders, ncmpAuthHeader) - def outputAuthHeader = (httpHeaders.Authorization == null ? null : httpHeaders.Authorization[0]) - assert outputAuthHeader == expectedAuthHeader - where: 'the following configurations are used' - scenario | authEnabled | ncmpAuthHeader || expectedAuthHeader - 'DMI basic auth enabled, no NCMP bearer token' | true | NO_AUTH_HEADER || BASIC_AUTH_HEADER - 'DMI basic auth enabled, with NCMP bearer token' | true | BEARER_AUTH_HEADER || BASIC_AUTH_HEADER - 'DMI basic auth disabled, no NCMP bearer token' | false | NO_AUTH_HEADER || NO_AUTH_HEADER - 'DMI basic auth disabled, with NCMP bearer token' | false | BEARER_AUTH_HEADER || BEARER_AUTH_HEADER - 'DMI basic auth disabled, with NCMP basic auth' | false | BASIC_AUTH_HEADER || NO_AUTH_HEADER - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiPropertiesSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiPropertiesSpec.groovy deleted file mode 100644 index c763c522c9..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiPropertiesSpec.groovy +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 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.api.impl.config - -import spock.lang.Specification - -class DmiPropertiesSpec extends Specification { - - def objectUnderTest = new DmiProperties() - - def 'Geting dmi base path.'() { - given: 'base path of #dmiBasePath' - objectUnderTest.dmiBasePath = dmiBasePath - expect: 'Preceding and trailing slash wil be removed' - assert objectUnderTest.getDmiBasePath() == 'test' - where: 'the following dmi base paths are used' - dmiBasePath << [ 'test' , '/test', 'test/', '/test/' ] - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfigurationSpec.groovy deleted file mode 100644 index fa995aa7c3..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfigurationSpec.groovy +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 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.api.impl.config - -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.context.TestPropertySource -import org.springframework.web.reactive.function.client.WebClient -import spock.lang.Specification - -@SpringBootTest -@ContextConfiguration(classes = [HttpClientConfiguration]) -@TestPropertySource(properties = ['ncmp.dmi.httpclient.data-services.connectionTimeoutInSeconds=1', 'ncmp.dmi.httpclient.model-services.maximumInMemorySizeInMegabytes=1']) -@EnableConfigurationProperties -class DmiWebClientConfigurationSpec extends Specification { - - def webClientBuilder = Mock(WebClient.Builder) { - defaultHeaders(_) >> it - clientConnector(_) >> it - codecs(_) >> it - build() >> Mock(WebClient) - } - - def httpClientConfiguration = Spy(HttpClientConfiguration.class) - - def objectUnderTest = new DmiWebClientConfiguration(httpClientConfiguration) - - def 'Web Client Configuration construction.'() { - expect: 'the system can create an instance' - new DmiWebClientConfiguration(httpClientConfiguration) != null - } - - def 'Creating a web client instance data service.'() { - given: 'Web client configuration is invoked' - def dataServicesWebClient = objectUnderTest.dataServicesWebClient(webClientBuilder) - expect: 'the system can create an instance for data service' - assert dataServicesWebClient != null - assert dataServicesWebClient instanceof WebClient - } - - def 'Creating a web client instance model service.'() { - given: 'Web client configuration invoked' - def modelServicesWebClient = objectUnderTest.modelServicesWebClient(webClientBuilder) - expect: 'the system can create an instance for model service' - assert modelServicesWebClient != null - assert modelServicesWebClient instanceof WebClient - } - - def 'Creating a web client instance health service.'() { - given: 'Web client configuration invoked' - def healthChecksWebClient = objectUnderTest.healthChecksWebClient(webClientBuilder) - expect: 'the system can create an instance for health service' - assert healthChecksWebClient != null - assert healthChecksWebClient instanceof WebClient - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy deleted file mode 100644 index 228f412779..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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.api.impl.config - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.context.TestPropertySource -import spock.lang.Specification - -@SpringBootTest -@ContextConfiguration(classes = [HttpClientConfiguration]) -@EnableConfigurationProperties(HttpClientConfiguration.class) -@TestPropertySource(properties = ["ncmp.dmi.httpclient.data-services.readTimeoutInSeconds=789", "ncmp.dmi.httpclient.model-services.maximumConnectionsTotal=111"]) -class HttpClientConfigurationSpec extends Specification { - - @Autowired - private HttpClientConfiguration httpClientConfiguration - - def 'Test http client configuration properties of data with custom and default values'() { - expect: 'properties are populated correctly for data' - with(httpClientConfiguration.dataServices) { - assert connectionTimeoutInSeconds == 123 - assert readTimeoutInSeconds == 789 - assert writeTimeoutInSeconds == 30 - assert maximumConnectionsTotal == 100 - assert pendingAcquireMaxCount == 22 - assert maximumInMemorySizeInMegabytes == 7 - } - } - - def 'Test http client configuration properties of model with custom and default values'() { - expect: 'properties are populated correctly for model' - with(httpClientConfiguration.modelServices) { - assert connectionTimeoutInSeconds == 456 - assert readTimeoutInSeconds == 30 - assert writeTimeoutInSeconds == 30 - assert maximumConnectionsTotal == 111 - assert pendingAcquireMaxCount == 44 - assert maximumInMemorySizeInMegabytes == 8 - } - } - - def 'Test http client configuration properties of health with default values'() { - expect: 'properties are populated correctly for health' - with(httpClientConfiguration.healthCheckServices) { - assert connectionTimeoutInSeconds == 30 - assert readTimeoutInSeconds == 30 - assert writeTimeoutInSeconds == 30 - assert maximumConnectionsTotal == 10 - assert pendingAcquireMaxCount == 5 - assert maximumInMemorySizeInMegabytes == 1 - } - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy deleted file mode 100644 index 07395cf5bc..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 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.api.impl.config - -import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter -import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler -import org.spockframework.spring.SpringBean -import org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryCustomizer -import spock.lang.Shared -import spock.lang.Specification - -class OpenTelemetryConfigSpec extends Specification{ - - @Shared - @SpringBean - OpenTelemetryConfig openTelemetryConfig = new OpenTelemetryConfig() - - def setupSpec() { - openTelemetryConfig.tracingExporterEndpointUrl="http://tracingExporterEndpointUrl" - openTelemetryConfig.jaegerRemoteSamplerUrl="http://jaegerremotesamplerurl" - openTelemetryConfig.serviceId ="cps-application" - } - - def 'OpenTelemetryConfig Construction.'() { - expect: 'the system can create an instance' - new OpenTelemetryConfig() != null - } - - def 'OTLP Exporter creation with Grpc protocol'(){ - when: 'an OTLP exporter is created' - def result = openTelemetryConfig.createOtlpExporterGrpc() - then: 'an OTLP Exporter is created' - assert result instanceof OtlpGrpcSpanExporter - } - - def 'OTLP Exporter creation with HTTP protocol'(){ - when: 'an OTLP exporter is created' - def result = openTelemetryConfig.createOtlpExporterHttp() - then: 'an OTLP Exporter is created' - assert result instanceof OtlpHttpSpanExporter - and: - assert result.builder.endpoint=="http://tracingExporterEndpointUrl" - } - - def 'Jaeger Remote Sampler Creation'(){ - when: 'an OTLP exporter is created' - def result = openTelemetryConfig.createJaegerRemoteSampler() - then: 'an OTLP Exporter is created' - assert result instanceof JaegerRemoteSampler - and: - assert result.delegate.type=="remoteSampling" - and: - assert result.delegate.url.toString().startsWith("http://jaegerremotesamplerurl") - } - - def 'Skipping Acutator endpoints'(){ - when: 'an OTLP exporter is created' - def result = openTelemetryConfig.skipActuatorEndpointsFromObservation() - then: 'an OTLP Exporter is created' - assert result instanceof ObservationRegistryCustomizer - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfigSpec.groovy deleted file mode 100644 index 4d3fd6616b..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/kafka/KafkaConfigSpec.groovy +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2023-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.api.impl.config.kafka - -import io.cloudevents.CloudEvent -import io.cloudevents.kafka.CloudEventDeserializer -import io.cloudevents.kafka.CloudEventSerializer -import org.spockframework.spring.EnableSharedInjection -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.kafka.KafkaProperties -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.support.serializer.JsonDeserializer -import org.springframework.kafka.support.serializer.JsonSerializer -import org.springframework.test.context.TestPropertySource -import spock.lang.Shared -import spock.lang.Specification - -@SpringBootTest(classes = [KafkaProperties, KafkaConfig]) -@EnableSharedInjection -@EnableConfigurationProperties -@TestPropertySource(properties = ["cps.tracing.enabled=true"]) -class KafkaConfigSpec extends Specification { - - @Shared - @Autowired - KafkaTemplate legacyEventKafkaTemplate - - @Shared - @Autowired - KafkaTemplate cloudEventKafkaTemplate - - def 'Verify kafka template serializer and deserializer configuration for #eventType.'() { - expect: 'kafka template is instantiated' - assert kafkaTemplateInstance.properties['beanName'] == beanName - and: 'verify event key and value serializer' - assert kafkaTemplateInstance.properties['producerFactory'].configs['value.serializer'].asType(String.class).contains(valueSerializer.getCanonicalName()) - and: 'verify event key and value deserializer' - assert kafkaTemplateInstance.properties['consumerFactory'].configs['spring.deserializer.value.delegate.class'].asType(String.class).contains(delegateDeserializer.getCanonicalName()) - where: 'the following event type is used' - eventType | kafkaTemplateInstance || beanName | valueSerializer | delegateDeserializer - 'legacy event' | legacyEventKafkaTemplate || 'legacyEventKafkaTemplate' | JsonSerializer | JsonDeserializer - 'cloud event' | cloudEventKafkaTemplate || 'cloudEventKafkaTemplate' | CloudEventSerializer | CloudEventDeserializer - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy deleted file mode 100644 index 2e04694301..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeBaseSpec.groovy +++ /dev/null @@ -1,54 +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.api.impl.utils - -import org.onap.cps.spi.model.DataNodeBuilder -import spock.lang.Specification - -import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME - -class DataNodeBaseSpec extends Specification { - - def leaves1 = [status:'PENDING', cmHandleId:'CMHandle3', details:'Subscription forwarded to dmi plugin'] as Map - def dataNode1 = createDataNodeWithLeaves(leaves1) - - def leaves2 = [status:'ACCEPTED', cmHandleId:'CMHandle2', details:''] as Map - def dataNode2 = createDataNodeWithLeaves(leaves2) - - def leaves3 = [status:'REJECTED', cmHandleId:'CMHandle1', details:'Cm handle does not exist'] as Map - def dataNode3 = createDataNodeWithLeaves(leaves3) - - def leaves4 = [datastore:'passthrough-running'] as Map - def dataNode4 = createDataNodeWithLeavesAndChildDataNodes(leaves4, [dataNode1, dataNode2, dataNode3]) - - static def createDataNodeWithLeaves(leaves) { - return new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME) - .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') - .withLeaves(leaves).build() - } - - static def createDataNodeWithLeavesAndChildDataNodes(leaves, dataNodes) { - return new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME) - .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') - .withLeaves(leaves).withChildDataNodes(dataNodes) - .build() - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy deleted file mode 100644 index 9481613d41..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/DataNodeHelperSpec.groovy +++ /dev/null @@ -1,85 +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.api.impl.utils - -import org.onap.cps.spi.model.DataNodeBuilder - -import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DATASPACE_NAME - -class DataNodeHelperSpec extends DataNodeBaseSpec { - - def 'Get data node leaves as expected from a nested data node.'() { - given: 'a nested data node' - def dataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME) - .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') - .withLeaves([clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001']) - .withChildDataNodes([dataNode4]).build() - when: 'the nested data node is flatten and retrieves the leaves ' - def result = DataNodeHelper.getDataNodeLeaves([dataNode]) - then: 'the result list size is 5' - result.size() == 5 - and: 'all the leaves result list are equal to given leaves of data nodes' - result[0] == [clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001'] - result[1] == [datastore:'passthrough-running'] - result[2] == [status:'PENDING', cmHandleId:'CMHandle3', details:'Subscription forwarded to dmi plugin'] - result[3] == [status:'ACCEPTED', cmHandleId:'CMHandle2', details:''] - result[4] == [status:'REJECTED', cmHandleId:'CMHandle1', details:'Cm handle does not exist'] - } - - def 'Get cm handle id to status as expected from a nested data node.'() { - given: 'a nested data node' - def dataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME) - .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') - .withLeaves([clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001']) - .withChildDataNodes([dataNode4]).build() - and: 'the nested data node is flatten and retrieves the leaves ' - def leaves = DataNodeHelper.getDataNodeLeaves([dataNode]) - when:'cm handle id to status is retrieved' - def result = DataNodeHelper.cmHandleIdToStatusAndDetailsAsMap(leaves) - then: 'the result list size is 3' - result.size() == 3 - and: 'the result contains expected values' - result == [ - CMHandle3: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map, - CMHandle2: [details:'',status:'ACCEPTED'] as Map, - CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map - ] as Map - - } - - def 'Get cm handle id to status map as expected from a nested data node.'() { - given: 'a nested data node' - def dataNode = new DataNodeBuilder().withDataspace(NCMP_DATASPACE_NAME) - .withAnchor('AVC-Subscriptions').withXpath('/subscription-registry/subscription') - .withLeaves([clientID:'SCO-9989752', isTagged:false, subscriptionName:'cm-subscription-001']) - .withChildDataNodes([dataNode4]).build() - when:'cm handle id to status is being extracted' - def result = DataNodeHelper.cmHandleIdToStatusAndDetailsAsMapFromDataNode([dataNode]); - then: 'the result list size is 3' - result.size() == 3 - and: 'the result contains expected values' - result == [ - CMHandle3: [details:'Subscription forwarded to dmi plugin',status:'PENDING'] as Map, - CMHandle2: [details:'',status:'ACCEPTED'] as Map, - CMHandle1: [details:'Cm handle does not exist',status:'REJECTED'] as Map - ] as Map - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatterSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatterSpec.groovy deleted file mode 100644 index c72eb9e4c9..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/EventDateTimeFormatterSpec.groovy +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 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.api.impl.utils - -import spock.lang.Specification -import java.time.Year - -class EventDateTimeFormatterSpec extends Specification { - - def 'Get ISO formatted date and time.' () { - expect: 'iso formatted date and time starts with current year' - assert EventDateTimeFormatter.getCurrentIsoFormattedDateTime().startsWith(String.valueOf(Year.now())) - } - - def 'Convert date time from string to OffsetDateTime type.'() { - when: 'date time as a string is converted to OffsetDateTime type' - def result = EventDateTimeFormatter.toIsoOffsetDateTime('2024-05-28T18:28:02.869+0100') - then: 'the result convert back back to a string is the same as the original timestamp (except the format of timezone offset)' - assert result.toString() == '2024-05-28T18:28:02.869+01:00' - } - - def 'Convert blank string.' () { - expect: 'converting a blank string result in null' - assert EventDateTimeFormatter.toIsoOffsetDateTime(' ') == null - } - -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy deleted file mode 100644 index ee117160c1..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/context/CpsApplicationContextSpec.groovy +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ============LICENSE_START======================================================== - * Copyright (c) 2023-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.api.impl.utils.context - -import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.utils.JsonObjectMapper -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification; - -@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) -@ContextConfiguration(classes = [CpsApplicationContext.class]) -class CpsApplicationContextSpec extends Specification { - - def 'Verify if cps application context contains a requested bean.'() { - when: 'cps bean is requested from application context' - def jsonObjectMapper = CpsApplicationContext.getCpsBean(JsonObjectMapper.class) - then: 'requested bean of JsonObjectMapper is not null' - assert jsonObjectMapper != null - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/url/builder/DmiServiceUrlTemplateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/url/builder/DmiServiceUrlTemplateBuilderSpec.groovy deleted file mode 100644 index 6d56f432d3..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/url/builder/DmiServiceUrlTemplateBuilderSpec.groovy +++ /dev/null @@ -1,63 +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.api.impl.utils.url.builder - -import spock.lang.Specification - -class DmiServiceUrlTemplateBuilderSpec extends Specification { - - def objectUnderTest = new DmiServiceUrlTemplateBuilder() - - def 'Build URL template parameters with (variable) path segments and query parameters.'() { - given: 'the URL details are given to the builder' - objectUnderTest.fixedPathSegment('segment') - objectUnderTest.variablePathSegment('myVariableSegment','someValue') - objectUnderTest.fixedPathSegment('segment?with:special&characters') - objectUnderTest.queryParameter('param1', 'abc') - objectUnderTest.queryParameter('param2', 'value?with#special:characters') - when: 'the URL template parameters are created' - def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') - then: 'the URL template contains variable names instead of value and un-encoded fixed segment' - assert result.urlTemplate == 'myDmiServer/myBasePath/v1/segment/{myVariableSegment}/segment?with:special&characters?param1={param1}¶m2={param2}' - and: 'URL variables contains name and un-encoded value pairs' - assert result.urlVariables == ['myVariableSegment': 'someValue', 'param1': 'abc', 'param2': 'value?with#special:characters'] - } - - def 'Build URL template parameters with special characters in query parameters.'() { - given: 'the query parameter is given to the builder' - objectUnderTest.queryParameter('my¶m', 'special&characters=are?not\\encoded') - when: 'the URL template parameters are created' - def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') - then: 'Special characters are not encoded' - assert result.urlVariables == ['my¶m': 'special&characters=are?not\\encoded'] - } - - def 'Build URL template parameters with empty query parameters.'() { - when: 'the query parameter is given to the builder' - objectUnderTest.queryParameter('param', value) - and: 'the URL template parameters are create' - def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') - then: 'no parameter gets added' - assert result.urlVariables.isEmpty() - where: 'the following parameter values are used' - value << [ null, '', ' ' ] - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/ConsumerBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/ConsumerBaseSpec.groovy deleted file mode 100644 index 28f8b02880..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/ConsumerBaseSpec.groovy +++ /dev/null @@ -1,43 +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.api.kafka - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.kafka.config.KafkaListenerEndpointRegistry -import org.springframework.kafka.test.utils.ContainerTestUtils - -@SpringBootTest(classes = KafkaListenerEndpointRegistry.class) -class ConsumerBaseSpec extends MessagingBaseSpec { - - @Autowired - private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry - - def setup() { - activateListeners() - } - - def activateListeners() { - kafkaListenerEndpointRegistry.getListenerContainers().forEach( - messageListenerContainer -> { ContainerTestUtils.waitForAssignment(messageListenerContainer, 1) } - ) - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/MessagingBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/MessagingBaseSpec.groovy deleted file mode 100644 index 0356c3fcdc..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/kafka/MessagingBaseSpec.groovy +++ /dev/null @@ -1,75 +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.api.kafka - -import io.cloudevents.CloudEvent -import io.cloudevents.kafka.CloudEventSerializer -import org.apache.kafka.common.serialization.StringDeserializer -import org.apache.kafka.common.serialization.StringSerializer -import org.springframework.kafka.core.DefaultKafkaProducerFactory -import org.springframework.kafka.core.KafkaTemplate -import org.springframework.kafka.support.serializer.JsonSerializer -import org.springframework.test.context.DynamicPropertyRegistry -import org.springframework.test.context.DynamicPropertySource -import org.testcontainers.containers.KafkaContainer -import org.testcontainers.utility.DockerImageName -import spock.lang.Specification - -class MessagingBaseSpec extends Specification { - - def setupSpec() { - kafkaTestContainer.start() - } - - def cleanupSpec() { - kafkaTestContainer.stop() - } - - static kafkaTestContainer = new KafkaContainer(DockerImageName.parse('registry.nordix.org/onaptest/confluentinc/cp-kafka:6.2.1').asCompatibleSubstituteFor('confluentinc/cp-kafka')) - - def legacyEventKafkaTemplate = new KafkaTemplate<>(new DefaultKafkaProducerFactory(eventProducerConfigProperties(JsonSerializer))) - - def cloudEventKafkaTemplate = new KafkaTemplate<>(new DefaultKafkaProducerFactory(eventProducerConfigProperties(CloudEventSerializer))) - - @DynamicPropertySource - static void registerKafkaProperties(DynamicPropertyRegistry dynamicPropertyRegistry) { - dynamicPropertyRegistry.add('spring.kafka.bootstrap-servers', kafkaTestContainer::getBootstrapServers) - } - - def eventProducerConfigProperties(valueSerializer) { - return [('bootstrap.servers'): kafkaTestContainer.getBootstrapServers().split(',')[0], - ('retries') : 0, - ('batch-size') : 16384, - ('linger.ms') : 1, - ('buffer.memory') : 33554432, - ('key.serializer') : StringSerializer, - ('value.serializer') : valueSerializer] - } - - def eventConsumerConfigProperties(consumerGroupId, valueSerializer) { - return [('bootstrap.servers') : kafkaTestContainer.getBootstrapServers().split(',')[0], - ('key.deserializer') : StringDeserializer, - ('value.deserializer'): valueSerializer, - ('auto.offset.reset') : 'earliest', - ('group.id') : consumerGroupId - ] - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/CpsApplicationContextSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/CpsApplicationContextSpec.groovy new file mode 100644 index 0000000000..215ea6c219 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/CpsApplicationContextSpec.groovy @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================== + * Copyright (c) 2023-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.config + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.utils.JsonObjectMapper +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification; + +@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) +@ContextConfiguration(classes = [CpsApplicationContext.class]) +class CpsApplicationContextSpec extends Specification { + + def 'Verify if cps application context contains a requested bean.'() { + when: 'cps bean is requested from application context' + def jsonObjectMapper = CpsApplicationContext.getCpsBean(JsonObjectMapper.class) + then: 'requested bean of JsonObjectMapper is not null' + assert jsonObjectMapper != null + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy new file mode 100644 index 0000000000..91aeb88a54 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2023-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.config + + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import spock.lang.Specification + +@SpringBootTest +@ContextConfiguration(classes = [HttpClientConfiguration]) +@EnableConfigurationProperties(HttpClientConfiguration.class) +@TestPropertySource(properties = ["ncmp.dmi.httpclient.data-services.readTimeoutInSeconds=789", "ncmp.dmi.httpclient.model-services.maximumConnectionsTotal=111"]) +class HttpClientConfigurationSpec extends Specification { + + @Autowired + private HttpClientConfiguration httpClientConfiguration + + def 'Test http client configuration properties of data with custom and default values'() { + expect: 'properties are populated correctly for data' + with(httpClientConfiguration.dataServices) { + assert connectionTimeoutInSeconds == 123 + assert readTimeoutInSeconds == 789 + assert writeTimeoutInSeconds == 30 + assert maximumConnectionsTotal == 100 + assert pendingAcquireMaxCount == 22 + assert maximumInMemorySizeInMegabytes == 7 + } + } + + def 'Test http client configuration properties of model with custom and default values'() { + expect: 'properties are populated correctly for model' + with(httpClientConfiguration.modelServices) { + assert connectionTimeoutInSeconds == 456 + assert readTimeoutInSeconds == 30 + assert writeTimeoutInSeconds == 30 + assert maximumConnectionsTotal == 111 + assert pendingAcquireMaxCount == 44 + assert maximumInMemorySizeInMegabytes == 8 + } + } + + def 'Test http client configuration properties of health with default values'() { + expect: 'properties are populated correctly for health' + with(httpClientConfiguration.healthCheckServices) { + assert connectionTimeoutInSeconds == 30 + assert readTimeoutInSeconds == 30 + assert writeTimeoutInSeconds == 30 + assert maximumConnectionsTotal == 10 + assert pendingAcquireMaxCount == 5 + assert maximumInMemorySizeInMegabytes == 1 + } + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/KafkaConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/KafkaConfigSpec.groovy new file mode 100644 index 0000000000..9e1649ef93 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/KafkaConfigSpec.groovy @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023-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.config + +import io.cloudevents.CloudEvent +import io.cloudevents.kafka.CloudEventDeserializer +import io.cloudevents.kafka.CloudEventSerializer +import org.spockframework.spring.EnableSharedInjection +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.kafka.KafkaProperties +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.support.serializer.JsonDeserializer +import org.springframework.kafka.support.serializer.JsonSerializer +import org.springframework.test.context.TestPropertySource +import spock.lang.Shared +import spock.lang.Specification + +@SpringBootTest(classes = [KafkaProperties, KafkaConfig]) +@EnableSharedInjection +@EnableConfigurationProperties +@TestPropertySource(properties = ["cps.tracing.enabled=true"]) +class KafkaConfigSpec extends Specification { + + @Shared + @Autowired + KafkaTemplate legacyEventKafkaTemplate + + @Shared + @Autowired + KafkaTemplate cloudEventKafkaTemplate + + def 'Verify kafka template serializer and deserializer configuration for #eventType.'() { + expect: 'kafka template is instantiated' + assert kafkaTemplateInstance.properties['beanName'] == beanName + and: 'verify event key and value serializer' + assert kafkaTemplateInstance.properties['producerFactory'].configs['value.serializer'].asType(String.class).contains(valueSerializer.getCanonicalName()) + and: 'verify event key and value deserializer' + assert kafkaTemplateInstance.properties['consumerFactory'].configs['spring.deserializer.value.delegate.class'].asType(String.class).contains(delegateDeserializer.getCanonicalName()) + where: 'the following event type is used' + eventType | kafkaTemplateInstance || beanName | valueSerializer | delegateDeserializer + 'legacy event' | legacyEventKafkaTemplate || 'legacyEventKafkaTemplate' | JsonSerializer | JsonDeserializer + 'cloud event' | cloudEventKafkaTemplate || 'cloudEventKafkaTemplate' | CloudEventSerializer | CloudEventDeserializer + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy new file mode 100644 index 0000000000..0f6906942f --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/OpenTelemetryCmNotificationSubscriptionConfigSpec.groovy @@ -0,0 +1,81 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 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.config + +import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter +import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler +import org.spockframework.spring.SpringBean +import org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryCustomizer +import spock.lang.Shared +import spock.lang.Specification + +class OpenTelemetryConfigSpec extends Specification{ + + @Shared + @SpringBean + OpenTelemetryConfig openTelemetryConfig = new OpenTelemetryConfig() + + def setupSpec() { + openTelemetryConfig.tracingExporterEndpointUrl="http://tracingExporterEndpointUrl" + openTelemetryConfig.jaegerRemoteSamplerUrl="http://jaegerremotesamplerurl" + openTelemetryConfig.serviceId ="cps-application" + } + + def 'OpenTelemetryConfig Construction.'() { + expect: 'the system can create an instance' + new OpenTelemetryConfig() != null + } + + def 'OTLP Exporter creation with Grpc protocol'(){ + when: 'an OTLP exporter is created' + def result = openTelemetryConfig.createOtlpExporterGrpc() + then: 'an OTLP Exporter is created' + assert result instanceof OtlpGrpcSpanExporter + } + + def 'OTLP Exporter creation with HTTP protocol'(){ + when: 'an OTLP exporter is created' + def result = openTelemetryConfig.createOtlpExporterHttp() + then: 'an OTLP Exporter is created' + assert result instanceof OtlpHttpSpanExporter + and: + assert result.builder.endpoint=="http://tracingExporterEndpointUrl" + } + + def 'Jaeger Remote Sampler Creation'(){ + when: 'an OTLP exporter is created' + def result = openTelemetryConfig.createJaegerRemoteSampler() + then: 'an OTLP Exporter is created' + assert result instanceof JaegerRemoteSampler + and: + assert result.delegate.type=="remoteSampling" + and: + assert result.delegate.url.toString().startsWith("http://jaegerremotesamplerurl") + } + + def 'Skipping Acutator endpoints'(){ + when: 'an OTLP exporter is created' + def result = openTelemetryConfig.skipActuatorEndpointsFromObservation() + then: 'an OTLP Exporter is created' + assert result instanceof ObservationRegistryCustomizer + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/DmiOperationsBaseSpec.groovy deleted file mode 100644 index 050932f654..0000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/DmiOperationsBaseSpec.groovy +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * 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.impl - -import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.ncmp.api.impl.client.DmiRestClient -import org.onap.cps.ncmp.api.inventory.models.CompositeState -import org.onap.cps.ncmp.impl.inventory.InventoryPersistence -import org.onap.cps.ncmp.impl.inventory.models.CmHandleState -import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle -import org.spockframework.spring.SpringBean -import spock.lang.Shared -import spock.lang.Specification - -abstract class DmiOperationsBaseSpec extends Specification { - - @Shared - def yangModelCmHandleProperty = new YangModelCmHandle.Property('prop1', 'val1') - - @SpringBean - DmiRestClient mockDmiRestClient = Mock() - - @SpringBean - InventoryPersistence mockInventoryPersistence = Mock() - - @SpringBean - ObjectMapper spyObjectMapper = Spy() - - def yangModelCmHandle = new YangModelCmHandle() - def static dmiServiceName = 'myServiceName' - def static cmHandleId = 'some-cm-handle' - def static resourceIdentifier = 'parent/child' - - def mockYangModelCmHandleRetrieval(dmiProperties) { - populateYangModelCmHandle(dmiProperties, '') - mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle - } - - def mockYangModelCmHandleRetrieval(dmiProperties, moduleSetTag) { - populateYangModelCmHandle(dmiProperties, moduleSetTag) - mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle - } - - def mockYangModelCmHandleCollectionRetrieval(dmiProperties) { - populateYangModelCmHandle(dmiProperties, '') - mockInventoryPersistence.getYangModelCmHandles(_) >> [yangModelCmHandle] - } - - def populateYangModelCmHandle(dmiProperties, moduleSetTag) { - yangModelCmHandle.dmiDataServiceName = dmiServiceName - yangModelCmHandle.dmiServiceName = dmiServiceName - yangModelCmHandle.dmiProperties = dmiProperties - yangModelCmHandle.id = cmHandleId - yangModelCmHandle.compositeState = new CompositeState() - yangModelCmHandle.compositeState.cmHandleState = CmHandleState.READY - yangModelCmHandle.moduleSetTag = moduleSetTag - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy index b335843bb3..2d50e770dd 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cache/DmiCacheHandlerSpec.groovy @@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import io.cloudevents.core.builder.CloudEventBuilder import org.apache.kafka.clients.consumer.ConsumerRecord -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.CmSubscriptionStatus import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails import org.onap.cps.ncmp.impl.cmnotificationsubscription.utils.CmSubscriptionPersistenceService @@ -32,6 +31,7 @@ import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.Nc import org.onap.cps.ncmp.impl.inventory.InventoryPersistence import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumerSpec.groovy index 98cc383e7f..a8b5250edf 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/cmavc/CmAvcEventConsumerSpec.groovy @@ -28,9 +28,9 @@ import io.cloudevents.kafka.impl.KafkaHeaders import org.apache.kafka.clients.consumer.ConsumerRecord import org.apache.kafka.clients.consumer.KafkaConsumer import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.events.avc1_0_0.AvcEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy index 06003fdcb4..6e28d14810 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiOutEventConsumerSpec.groovy @@ -28,13 +28,13 @@ import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import io.cloudevents.core.builder.CloudEventBuilder import org.apache.kafka.clients.consumer.ConsumerRecord -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventMapper import org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp.NcmpOutEventProducer import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.Data import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.dmi_to_ncmp.DmiOutEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy index 637e9ebfec..2881737e82 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpInEventConsumerSpec.groovy @@ -28,9 +28,9 @@ import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import io.cloudevents.core.builder.CloudEventBuilder import org.apache.kafka.clients.consumer.ConsumerRecord -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.client_to_ncmp.NcmpInEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy index 3a199ff417..c2bbfc2edc 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy @@ -25,12 +25,12 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.data.models.CmResourceAddress import org.onap.cps.ncmp.api.data.models.DataOperationRequest -import org.onap.cps.ncmp.api.impl.config.DmiProperties -import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException -import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext -import org.onap.cps.ncmp.api.impl.utils.url.builder.UrlTemplateParameters +import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException +import org.onap.cps.ncmp.config.CpsApplicationContext import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent -import org.onap.cps.ncmp.impl.DmiOperationsBaseSpec +import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec +import org.onap.cps.ncmp.impl.dmi.DmiProperties +import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters import org.onap.cps.ncmp.impl.inventory.models.CmHandleState import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandlerSpec.groovy index 39701d8e70..d5db24cc33 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpDatastoreRequestHandlerSpec.groovy @@ -26,7 +26,7 @@ import org.onap.cps.ncmp.api.data.exceptions.OperationNotSupportedException import org.onap.cps.ncmp.api.data.models.CmResourceAddress import org.onap.cps.ncmp.api.data.models.DataOperationDefinition import org.onap.cps.ncmp.api.data.models.DataOperationRequest -import org.onap.cps.ncmp.exceptions.PayloadTooLargeException +import org.onap.cps.ncmp.api.exceptions.PayloadTooLargeException import org.springframework.http.ResponseEntity import reactor.core.publisher.Mono import spock.lang.Specification diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy index ad7d741ae2..4bcafe8c61 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/CpsAsyncRequestResponseEventIntegrationSpec.groovy @@ -25,10 +25,10 @@ import org.apache.kafka.clients.consumer.KafkaConsumer import org.apache.kafka.common.serialization.StringDeserializer import org.mapstruct.factory.Mappers import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumerSpec.groovy index 7e9f5089b7..afb594ab04 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/DataOperationEventConsumerSpec.groovy @@ -30,9 +30,9 @@ import org.apache.kafka.clients.consumer.ConsumerRecord import org.apache.kafka.clients.consumer.KafkaConsumer import org.apache.kafka.common.header.internals.RecordHeaders import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/FilterStrategiesIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/FilterStrategiesIntegrationSpec.groovy index 0643dbcf17..01d2a3666b 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/FilterStrategiesIntegrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/FilterStrategiesIntegrationSpec.groovy @@ -22,9 +22,9 @@ package org.onap.cps.ncmp.impl.data.async import io.cloudevents.core.builder.CloudEventBuilder import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.impl.config.kafka.KafkaConfig -import org.onap.cps.ncmp.api.kafka.ConsumerBaseSpec +import org.onap.cps.ncmp.config.KafkaConfig import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent +import org.onap.cps.ncmp.utils.events.ConsumerBaseSpec import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.EnableAutoConfiguration diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/SerializationIntegrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/SerializationIntegrationSpec.groovy index 94ebc38a48..3fe7ec222e 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/SerializationIntegrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/async/SerializationIntegrationSpec.groovy @@ -23,13 +23,13 @@ package org.onap.cps.ncmp.impl.data.async import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.core.builder.CloudEventBuilder import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.impl.config.kafka.KafkaConfig -import org.onap.cps.ncmp.api.kafka.ConsumerBaseSpec +import org.onap.cps.ncmp.config.KafkaConfig import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent import org.onap.cps.ncmp.events.async1_0_0.Data import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent import org.onap.cps.ncmp.events.async1_0_0.Response +import org.onap.cps.ncmp.utils.events.ConsumerBaseSpec import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelperSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelperSpec.groovy index cdf9eae40b..84eafb0da3 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelperSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/utils/DmiDataOperationsHelperSpec.groovy @@ -28,13 +28,13 @@ import org.apache.kafka.clients.consumer.KafkaConsumer import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.data.models.DataOperationRequest import org.onap.cps.ncmp.api.data.models.OperationType -import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec +import org.onap.cps.ncmp.config.CpsApplicationContext import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent import org.onap.cps.ncmp.impl.data.models.DmiDataOperation import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.test.context.ContextConfiguration diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImplSpec.groovy new file mode 100644 index 0000000000..94c490ab07 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobServiceImplSpec.groovy @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 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.impl.datajobs + +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 org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata +import org.onap.cps.ncmp.api.datajobs.models.DataJobReadRequest +import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest +import org.onap.cps.ncmp.api.datajobs.models.ReadOperation +import org.onap.cps.ncmp.api.datajobs.models.WriteOperation +import org.slf4j.LoggerFactory +import spock.lang.Specification + +class DataJobServiceImplSpec extends Specification { + + def mockWriteRequestExaminer = Mock(WriteRequestExaminer) + def mockDmiSubJobRequestHandler = Mock(DmiSubJobRequestHandler) + + def objectUnderTest = new DataJobServiceImpl(mockDmiSubJobRequestHandler, mockWriteRequestExaminer) + + def myDataJobMetadata = new DataJobMetadata('', '', '') + + def logger = Spy(ListAppender) + + def setup() { + setupLogger() + } + + def cleanup() { + ((Logger) LoggerFactory.getLogger(DataJobServiceImpl.class)).detachAndStopAllAppenders() + } + + def 'Read data job request.'() { + when: 'read data job request is processed' + def readOperation = new ReadOperation('', '', '', [], [], '', '', 1) + objectUnderTest.readDataJob('my-job-id', myDataJobMetadata, new DataJobReadRequest([readOperation])) + then: 'the data job id is correctly logged' + def loggingEvent = logger.list[0] + assert loggingEvent.level == Level.INFO + assert loggingEvent.formattedMessage.contains('data job id for read operation is: my-job-id') + } + + def 'Write data-job request.'() { + given: 'data job metadata and write request' + def dataJobWriteRequest = new DataJobWriteRequest([new WriteOperation('', '', '', null)]) + and: 'a map of producer key and dmi 3gpp write operation' + def dmiWriteOperationsPerProducerKey = [:] + when: 'write data job request is processed' + objectUnderTest.writeDataJob('my-job-id', myDataJobMetadata, dataJobWriteRequest) + then: 'the examiner service is called and a map is returned' + 1 * mockWriteRequestExaminer.splitDmiWriteOperationsFromRequest('my-job-id', dataJobWriteRequest) >> dmiWriteOperationsPerProducerKey + and: 'the dmi request handler is called with the result from the examiner' + 1 * mockDmiSubJobRequestHandler.sendRequestsToDmi('my-job-id', myDataJobMetadata, dmiWriteOperationsPerProducerKey) + } + + def setupLogger() { + def setupLogger = ((Logger) LoggerFactory.getLogger(DataJobServiceImpl.class)) + setupLogger.setLevel(Level.DEBUG) + setupLogger.addAppender(logger) + logger.start() + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandlerSpec.groovy new file mode 100644 index 0000000000..e07b978482 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandlerSpec.groovy @@ -0,0 +1,40 @@ +package org.onap.cps.ncmp.impl.datajobs + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.ncmp.api.data.models.OperationType +import org.onap.cps.ncmp.api.datajobs.models.DataJobMetadata +import org.onap.cps.ncmp.api.datajobs.models.DmiWriteOperation +import org.onap.cps.ncmp.api.datajobs.models.ProducerKey +import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse +import org.onap.cps.ncmp.impl.dmi.DmiProperties +import org.onap.cps.ncmp.impl.dmi.DmiRestClient +import org.onap.cps.ncmp.impl.models.RequiredDmiService +import org.onap.cps.utils.JsonObjectMapper +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import spock.lang.Specification + +class DmiSubJobRequestHandlerSpec extends Specification { + + def mockDmiRestClient = Mock(DmiRestClient) + def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + def mockDmiProperties = Mock(DmiProperties) + def static NO_AUTH = null + def objectUnderTest = new DmiSubJobRequestHandler(mockDmiRestClient, mockDmiProperties, jsonObjectMapper) + + def 'Send a sub-job request to the DMI Plugin.'() { + given: 'a data job id, metadata and a map of producer keys and write operations to create a request' + def dataJobId = 'some-job-id' + def dataJobMetadata = new DataJobMetadata('', '', '') + def dmiWriteOperation = new DmiWriteOperation('', '', '', null, '', [:]) + def dmiWriteOperationsPerProducerKey = [new ProducerKey('', ''): [dmiWriteOperation]] + def response = new ResponseEntity<>(new SubJobWriteResponse('my-sub-job-id', '', ''), HttpStatus.OK) + when: 'sending request to DMI invoked' + objectUnderTest.sendRequestsToDmi(dataJobId, dataJobMetadata, dmiWriteOperationsPerProducerKey) + then: 'the dmi rest client is called' + 1 * mockDmiRestClient.synchronousPostOperationWithJsonData(RequiredDmiService.DATA, _, _, OperationType.CREATE, NO_AUTH) >> response + and: 'the result contains the expected sub-job write responses' + def result = response.body + assert result.subJobId() == 'my-sub-job-id' + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy new file mode 100644 index 0000000000..84eb78b751 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy @@ -0,0 +1,63 @@ + +package org.onap.cps.ncmp.impl.datajobs + +import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest +import org.onap.cps.ncmp.api.datajobs.models.WriteOperation +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher +import org.onap.cps.spi.model.DataNode +import spock.lang.Specification + +class WriteRequestExaminerSpec extends Specification { + + def mockAlternateIdMatcher = Mock(AlternateIdMatcher) + def objectUnderTest = new WriteRequestExaminer(mockAlternateIdMatcher) + + def setup() { + def ch1 = new DataNode(leaves: [id: 'ch1', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p1']) + def ch2 = new DataNode(leaves: [id: 'ch2', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p1']) + def ch3 = new DataNode(leaves: [id: 'ch3', 'dmi-service-name': 'dmiA', 'data-producer-identifier': 'p2']) + def ch4 = new DataNode(leaves: [id: 'ch4', 'dmi-service-name': 'dmiB', 'data-producer-identifier': 'p1']) + mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn1', '/') >> ch1 + mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn2', '/') >> ch2 + mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn3', '/') >> ch3 + mockAlternateIdMatcher.getCmHandleDataNodeByLongestMatchingAlternateId('fdn4', '/') >> ch4 + } + + def 'Create a map of dmi write requests per producer key with #scenario.'() { + given: 'a write request with some write operations' + def writeOperations = writeOperationFdns.collect { + new WriteOperation(it, '', '', null) + } + and: 'operations are wrapped in a write request' + def dataJobWriteRequest = new DataJobWriteRequest(writeOperations) + when: 'the DMI write operations are split from the request' + def dmiWriteOperationsPerProducerKey = objectUnderTest.splitDmiWriteOperationsFromRequest('some id', dataJobWriteRequest) + then: 'we get the expected number of keys and values.' + def producerKeysAsStrings = dmiWriteOperationsPerProducerKey.keySet().collect { + it.toString() + } + assert producerKeysAsStrings.size() == expectedKeys.size() + assert expectedKeys.containsAll(producerKeysAsStrings) + where: + scenario | writeOperationFdns || expectedKeys + 'one fdn' | ['fdn1'] || ['dmiA#p1'] + 'a duplicated target' | ['fdn1','fdn1'] || ['dmiA#p1'] + 'two different targets' | ['fdn1','fdn2'] || ['dmiA#p1'] + 'two different targets and different producer keys' | ['fdn1','fdn3'] || ['dmiA#p1', 'dmiA#p2'] + 'two different targets and different DMI services' | ['fdn1','fdn4'] || ['dmiA#p1', 'dmiB#p1'] + 'many targets with different dmi service names and producer keys' | ['fdn1', 'fdn2', 'fdn3', 'fdn4'] || ['dmiA#p1', 'dmiA#p2', 'dmiB#p1'] + } + + def 'Validate the ordering of the created sub jobs.'() { + given: 'a few write operations for the same producer' + def writeOperations = (1..3).collect { + new WriteOperation('fdn1', '', it.toString(), null) + } + and: 'operation is wrapped in a write request' + def dataJobWriteRequest = new DataJobWriteRequest(writeOperations) + when: 'the DMI write operations are split from the request' + def dmiWriteOperations = objectUnderTest.splitDmiWriteOperationsFromRequest('some id', dataJobWriteRequest).values().iterator().next() + then: 'we get the operation ids in the expected order.' + assert dmiWriteOperations.operationId == ['1', '2', '3'] + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy new file mode 100644 index 0000000000..affbf2aa4f --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy @@ -0,0 +1,75 @@ +/* + * ============LICENSE_START======================================================= + * 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.impl.dmi + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.ncmp.api.inventory.models.CompositeState +import org.onap.cps.ncmp.impl.inventory.InventoryPersistence +import org.onap.cps.ncmp.impl.inventory.models.CmHandleState +import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle +import org.spockframework.spring.SpringBean +import spock.lang.Shared +import spock.lang.Specification + +abstract class DmiOperationsBaseSpec extends Specification { + + @Shared + def yangModelCmHandleProperty = new YangModelCmHandle.Property('prop1', 'val1') + + @SpringBean + DmiRestClient mockDmiRestClient = Mock() + + @SpringBean + InventoryPersistence mockInventoryPersistence = Mock() + + @SpringBean + ObjectMapper spyObjectMapper = Spy() + + def yangModelCmHandle = new YangModelCmHandle() + def static dmiServiceName = 'myServiceName' + def static cmHandleId = 'some-cm-handle' + def static resourceIdentifier = 'parent/child' + + def mockYangModelCmHandleRetrieval(dmiProperties) { + populateYangModelCmHandle(dmiProperties, '') + mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle + } + + def mockYangModelCmHandleRetrieval(dmiProperties, moduleSetTag) { + populateYangModelCmHandle(dmiProperties, moduleSetTag) + mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle + } + + def mockYangModelCmHandleCollectionRetrieval(dmiProperties) { + populateYangModelCmHandle(dmiProperties, '') + mockInventoryPersistence.getYangModelCmHandles(_) >> [yangModelCmHandle] + } + + def populateYangModelCmHandle(dmiProperties, moduleSetTag) { + yangModelCmHandle.dmiDataServiceName = dmiServiceName + yangModelCmHandle.dmiServiceName = dmiServiceName + yangModelCmHandle.dmiProperties = dmiProperties + yangModelCmHandle.id = cmHandleId + yangModelCmHandle.compositeState = new CompositeState() + yangModelCmHandle.compositeState.cmHandleState = CmHandleState.READY + yangModelCmHandle.moduleSetTag = moduleSetTag + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiPropertiesSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiPropertiesSpec.groovy new file mode 100644 index 0000000000..418b3bb3c8 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiPropertiesSpec.groovy @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 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.impl.dmi + + +import spock.lang.Specification + +class DmiPropertiesSpec extends Specification { + + def objectUnderTest = new DmiProperties() + + def 'Geting dmi base path.'() { + given: 'base path of #dmiBasePath' + objectUnderTest.dmiBasePath = dmiBasePath + expect: 'Preceding and trailing slash wil be removed' + assert objectUnderTest.getDmiBasePath() == 'test' + where: 'the following dmi base paths are used' + dmiBasePath << [ 'test' , '/test', 'test/', '/test/' ] + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy new file mode 100644 index 0000000000..3dadf23249 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy @@ -0,0 +1,166 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2024 Nordix Foundation + * Modifications Copyright (C) 2022 Bell Canada + * ================================================================================ + * 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.impl.dmi + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ObjectNode +import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException +import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.utils.JsonObjectMapper +import org.springframework.http.HttpHeaders +import org.springframework.http.HttpStatus +import org.springframework.http.HttpStatusCode +import org.springframework.http.ResponseEntity +import org.springframework.web.client.HttpServerErrorException +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.WebClientRequestException +import org.springframework.web.reactive.function.client.WebClientResponseException +import reactor.core.publisher.Mono +import spock.lang.Specification + +import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR +import static org.onap.cps.ncmp.api.data.models.OperationType.READ +import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA +import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL + +class DmiRestClientSpec extends Specification { + + static final NO_AUTH_HEADER = null + static final BASIC_AUTH_HEADER = 'Basic c29tZSB1c2VyOnNvbWUgcGFzc3dvcmQ=' + static final BEARER_AUTH_HEADER = 'Bearer my-bearer-token' + static final urlTemplateParameters = new UrlTemplateParameters('/{pathParam1}/{pathParam2}', ['pathParam1': 'my', 'pathParam2': 'url']) + + def mockDataServicesWebClient = Mock(WebClient) + def mockModelServicesWebClient = Mock(WebClient) + def mockHealthChecksWebClient = Mock(WebClient) + + def mockRequestBody = Mock(WebClient.RequestBodyUriSpec) + def mockResponse = Mock(WebClient.ResponseSpec) + + def mockDmiProperties = Mock(DmiProperties) + + JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + + DmiRestClient objectUnderTest = new DmiRestClient(mockDmiProperties, jsonObjectMapper, mockDataServicesWebClient, mockModelServicesWebClient, mockHealthChecksWebClient) + + def setup() { + mockRequestBody.uri(_,_) >> mockRequestBody + mockRequestBody.headers(_) >> mockRequestBody + mockRequestBody.body(_) >> mockRequestBody + mockRequestBody.retrieve() >> mockResponse + } + + def 'DMI POST Operation with JSON for DMI Data Service '() { + given: 'the Data web client returns a valid response entity for the expected parameters' + mockDataServicesWebClient.post() >> mockRequestBody + mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Data service', HttpStatus.I_AM_A_TEAPOT)) + when: 'POST operation is invoked fro Data Service' + def response = objectUnderTest.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) + then: 'the output of the method is equal to the output from the test template' + assert response.statusCode == HttpStatus.I_AM_A_TEAPOT + assert response.body == 'from Data service' + } + + def 'DMI POST Operation with JSON for DMI Model Service '() { + given: 'the Model web client returns a valid response entity for the expected parameters' + mockModelServicesWebClient.post() >> mockRequestBody + mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Model service', HttpStatus.I_AM_A_TEAPOT)) + when: 'POST operation is invoked for Model Service' + def response = objectUnderTest.synchronousPostOperationWithJsonData(MODEL, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) + then: 'the output of the method is equal to the output from the test template' + assert response.statusCode == HttpStatus.I_AM_A_TEAPOT + assert response.body == 'from Model service' + } + + def 'Dmi service sends client error response when #scenario'() { + given: 'the web client unable to return response entity but error' + mockDataServicesWebClient.post() >> mockRequestBody + mockResponse.toEntity(Object.class) >> Mono.error(exceptionType) + when: 'POST operation is invoked' + objectUnderTest.synchronousPostOperationWithJsonData(DATA, urlTemplateParameters, 'some json', READ, NO_AUTH_HEADER) + then: 'a http client exception is thrown' + def thrown = thrown(DmiClientRequestException) + and: 'the exception has the relevant details from the error response' + assert thrown.ncmpResponseStatus == expectedNcmpResponseStatusCode + assert thrown.httpStatusCode == httpStatusCode + where: 'the following errors occur' + scenario | httpStatusCode | exceptionType || expectedNcmpResponseStatusCode + 'dmi service unavailable' | 503 | new WebClientRequestException(new RuntimeException('some-error'), null, null, new HttpHeaders()) || DMI_SERVICE_NOT_RESPONDING + 'dmi request timeout' | 408 | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null) || DMI_SERVICE_NOT_RESPONDING + 'dmi server error' | 500 | new WebClientResponseException('message', httpStatusCode, 'statusText', null, null, null) || UNABLE_TO_READ_RESOURCE_DATA + 'dmi service unavailable' | 503 | new HttpServerErrorException(HttpStatusCode.valueOf(503)) || DMI_SERVICE_NOT_RESPONDING + 'unknown error' | 500 | new Throwable('message') || UNKNOWN_ERROR + } + + def 'Dmi trust level is determined by spring boot health status'() { + given: 'a health check response' + def dmiPluginHealthCheckResponseJsonData = TestUtils.getResourceFileContent('dmiPluginHealthCheckResponse.json') + def jsonNode = jsonObjectMapper.convertJsonString(dmiPluginHealthCheckResponseJsonData, JsonNode.class) + ((ObjectNode) jsonNode).put('status', 'my status') + mockHealthChecksWebClient.get() >> mockRequestBody + mockResponse.onStatus(_,_)>> mockResponse + mockResponse.bodyToMono(JsonNode.class) >> Mono.just(jsonNode) + when: 'get trust level of the dmi plugin' + def urlTemplateParameters = new UrlTemplateParameters('some url', [:]) + def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block() + then: 'the status value from the json is returned' + assert result == 'my status' + } + + def 'Failing to get dmi plugin health status #scenario'() { + given: 'web client instance with #scenario' + mockHealthChecksWebClient.get() >> mockRequestBody + mockResponse.onStatus(_, _) >> mockResponse + mockResponse.bodyToMono(_) >> Mono.error(exceptionType) + when: 'attempt to get health status of the dmi plugin' + def urlTemplateParameters = new UrlTemplateParameters('some url', [:]) + def result = objectUnderTest.getDmiHealthStatus(urlTemplateParameters).block() + then: 'result will be empty' + assert result == '' + where: 'the following responses are used' + scenario | exceptionType + 'dmi request timeout' | new WebClientResponseException('some-message', 408, 'some-text', null, null, null) + 'dmi service unavailable' | new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE) + } + + def 'DMI auth header #scenario'() { + when: 'Specific dmi properties are provided' + mockDmiProperties.dmiBasicAuthEnabled >> authEnabled + mockDmiProperties.authUsername >> 'some user' + mockDmiProperties.authPassword >> 'some password' + then: 'http headers to conditionally have Authorization header' + def httpHeaders = new HttpHeaders() + objectUnderTest.configureHttpHeaders(httpHeaders, ncmpAuthHeader) + def outputAuthHeader = (httpHeaders.Authorization == null ? null : httpHeaders.Authorization[0]) + assert outputAuthHeader == expectedAuthHeader + where: 'the following configurations are used' + scenario | authEnabled | ncmpAuthHeader || expectedAuthHeader + 'DMI basic auth enabled, no NCMP bearer token' | true | NO_AUTH_HEADER || BASIC_AUTH_HEADER + 'DMI basic auth enabled, with NCMP bearer token' | true | BEARER_AUTH_HEADER || BASIC_AUTH_HEADER + 'DMI basic auth disabled, no NCMP bearer token' | false | NO_AUTH_HEADER || NO_AUTH_HEADER + 'DMI basic auth disabled, with NCMP bearer token' | false | BEARER_AUTH_HEADER || BEARER_AUTH_HEADER + 'DMI basic auth disabled, with NCMP basic auth' | false | BASIC_AUTH_HEADER || NO_AUTH_HEADER + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy new file mode 100644 index 0000000000..9e1b37023b --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy @@ -0,0 +1,64 @@ +/* + * ============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.impl.dmi + + +import spock.lang.Specification + +class DmiServiceUrlTemplateBuilderSpec extends Specification { + + def objectUnderTest = new DmiServiceUrlTemplateBuilder() + + def 'Build URL template parameters with (variable) path segments and query parameters.'() { + given: 'the URL details are given to the builder' + objectUnderTest.fixedPathSegment('segment') + objectUnderTest.variablePathSegment('myVariableSegment','someValue') + objectUnderTest.fixedPathSegment('segment?with:special&characters') + objectUnderTest.queryParameter('param1', 'abc') + objectUnderTest.queryParameter('param2', 'value?with#special:characters') + when: 'the URL template parameters are created' + def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') + then: 'the URL template contains variable names instead of value and un-encoded fixed segment' + assert result.urlTemplate == 'myDmiServer/myBasePath/v1/segment/{myVariableSegment}/segment?with:special&characters?param1={param1}¶m2={param2}' + and: 'URL variables contains name and un-encoded value pairs' + assert result.urlVariables == ['myVariableSegment': 'someValue', 'param1': 'abc', 'param2': 'value?with#special:characters'] + } + + def 'Build URL template parameters with special characters in query parameters.'() { + given: 'the query parameter is given to the builder' + objectUnderTest.queryParameter('my¶m', 'special&characters=are?not\\encoded') + when: 'the URL template parameters are created' + def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') + then: 'Special characters are not encoded' + assert result.urlVariables == ['my¶m': 'special&characters=are?not\\encoded'] + } + + def 'Build URL template parameters with empty query parameters.'() { + when: 'the query parameter is given to the builder' + objectUnderTest.queryParameter('param', value) + and: 'the URL template parameters are create' + def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath') + then: 'no parameter gets added' + assert result.urlVariables.isEmpty() + where: 'the following parameter values are used' + value << [ null, '', ' ' ] + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy new file mode 100644 index 0000000000..fca47d8c24 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 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.impl.dmi + + +import org.onap.cps.ncmp.config.HttpClientConfiguration +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.TestPropertySource +import org.springframework.web.reactive.function.client.WebClient +import spock.lang.Specification + +@SpringBootTest +@ContextConfiguration(classes = [HttpClientConfiguration]) +@TestPropertySource(properties = ['ncmp.dmi.httpclient.data-services.connectionTimeoutInSeconds=1', 'ncmp.dmi.httpclient.model-services.maximumInMemorySizeInMegabytes=1']) +@EnableConfigurationProperties +class DmiWebClientConfigurationSpec extends Specification { + + def webClientBuilder = Mock(WebClient.Builder) { + defaultHeaders(_) >> it + clientConnector(_) >> it + codecs(_) >> it + build() >> Mock(WebClient) + } + + def httpClientConfiguration = Spy(HttpClientConfiguration.class) + + def objectUnderTest = new DmiWebClientConfiguration(httpClientConfiguration) + + def 'Web Client Configuration construction.'() { + expect: 'the system can create an instance' + new DmiWebClientConfiguration(httpClientConfiguration) != null + } + + def 'Creating a web client instance data service.'() { + given: 'Web client configuration is invoked' + def dataServicesWebClient = objectUnderTest.dataServicesWebClient(webClientBuilder) + expect: 'the system can create an instance for data service' + assert dataServicesWebClient != null + assert dataServicesWebClient instanceof WebClient + } + + def 'Creating a web client instance model service.'() { + given: 'Web client configuration invoked' + def modelServicesWebClient = objectUnderTest.modelServicesWebClient(webClientBuilder) + expect: 'the system can create an instance for model service' + assert modelServicesWebClient != null + assert modelServicesWebClient instanceof WebClient + } + + def 'Creating a web client instance health service.'() { + given: 'Web client configuration invoked' + def healthChecksWebClient = objectUnderTest.healthChecksWebClient(webClientBuilder) + expect: 'the system can create an instance for health service' + assert healthChecksWebClient != null + assert healthChecksWebClient instanceof WebClient + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy index 4ff56312a1..0c702abea6 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy @@ -24,7 +24,7 @@ package org.onap.cps.ncmp.impl.inventory import com.hazelcast.map.IMap import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService -import org.onap.cps.ncmp.api.impl.exception.DmiRequestException +import org.onap.cps.ncmp.api.exceptions.DmiRequestException import org.onap.cps.ncmp.api.inventory.models.CmHandleRegistrationResponse import org.onap.cps.ncmp.api.inventory.models.CompositeState import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy index 17352977b8..196a1cd360 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy @@ -23,11 +23,11 @@ package org.onap.cps.ncmp.impl.inventory.sync import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.ncmp.api.impl.config.DmiProperties -import org.onap.cps.ncmp.impl.DmiOperationsBaseSpec +import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec +import org.onap.cps.ncmp.impl.dmi.DmiProperties +import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters import org.onap.cps.spi.model.ModuleReference import org.onap.cps.utils.JsonObjectMapper -import org.onap.cps.ncmp.api.impl.utils.url.builder.UrlTemplateParameters import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsPublisherSpec.groovy index e7674761c8..3e7ed9aff6 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsPublisherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventsPublisherSpec.groovy @@ -24,10 +24,10 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.consumer.KafkaConsumer import org.apache.kafka.common.serialization.StringDeserializer import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.events.lcm.v1.Event import org.onap.cps.ncmp.events.lcm.v1.LcmEvent import org.onap.cps.ncmp.utils.TestUtils +import org.onap.cps.ncmp.utils.events.MessagingBaseSpec import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy index f975d23ba2..0a34d267c5 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy @@ -20,9 +20,9 @@ package org.onap.cps.ncmp.impl.inventory.trustlevel -import org.onap.cps.ncmp.api.impl.client.DmiRestClient -import org.onap.cps.ncmp.api.impl.utils.url.builder.UrlTemplateParameters import org.onap.cps.ncmp.api.inventory.models.TrustLevel +import org.onap.cps.ncmp.impl.dmi.DmiRestClient +import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService import reactor.core.publisher.Mono import spock.lang.Specification diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatterSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatterSpec.groovy new file mode 100644 index 0000000000..7f07165df3 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/EventDateTimeFormatterSpec.groovy @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 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.impl.utils + +import spock.lang.Specification + +import java.time.Year + +class EventDateTimeFormatterSpec extends Specification { + + def 'Get ISO formatted date and time.' () { + expect: 'iso formatted date and time starts with current year' + assert EventDateTimeFormatter.getCurrentIsoFormattedDateTime().startsWith(String.valueOf(Year.now())) + } + + def 'Convert date time from string to OffsetDateTime type.'() { + when: 'date time as a string is converted to OffsetDateTime type' + def result = EventDateTimeFormatter.toIsoOffsetDateTime('2024-05-28T18:28:02.869+0100') + then: 'the result convert back back to a string is the same as the original timestamp (except the format of timezone offset)' + assert result.toString() == '2024-05-28T18:28:02.869+01:00' + } + + def 'Convert blank string.' () { + expect: 'converting a blank string result in null' + assert EventDateTimeFormatter.toIsoOffsetDateTime(' ') == null + } + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/AbstractModelLoaderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/AbstractModelLoaderSpec.groovy index 162a9831ce..38eeaa589f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/AbstractModelLoaderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/AbstractModelLoaderSpec.groovy @@ -23,15 +23,15 @@ package org.onap.cps.ncmp.init import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.core.read.ListAppender -import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService +import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsModuleService -import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException +import org.onap.cps.ncmp.exceptions.NcmpStartUpException import org.onap.cps.spi.CascadeDeleteAllowed import org.onap.cps.spi.exceptions.AlreadyDefinedException -import org.springframework.boot.SpringApplication import org.slf4j.LoggerFactory +import org.springframework.boot.SpringApplication import org.springframework.boot.context.event.ApplicationStartedEvent import org.springframework.context.annotation.AnnotationConfigApplicationContext import spock.lang.Specification diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy index dd1fd0b462..caaad8d34d 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy @@ -27,7 +27,7 @@ import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsModuleService -import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException +import org.onap.cps.ncmp.exceptions.NcmpStartUpException import org.onap.cps.spi.exceptions.AlreadyDefinedException import org.onap.cps.spi.model.Dataspace import org.slf4j.LoggerFactory diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/CmAvcEventPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/CmAvcEventPublisherSpec.groovy index 247f321834..051f5df4cf 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/CmAvcEventPublisherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/CmAvcEventPublisherSpec.groovy @@ -23,8 +23,7 @@ package org.onap.cps.ncmp.utils.events import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import org.onap.cps.events.EventsPublisher -import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext -import org.onap.cps.ncmp.api.kafka.MessagingBaseSpec +import org.onap.cps.ncmp.config.CpsApplicationContext import org.onap.cps.ncmp.events.avc.ncmp_to_client.Avc import org.onap.cps.ncmp.events.avc.ncmp_to_client.AvcEvent import org.onap.cps.utils.JsonObjectMapper diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/ConsumerBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/ConsumerBaseSpec.groovy new file mode 100644 index 0000000000..73dc2a37c5 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/ConsumerBaseSpec.groovy @@ -0,0 +1,44 @@ +/* + * ============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.utils.events + + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.kafka.config.KafkaListenerEndpointRegistry +import org.springframework.kafka.test.utils.ContainerTestUtils + +@SpringBootTest(classes = KafkaListenerEndpointRegistry.class) +class ConsumerBaseSpec extends MessagingBaseSpec { + + @Autowired + private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry + + def setup() { + activateListeners() + } + + def activateListeners() { + kafkaListenerEndpointRegistry.getListenerContainers().forEach( + messageListenerContainer -> { ContainerTestUtils.waitForAssignment(messageListenerContainer, 1) } + ) + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/MessagingBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/MessagingBaseSpec.groovy new file mode 100644 index 0000000000..377a1a6637 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/MessagingBaseSpec.groovy @@ -0,0 +1,75 @@ +/* + * ============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.utils.events + +import io.cloudevents.CloudEvent +import io.cloudevents.kafka.CloudEventSerializer +import org.apache.kafka.common.serialization.StringDeserializer +import org.apache.kafka.common.serialization.StringSerializer +import org.springframework.kafka.core.DefaultKafkaProducerFactory +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.support.serializer.JsonSerializer +import org.springframework.test.context.DynamicPropertyRegistry +import org.springframework.test.context.DynamicPropertySource +import org.testcontainers.containers.KafkaContainer +import org.testcontainers.utility.DockerImageName +import spock.lang.Specification + +class MessagingBaseSpec extends Specification { + + def setupSpec() { + kafkaTestContainer.start() + } + + def cleanupSpec() { + kafkaTestContainer.stop() + } + + static kafkaTestContainer = new KafkaContainer(DockerImageName.parse('registry.nordix.org/onaptest/confluentinc/cp-kafka:6.2.1').asCompatibleSubstituteFor('confluentinc/cp-kafka')) + + def legacyEventKafkaTemplate = new KafkaTemplate<>(new DefaultKafkaProducerFactory(eventProducerConfigProperties(JsonSerializer))) + + def cloudEventKafkaTemplate = new KafkaTemplate<>(new DefaultKafkaProducerFactory(eventProducerConfigProperties(CloudEventSerializer))) + + @DynamicPropertySource + static void registerKafkaProperties(DynamicPropertyRegistry dynamicPropertyRegistry) { + dynamicPropertyRegistry.add('spring.kafka.bootstrap-servers', kafkaTestContainer::getBootstrapServers) + } + + def eventProducerConfigProperties(valueSerializer) { + return [('bootstrap.servers'): kafkaTestContainer.getBootstrapServers().split(',')[0], + ('retries') : 0, + ('batch-size') : 16384, + ('linger.ms') : 1, + ('buffer.memory') : 33554432, + ('key.serializer') : StringSerializer, + ('value.serializer') : valueSerializer] + } + + def eventConsumerConfigProperties(consumerGroupId, valueSerializer) { + return [('bootstrap.servers') : kafkaTestContainer.getBootstrapServers().split(',')[0], + ('key.deserializer') : StringDeserializer, + ('value.deserializer'): valueSerializer, + ('auto.offset.reset') : 'earliest', + ('group.id') : consumerGroupId + ] + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/TopicValidatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/TopicValidatorSpec.groovy index 26148f8709..8fc3e18c7f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/TopicValidatorSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/events/TopicValidatorSpec.groovy @@ -20,7 +20,7 @@ package org.onap.cps.ncmp.utils.events -import org.onap.cps.ncmp.exceptions.InvalidTopicException +import org.onap.cps.ncmp.api.exceptions.InvalidTopicException import spock.lang.Specification class TopicValidatorSpec extends Specification { -- cgit 1.2.3-korg