diff options
Diffstat (limited to 'cps-ncmp-service/src')
16 files changed, 249 insertions, 83 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java new file mode 100644 index 0000000000..aaa4f1e5bb --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java @@ -0,0 +1,57 @@ +/*- + * ============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.config; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.convert.DurationUnit; + +@Getter +@Setter +@ConfigurationProperties(prefix = "httpclient5", ignoreUnknownFields = true) +public class HttpClientConfiguration { + + /** + * The maximum time to establish a connection. + */ + @DurationUnit(ChronoUnit.SECONDS) + private Duration connectionTimeoutInSeconds = Duration.ofSeconds(180); + + /** + * The maximum number of open connections per route. + */ + private int maximumConnectionsPerRoute = 50; + + /** + * The maximum total number of open connections. + */ + private int maximumConnectionsTotal = maximumConnectionsPerRoute * 2; + + /** + * The duration after which idle connections are evicted. + */ + @DurationUnit(ChronoUnit.SECONDS) + private Duration idleConnectionEvictionThresholdInSeconds = Duration.ofSeconds(5); + +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java index ffecf9c7f1..4460094f54 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-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. @@ -20,29 +20,36 @@ package org.onap.cps.ncmp.api.impl.config; -import java.time.Duration; import java.util.Arrays; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.apache.hc.client5.http.config.ConnectionConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.core5.util.Timeout; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.http.MediaType; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Configuration +@EnableConfigurationProperties(HttpClientConfiguration.class) @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class NcmpConfiguration { - private static final Duration CONNECTION_TIMEOUT_MILLISECONDS = Duration.ofMillis(180000); - private static final Duration READ_TIMEOUT_MILLISECONDS = Duration.ofMillis(180000); - @Getter @Component public static class DmiProperties { @@ -60,13 +67,38 @@ public class NcmpConfiguration { * Rest template bean. * * @param restTemplateBuilder the rest template builder + * @param httpClientConfiguration the http client configuration * @return rest template instance */ @Bean @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public static RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { - final RestTemplate restTemplate = restTemplateBuilder.setConnectTimeout(CONNECTION_TIMEOUT_MILLISECONDS) - .setReadTimeout(READ_TIMEOUT_MILLISECONDS).build(); + public static RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder, + final HttpClientConfiguration httpClientConfiguration) { + + final ConnectionConfig connectionConfig = ConnectionConfig.copy(ConnectionConfig.DEFAULT) + .setConnectTimeout(Timeout.of(httpClientConfiguration.getConnectionTimeoutInSeconds())) + .build(); + + final PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() + .setDefaultConnectionConfig(connectionConfig) + .setMaxConnTotal(httpClientConfiguration.getMaximumConnectionsTotal()) + .setMaxConnPerRoute(httpClientConfiguration.getMaximumConnectionsPerRoute()) + .build(); + + final CloseableHttpClient httpClient = HttpClients.custom() + .setConnectionManager(connectionManager) + .evictExpiredConnections() + .evictIdleConnections( + TimeValue.of(httpClientConfiguration.getIdleConnectionEvictionThresholdInSeconds())) + .build(); + + final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + + final RestTemplate restTemplate = restTemplateBuilder + .requestFactory(() -> requestFactory) + .setConnectTimeout(httpClientConfiguration.getConnectionTimeoutInSeconds()) + .build(); + setRestTemplateMessageConverters(restTemplate); return restTemplate; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java index 159d8f345a..a0aeac3e89 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java @@ -29,7 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.api.CpsAdminService; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; import org.onap.cps.api.CpsModuleService; import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; @@ -48,7 +48,7 @@ import org.springframework.stereotype.Component; public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements InventoryPersistence { private final CpsModuleService cpsModuleService; - private final CpsAdminService cpsAdminService; + private final CpsAnchorService cpsAnchorService; private final CpsValidator cpsValidator; /** @@ -58,14 +58,14 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv * @param cpsDataService cps data service instance * @param cpsModuleService cps module service instance * @param cpsValidator cps validation service instance - * @param cpsAdminService cps admin service instance + * @param cpsAnchorService cps anchor service instance */ public InventoryPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService, final CpsModuleService cpsModuleService, final CpsValidator cpsValidator, - final CpsAdminService cpsAdminService) { + final CpsAnchorService cpsAnchorService) { super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator); this.cpsModuleService = cpsModuleService; - this.cpsAdminService = cpsAdminService; + this.cpsAnchorService = cpsAnchorService; this.cpsValidator = cpsValidator; } @@ -160,7 +160,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv @Override public Collection<String> getCmHandleIdsWithGivenModules(final Collection<String> moduleNamesForQuery) { - return cpsAdminService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery); + return cpsAnchorService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery); } private static String createCmHandleXPath(final String cmHandleId) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java index a6b85a5cab..b21a2f1f85 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java @@ -35,7 +35,7 @@ import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.onap.cps.api.CpsAdminService; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; import org.onap.cps.api.CpsModuleService; import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries; @@ -59,9 +59,9 @@ public class ModuleSyncService { private final DmiModelOperations dmiModelOperations; private final CpsModuleService cpsModuleService; - private final CpsAdminService cpsAdminService; private final CmHandleQueries cmHandleQueries; private final CpsDataService cpsDataService; + private final CpsAnchorService cpsAnchorService; private final JsonObjectMapper jsonObjectMapper; private final Map<String, Collection<ModuleReference>> moduleSetTagCache; private static final Map<String, String> NO_NEW_MODULES = Collections.emptyMap(); @@ -105,7 +105,7 @@ public class ModuleSyncService { } } if (!inUpgrade) { - cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId); + cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId); } setCmHandleModuleSetTag(yangModelCmHandle, moduleSetTag); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java index fd5f2b0ed6..bd8dec4dc8 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java @@ -29,8 +29,9 @@ import java.util.Map; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.api.CpsAdminService; +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.spi.CascadeDeleteAllowed; @@ -44,9 +45,10 @@ import org.springframework.boot.context.event.ApplicationReadyEvent; @RequiredArgsConstructor abstract class AbstractModelLoader implements ModelLoader { - private final CpsAdminService cpsAdminService; + private final CpsDataspaceService cpsDataspaceService; private final CpsModuleService cpsModuleService; private final CpsDataService cpsDataService; + private final CpsAnchorService cpsAnchorService; private static final int EXIT_CODE_ON_ERROR = 1; @@ -71,7 +73,7 @@ abstract class AbstractModelLoader implements ModelLoader { void waitUntilDataspaceIsAvailable(final String dataspaceName) { log.info("Model Loader start-up, waiting for database to be ready"); int attemptCount = 0; - while (cpsAdminService.getDataspace(dataspaceName) == null) { + while (cpsDataspaceService.getDataspace(dataspaceName) == null) { if (attemptCount < maximumAttemptCount) { try { Thread.sleep(attemptCount * retryTimeMs); @@ -111,7 +113,7 @@ abstract class AbstractModelLoader implements ModelLoader { void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) { try { - cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName); + cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName); } catch (final AlreadyDefinedException alreadyDefinedException) { log.warn("Creating new anchor failed as anchor already exists"); } catch (final Exception exception) { @@ -134,7 +136,7 @@ abstract class AbstractModelLoader implements ModelLoader { void updateAnchorSchemaSet(final String dataspaceName, final String anchorName, final String schemaSetName) { try { - cpsAdminService.updateAnchorSchemaSet(dataspaceName, anchorName, schemaSetName); + cpsAnchorService.updateAnchorSchemaSet(dataspaceName, anchorName, schemaSetName); } catch (final Exception exception) { log.error("Updating schema set failed: {}", exception.getMessage()); throw new NcmpStartUpException("Updating schema set failed", exception.getMessage()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java index ade31e9ce6..c0f0279ad4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java @@ -23,8 +23,9 @@ package org.onap.cps.ncmp.init; import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.api.CpsAdminService; +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.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -45,10 +46,11 @@ public class CmDataSubscriptionModelLoader extends AbstractModelLoader { - public CmDataSubscriptionModelLoader(final CpsAdminService cpsAdminService, + public CmDataSubscriptionModelLoader(final CpsDataspaceService cpsDataspaceService, final CpsModuleService cpsModuleService, - final CpsDataService cpsDataService) { - super(cpsAdminService, cpsModuleService, cpsDataService); + final CpsDataService cpsDataService, + final CpsAnchorService cpsAnchorService) { + super(cpsDataspaceService, cpsModuleService, cpsDataService, cpsAnchorService); } @Value("${ncmp.model-loader.subscription:true}") diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java index b805cdcd84..0e562cdd8b 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java @@ -24,8 +24,9 @@ import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DA import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.api.CpsAdminService; +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.springframework.stereotype.Service; @@ -33,13 +34,14 @@ import org.springframework.stereotype.Service; @Service public class InventoryModelLoader extends AbstractModelLoader { - private static final String NEW_MODEL_FILE_NAME = "dmi-registry@2023-08-23.yang"; - private static final String NEW_SCHEMA_SET_NAME = "dmi-registry-2023-08-23"; + private static final String NEW_MODEL_FILE_NAME = "dmi-registry@2023-11-27.yang"; + private static final String NEW_SCHEMA_SET_NAME = "dmi-registry-2023-11-27"; - public InventoryModelLoader(final CpsAdminService cpsAdminService, + public InventoryModelLoader(final CpsDataspaceService cpsDataspaceService, final CpsModuleService cpsModuleService, - final CpsDataService cpsDataService) { - super(cpsAdminService, cpsModuleService, cpsDataService); + final CpsDataService cpsDataService, + final CpsAnchorService cpsAnchorService) { + super(cpsDataspaceService, cpsModuleService, cpsDataService, cpsAnchorService); } @Override diff --git a/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-08-23.yang b/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-11-27.yang index bb7604d91a..808bbdd1bc 100644 --- a/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-08-23.yang +++ b/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-11-27.yang @@ -8,24 +8,29 @@ module dmi-registry { contact "toine.siebelink@est.tech"; + revision "2023-11-27" { + description + "Added alternate-id"; + } + revision "2023-08-23" { description - "Added ModuleSetTag"; + "Added module-set-tag"; } revision "2022-05-10" { description - "Added DataSyncEnabled, SyncState with State, LastSyncTime, DataStoreSyncState with Operational and Running syncstate"; + "Added data-sync-enabled, sync-state with state, last-sync-time, data-store-sync-state with operational and running syncstate"; } revision "2022-02-10" { description - "Added State, LockReason, LockReasonDetails to aid with cmHandle sync and timestamp to aid with retry/timeout scenarios"; + "Added state, lock-reason, lock-reason-details to aid with cmHandle sync and timestamp to aid with retry/timeout scenarios"; } revision "2021-12-13" { description - "Added new list of public additional properties for a Cm-Handle which are exposed to clients of the NCMP interface"; + "Added new list of public-properties and additional-properties for a Cm-Handle which are exposed to clients of the NCMP interface"; } revision "2021-10-20" { @@ -83,6 +88,9 @@ module dmi-registry { leaf module-set-tag { type string; } + leaf alternate-id { + type string; + } list additional-properties { key "name"; @@ -129,3 +137,4 @@ module dmi-registry { } } } + diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy index 51b00d1431..f565ede394 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy @@ -210,12 +210,10 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { } and: 'state handler is invoked with the expected parameters' 1 * mockLcmEventsCmHandleStateHandler.initiateStateAdvised(_) >> { - args -> - { - def cmHandleStatePerCmHandle = (args[0] as Map) - cmHandleStatePerCmHandle.each { - assert (it.id == 'cmhandle' && it.dmiServiceName == 'my-server') - } + args -> { + def yangModelCmHandles = args[0] + assert yangModelCmHandles.id == ['cmhandle'] + assert yangModelCmHandles.dmiServiceName == ['my-server'] } } where: 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 new file mode 100644 index 0000000000..941c8b8a70 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy @@ -0,0 +1,48 @@ +/*- + * ============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.config + +import java.time.Duration +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 org.springframework.test.context.support.AnnotationConfigContextLoader +import spock.lang.Specification + +@SpringBootTest +@ContextConfiguration(classes = [HttpClientConfiguration]) +@EnableConfigurationProperties(HttpClientConfiguration.class) +@TestPropertySource(properties = ["httpclient5.connectionTimeoutInSeconds=1", "httpclient5.maximumConnectionsTotal=200"]) +class HttpClientConfigurationSpec extends Specification { + + @Autowired + private HttpClientConfiguration httpClientConfiguration + + def 'Test HttpClientConfiguration properties with custom and default values'() { + expect: 'custom property values' + httpClientConfiguration.getConnectionTimeoutInSeconds() == Duration.ofSeconds(1) + httpClientConfiguration.getMaximumConnectionsTotal() == 200 + and: 'default property values' + httpClientConfiguration.getMaximumConnectionsPerRoute() == 50 + httpClientConfiguration.getIdleConnectionEvictionThresholdInSeconds() == Duration.ofSeconds(5) + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy index e1aba79a50..a4df9b37cf 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation + * Copyright (C) 2021-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. @@ -19,22 +19,27 @@ */ package org.onap.cps.ncmp.api.impl.config +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.web.client.RestTemplateBuilder import org.springframework.http.MediaType +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter import org.springframework.test.context.ContextConfiguration import org.springframework.web.client.RestTemplate import spock.lang.Specification @SpringBootTest -@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties]) +@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, HttpClientConfiguration]) class NcmpConfigurationSpec extends Specification{ @Autowired NcmpConfiguration.DmiProperties dmiProperties - + + @Autowired + HttpClientConfiguration httpClientConfiguration + def mockRestTemplateBuilder = new RestTemplateBuilder() def 'NcmpConfiguration Construction.'() { @@ -48,11 +53,14 @@ class NcmpConfigurationSpec extends Specification{ dmiProperties.authPassword == 'some-password' } - def 'Rest Template creation.'() { + def 'Rest Template creation with CloseableHttpClient and MappingJackson2HttpMessageConverter.'() { when: 'a rest template is created' - def result = NcmpConfiguration.restTemplate(mockRestTemplateBuilder) + def result = NcmpConfiguration.restTemplate(mockRestTemplateBuilder, httpClientConfiguration) then: 'the rest template is returned' assert result instanceof RestTemplate + and: 'the rest template is created with httpclient5' + assert result.getRequestFactory() instanceof HttpComponentsClientHttpRequestFactory + assert ((HttpComponentsClientHttpRequestFactory) result.getRequestFactory()).getHttpClient() instanceof CloseableHttpClient; and: 'a jackson media converter has been added' def lastMessageConverter = result.getMessageConverters().get(result.getMessageConverters().size()-1) lastMessageConverter instanceof MappingJackson2HttpMessageConverter diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy index bb4eebd40e..297f18c989 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy @@ -22,6 +22,8 @@ package org.onap.cps.ncmp.api.impl.inventory +import org.onap.cps.api.CpsAnchorService + import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR @@ -30,12 +32,8 @@ import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NO_TIME import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.api.CpsAdminService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService -import org.onap.cps.ncmp.api.impl.inventory.CmHandleState -import org.onap.cps.ncmp.api.impl.inventory.CompositeState -import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistenceImpl import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.spi.CascadeDeleteAllowed import org.onap.cps.spi.FetchDescendantsOption @@ -58,12 +56,12 @@ class InventoryPersistenceImplSpec extends Specification { def mockCpsModuleService = Mock(CpsModuleService) - def mockCpsAdminService = Mock(CpsAdminService) + def mockCpsAnchorService = Mock(CpsAnchorService) def mockCpsValidator = Mock(CpsValidator) def objectUnderTest = new InventoryPersistenceImpl(spiedJsonObjectMapper, mockCpsDataService, mockCpsModuleService, - mockCpsValidator, mockCpsAdminService) + mockCpsValidator, mockCpsAnchorService) def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ") .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC)) @@ -284,7 +282,7 @@ class InventoryPersistenceImplSpec extends Specification { when: 'the method to get cm handles is called' objectUnderTest.getCmHandleIdsWithGivenModules(['sample-module-name']) then: 'the admin persistence service method to query anchors is invoked once with the same parameter' - 1 * mockCpsAdminService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, ['sample-module-name']) + 1 * mockCpsAnchorService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, ['sample-module-name']) } def 'Replace list content'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy index 2ded84fac1..de783ed2ca 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy @@ -20,13 +20,14 @@ package org.onap.cps.ncmp.api.impl.inventory.sync +import org.onap.cps.api.CpsAnchorService + import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_UPGRADE import org.onap.cps.ncmp.api.impl.inventory.CmHandleState import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.model.DataNode -import org.onap.cps.api.CpsAdminService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.spi.model.DataNodeBuilder @@ -45,14 +46,14 @@ class ModuleSyncServiceSpec extends Specification { def mockCpsModuleService = Mock(CpsModuleService) def mockDmiModelOperations = Mock(DmiModelOperations) - def mockCpsAdminService = Mock(CpsAdminService) + def mockCpsAnchorService = Mock(CpsAnchorService) def mockCmHandleQueries = Mock(CmHandleQueries) def mockCpsDataService = Mock(CpsDataService) def mockJsonObjectMapper = Mock(JsonObjectMapper) def mockModuleSetTagCache = [:] - def objectUnderTest = new ModuleSyncService(mockDmiModelOperations, mockCpsModuleService, mockCpsAdminService, - mockCmHandleQueries, mockCpsDataService, mockJsonObjectMapper, mockModuleSetTagCache) + def objectUnderTest = new ModuleSyncService(mockDmiModelOperations, mockCpsModuleService, + mockCmHandleQueries, mockCpsDataService, mockCpsAnchorService, mockJsonObjectMapper, mockModuleSetTagCache) def expectedDataspaceName = NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME def static cmHandleWithModuleSetTag = new DataNodeBuilder().withXpath("//cm-handles[@module-set-tag='tag-1'][@id='otherId']").withAnchor('otherId').build() @@ -78,7 +79,7 @@ class ModuleSyncServiceSpec extends Specification { then: 'create schema set from module is invoked with correct parameters' 1 * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', newModuleNameContentToMap, moduleReferences) and: 'anchor is created with the correct parameters' - 1 * mockCpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', 'ch-1') + 1 * mockCpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', 'ch-1') where: 'the following parameters are used' scenario | existingModuleResourcesInCps | identifiedNewModuleReferences | newModuleNameContentToMap | moduleSetTag 'one new module' | [['module2': '2'], ['module3': '3']] | [['module1': '1']] | [module1: 'some yang source'] | '' @@ -115,7 +116,7 @@ class ModuleSyncServiceSpec extends Specification { and: 'create schema set from module is invoked for the upgraded cm handle' expectedCallsToCeateSchemaSet * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences) and: 'No anchor is created for the upgraded cm handle' - 0 * mockCpsAdminService.createAnchor(*_) + 0 * mockCpsAnchorService.createAnchor(*_) where: 'the following parameters are used' scenario | populateCache | existingCmHandlesWithSameTag || expectedCallsToUpgradeSchemaSet | expectedCallsToCeateSchemaSet 'new' | false | [] || 0 | 1 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 e5ed21f1c4..3b1c25ba6a 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,7 +23,8 @@ 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.CpsAdminService +import org.onap.cps.api.CpsDataspaceService +import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.ncmp.api.impl.exception.NcmpStartUpException @@ -37,10 +38,11 @@ import spock.lang.Specification class AbstractModelLoaderSpec extends Specification { - def mockCpsAdminService = Mock(CpsAdminService) + def mockCpsDataspaceService = Mock(CpsDataspaceService) def mockCpsModuleService = Mock(CpsModuleService) def mockCpsDataService = Mock(CpsDataService) - def objectUnderTest = Spy(new TestModelLoader(mockCpsAdminService, mockCpsModuleService, mockCpsDataService)) + def mockCpsAnchorService = Mock(CpsAnchorService) + def objectUnderTest = Spy(new TestModelLoader(mockCpsDataspaceService, mockCpsModuleService, mockCpsDataService, mockCpsAnchorService)) def applicationContext = new AnnotationConfigApplicationContext() @@ -141,12 +143,12 @@ class AbstractModelLoaderSpec extends Specification { when: 'creating an anchor' objectUnderTest.createAnchor('some dataspace','some schema set','new name') then: 'the operation is delegated to the admin service' - 1 * mockCpsAdminService.createAnchor('some dataspace','some schema set', 'new name') + 1 * mockCpsAnchorService.createAnchor('some dataspace','some schema set', 'new name') } def 'Create anchor with already defined exception.'() { given: 'the admin service throws an already defined exception' - mockCpsAdminService.createAnchor(*_)>> { throw AlreadyDefinedException.forAnchor('name','context',null) } + mockCpsAnchorService.createAnchor(*_)>> { throw AlreadyDefinedException.forAnchor('name','context',null) } when: 'attempt to create anchor' objectUnderTest.createAnchor('some dataspace','some schema set','new name') then: 'the exception is ignored i.e. no exception thrown up' @@ -158,7 +160,7 @@ class AbstractModelLoaderSpec extends Specification { def 'Create anchor with any other exception.'() { given: 'the admin service throws a exception' - mockCpsAdminService.createAnchor(*_)>> { throw new RuntimeException('test message') } + mockCpsAnchorService.createAnchor(*_)>> { throw new RuntimeException('test message') } when: 'attempt to create anchor' objectUnderTest.createAnchor('some dataspace','some schema set','new name') then: 'a startup exception with correct message and details is thrown' @@ -201,12 +203,12 @@ class AbstractModelLoaderSpec extends Specification { when: 'a schema set for an anchor is updated' objectUnderTest.updateAnchorSchemaSet('some dataspace', 'anchor', 'new schema set') then: 'the request is delegated to the admin service' - 1 * mockCpsAdminService.updateAnchorSchemaSet('some dataspace', 'anchor', 'new schema set') + 1 * mockCpsAnchorService.updateAnchorSchemaSet('some dataspace', 'anchor', 'new schema set') } def 'Update anchor schema set with exception.'() { given: 'the admin service throws an exception' - mockCpsAdminService.updateAnchorSchemaSet(*_) >> { throw new RuntimeException('test message') } + mockCpsAnchorService.updateAnchorSchemaSet(*_) >> { throw new RuntimeException('test message') } when: 'a schema set for an anchor is updated' objectUnderTest.updateAnchorSchemaSet('some dataspace', 'anchor', 'new schema set') then: 'a startup exception with correct message and details is thrown' @@ -217,10 +219,11 @@ class AbstractModelLoaderSpec extends Specification { class TestModelLoader extends AbstractModelLoader { - TestModelLoader(final CpsAdminService cpsAdminService, + TestModelLoader(final CpsDataspaceService cpsDataspaceService, final CpsModuleService cpsModuleService, - final CpsDataService cpsDataService) { - super(cpsAdminService, cpsModuleService, cpsDataService) + final CpsDataService cpsDataService, + final CpsAnchorService cpsAnchorService) { + super(cpsDataspaceService, cpsModuleService, cpsDataService, cpsAnchorService) super.maximumAttemptCount = 2 super.retryTimeMs = 1 } 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 06627129a9..aed495ec45 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 @@ -20,12 +20,14 @@ package org.onap.cps.ncmp.init +import org.onap.cps.api.CpsAnchorService + import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.core.read.ListAppender -import org.onap.cps.api.CpsAdminService +import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.spi.model.Dataspace @@ -36,10 +38,11 @@ import spock.lang.Specification class CmDataSubscriptionModelLoaderSpec extends Specification { - def mockCpsAdminService = Mock(CpsAdminService) + def mockCpsDataspaceService = Mock(CpsDataspaceService) def mockCpsModuleService = Mock(CpsModuleService) def mockCpsDataService = Mock(CpsDataService) - def objectUnderTest = new CmDataSubscriptionModelLoader(mockCpsAdminService, mockCpsModuleService, mockCpsDataService) + def mockCpsAnchorService = Mock(CpsAnchorService) + def objectUnderTest = new CmDataSubscriptionModelLoader(mockCpsDataspaceService, mockCpsModuleService, mockCpsDataService, mockCpsAnchorService) def applicationContext = new AnnotationConfigApplicationContext() @@ -65,13 +68,13 @@ class CmDataSubscriptionModelLoaderSpec extends Specification { given:'model loader is enabled' objectUnderTest.subscriptionModelLoaderEnabled = true and: 'dataspace is ready for use' - mockCpsAdminService.getDataspace(NCMP_DATASPACE_NAME) >> new Dataspace('') + mockCpsDataspaceService.getDataspace(NCMP_DATASPACE_NAME) >> new Dataspace('') when: 'the application is ready' objectUnderTest.onApplicationEvent(Mock(ApplicationReadyEvent)) then: 'the module service to create schema set is called once' 1 * mockCpsModuleService.createSchemaSet(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', expectedYangResourcesToContentMap) and: 'the admin service to create an anchor set is called once' - 1 * mockCpsAdminService.createAnchor(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', 'cm-data-subscriptions') + 1 * mockCpsAnchorService.createAnchor(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', 'cm-data-subscriptions') and: 'the data service to create a top level datanode is called once' 1 * mockCpsDataService.saveData(NCMP_DATASPACE_NAME, 'cm-data-subscriptions', '{"datastores":{}}', _) } @@ -82,7 +85,7 @@ class CmDataSubscriptionModelLoaderSpec extends Specification { when: 'application is ready' objectUnderTest.onApplicationEvent(Mock(ApplicationReadyEvent)) then: 'no interaction with admin service' - 0 * mockCpsAdminService.getDataspace(_) + 0 * mockCpsDataspaceService.getDataspace(_) then: 'a message is logged that the function is disabled' def logs = loggingListAppender.list.toString() assert logs.contains('Subscription Model Loader is disabled') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy index 43e0f69b3f..5557993abd 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy @@ -20,13 +20,15 @@ package org.onap.cps.ncmp.init +import org.onap.cps.api.CpsAnchorService + import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.core.read.ListAppender -import org.onap.cps.api.CpsAdminService +import org.onap.cps.api.CpsDataspaceService import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.spi.model.Dataspace @@ -37,10 +39,11 @@ import spock.lang.Specification class InventoryModelLoaderSpec extends Specification { - def mockCpsAdminService = Mock(CpsAdminService) + def mockCpsAdminService = Mock(CpsDataspaceService) def mockCpsModuleService = Mock(CpsModuleService) def mockCpsDataService = Mock(CpsDataService) - def objectUnderTest = new InventoryModelLoader(mockCpsAdminService, mockCpsModuleService, mockCpsDataService) + def mockCpsAnchorService = Mock(CpsAnchorService) + def objectUnderTest = new InventoryModelLoader(mockCpsAdminService, mockCpsModuleService, mockCpsDataService, mockCpsAnchorService) def applicationContext = new AnnotationConfigApplicationContext() @@ -49,7 +52,7 @@ class InventoryModelLoaderSpec extends Specification { def loggingListAppender void setup() { - expectedYangResourceToContentMap = objectUnderTest.createYangResourcesToContentMap('dmi-registry@2023-08-23.yang') + expectedYangResourceToContentMap = objectUnderTest.createYangResourcesToContentMap('dmi-registry@2023-11-27.yang') logger.setLevel(Level.DEBUG) loggingListAppender = new ListAppender() logger.addAppender(loggingListAppender) @@ -68,9 +71,9 @@ class InventoryModelLoaderSpec extends Specification { when: 'the application is ready' objectUnderTest.onApplicationEvent(Mock(ApplicationReadyEvent)) then: 'the module service is used to create the new schema set from the correct resource' - 1 * mockCpsModuleService.createSchemaSet(NCMP_DATASPACE_NAME, 'dmi-registry-2023-08-23', expectedYangResourceToContentMap) + 1 * mockCpsModuleService.createSchemaSet(NCMP_DATASPACE_NAME, 'dmi-registry-2023-11-27', expectedYangResourceToContentMap) and: 'the admin service is used to update the anchor' - 1 * mockCpsAdminService.updateAnchorSchemaSet(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, 'dmi-registry-2023-08-23') + 1 * mockCpsAnchorService.updateAnchorSchemaSet(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, 'dmi-registry-2023-11-27') and: 'No schema sets are being removed by the module service (yet)' 0 * mockCpsModuleService.deleteSchemaSet(NCMP_DATASPACE_NAME, _, _) } |