summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-application/src/main/resources/application.yml4
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy3
-rw-r--r--cps-ncmp-service/pom.xml4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java57
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java48
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/AbstractModelLoader.java12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoader.java10
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java14
-rw-r--r--cps-ncmp-service/src/main/resources/models/dmi-registry@2023-11-27.yang (renamed from integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2022-05-10.yang)25
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy10
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy48
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy18
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy12
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy13
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/AbstractModelLoaderSpec.groovy25
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/CmDataSubscriptionModelLoaderSpec.groovy15
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/init/InventoryModelLoaderSpec.groovy15
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java26
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy44
-rw-r--r--cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy10
-rw-r--r--[-rwxr-xr-x]cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java (renamed from cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java)45
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsDataspaceService.java66
-rw-r--r--[-rwxr-xr-x]cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java (renamed from cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java)56
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java62
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java64
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java12
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java108
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/KafkaProducerListener.java52
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationErrorHandler.java40
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationProperties.java43
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationPublisher.java66
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationService.java124
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/Operation.java27
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java6
-rw-r--r--[-rwxr-xr-x]cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy (renamed from cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy)60
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy72
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy67
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy21
-rwxr-xr-xcps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy17
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/config/AsyncConfigSpec.groovy46
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdatedEventFactorySpec.groovy142
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/KafkaPublisherSpecBase.groovy93
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/KafkaTestContainerConfig.groovy49
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationErrorHandlerSpec.groovy60
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationPublisherSpec.groovy91
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy158
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy8
-rw-r--r--docker-compose/README.md2
-rw-r--r--docker-compose/docker-compose.yml2
-rw-r--r--docs/deployment.rst3
-rwxr-xr-xdocs/release-notes.rst1
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy25
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy10
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy6
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy (renamed from integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy)73
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy4
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataspaceServiceIntegrationSpec.groovy107
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy15
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpPerfTestBase.groovy8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy4
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataspaceServiceLimitsPerfTest.groovy (renamed from integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimitsPerfTest.groovy)8
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy8
-rw-r--r--integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2023-11-27.yang (renamed from cps-ncmp-service/src/main/resources/models/dmi-registry@2023-08-23.yang)9
67 files changed, 802 insertions, 1573 deletions
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index 89969b9c6a..8dafdec11a 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -114,10 +114,6 @@ app:
notification:
enabled: true
- data-updated:
- topic: ${CPS_CHANGE_EVENT_TOPIC:cps.data-updated-events}
- filters:
- enabled-dataspaces: ${NOTIFICATION_DATASPACE_FILTER_PATTERNS:""}
async:
executor:
core-pool-size: 2
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
index 870c36c777..55590168d9 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/executor/CpsNcmpTaskExecutorSpec.groovy
@@ -26,7 +26,6 @@ import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.read.ListAppender
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
-import org.onap.cps.notification.NotificationErrorHandler
import org.slf4j.LoggerFactory
import spock.lang.Specification
@@ -44,7 +43,7 @@ class CpsNcmpTaskExecutorSpec extends Specification {
@AfterEach
void teardown() {
- ((Logger) LoggerFactory.getLogger(NotificationErrorHandler.class)).detachAndStopAllAppenders();
+ ((Logger) LoggerFactory.getLogger(CpsNcmpTaskExecutor.class)).detachAndStopAllAppenders();
}
def 'Execute successful task.'() {
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index f448c8f47c..e9faf43498 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -42,6 +42,10 @@
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.httpcomponents.client5</groupId>
+ <artifactId>httpclient5</artifactId>
+ </dependency>
+ <dependency>
<groupId>io.cloudevents</groupId>
<artifactId>cloudevents-json-jackson</artifactId>
</dependency>
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/integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2022-05-10.yang b/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-11-27.yang
index 77517968c6..808bbdd1bc 100644
--- a/integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2022-05-10.yang
+++ b/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-11-27.yang
@@ -8,19 +8,29 @@ module dmi-registry {
contact "toine.siebelink@est.tech";
+ revision "2023-11-27" {
+ description
+ "Added alternate-id";
+ }
+
+ revision "2023-08-23" {
+ description
+ "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" {
@@ -75,6 +85,12 @@ module dmi-registry {
leaf dmi-model-service-name {
type string;
}
+ leaf module-set-tag {
+ type string;
+ }
+ leaf alternate-id {
+ type string;
+ }
list additional-properties {
key "name";
@@ -120,4 +136,5 @@ module dmi-registry {
}
}
}
-} \ No newline at end of file
+}
+
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, _, _)
}
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
index 993dad58c3..9b78f85201 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/AdminRestController.java
@@ -33,7 +33,8 @@ import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.api.CpsAdminService;
+import org.onap.cps.api.CpsAnchorService;
+import org.onap.cps.api.CpsDataspaceService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.rest.api.CpsAdminApi;
import org.onap.cps.rest.model.AnchorDetails;
@@ -53,9 +54,10 @@ import org.springframework.web.multipart.MultipartFile;
@RequiredArgsConstructor
public class AdminRestController implements CpsAdminApi {
- private final CpsAdminService cpsAdminService;
+ private final CpsDataspaceService cpsDataspaceService;
private final CpsModuleService cpsModuleService;
private final CpsRestInputMapper cpsRestInputMapper;
+ private final CpsAnchorService cpsAnchorService;
/**
* Create a dataspace.
@@ -65,7 +67,7 @@ public class AdminRestController implements CpsAdminApi {
*/
@Override
public ResponseEntity<String> createDataspace(@NotNull @Valid final String dataspaceName) {
- cpsAdminService.createDataspace(dataspaceName);
+ cpsDataspaceService.createDataspace(dataspaceName);
return new ResponseEntity<>(dataspaceName, HttpStatus.CREATED);
}
@@ -77,7 +79,7 @@ public class AdminRestController implements CpsAdminApi {
*/
@Override
public ResponseEntity<Void> createDataspaceV2(@NotNull @Valid final String dataspaceName) {
- cpsAdminService.createDataspace(dataspaceName);
+ cpsDataspaceService.createDataspace(dataspaceName);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -89,7 +91,7 @@ public class AdminRestController implements CpsAdminApi {
*/
@Override
public ResponseEntity<Void> deleteDataspace(final String apiVersion, final String dataspaceName) {
- cpsAdminService.deleteDataspace(dataspaceName);
+ cpsDataspaceService.deleteDataspace(dataspaceName);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@@ -184,7 +186,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<String> createAnchor(final String dataspaceName, @NotNull @Valid final String schemaSetName,
@NotNull @Valid final String anchorName) {
- cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName);
+ cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName);
return new ResponseEntity<>(anchorName, HttpStatus.CREATED);
}
@@ -199,7 +201,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<Void> createAnchorV2(final String dataspaceName, @NotNull @Valid final String schemaSetName,
@NotNull @Valid final String anchorName) {
- cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName);
+ cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -214,7 +216,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<Void> deleteAnchor(final String apiVersion,
final String dataspaceName, final String anchorName) {
- cpsAdminService.deleteAnchor(dataspaceName, anchorName);
+ cpsAnchorService.deleteAnchor(dataspaceName, anchorName);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@@ -229,7 +231,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<AnchorDetails> getAnchor(final String apiVersion,
final String dataspaceName, final String anchorName) {
- final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final var anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final var anchorDetails = cpsRestInputMapper.toAnchorDetails(anchor);
return new ResponseEntity<>(anchorDetails, HttpStatus.OK);
}
@@ -244,7 +246,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<List<AnchorDetails>> getAnchors(final String apiVersion,
final String dataspaceName) {
- final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName);
+ final Collection<Anchor> anchors = cpsAnchorService.getAnchors(dataspaceName);
final List<AnchorDetails> anchorDetails = anchors.stream().map(cpsRestInputMapper::toAnchorDetails)
.collect(Collectors.toList());
return new ResponseEntity<>(anchorDetails, HttpStatus.OK);
@@ -252,7 +254,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<List<DataspaceDetails>> getAllDataspaces(final String apiVersion) {
- final Collection<Dataspace> dataspaces = cpsAdminService.getAllDataspaces();
+ final Collection<Dataspace> dataspaces = cpsDataspaceService.getAllDataspaces();
final List<DataspaceDetails> dataspaceDetails = dataspaces.stream().map(cpsRestInputMapper::toDataspaceDetails)
.collect(Collectors.toList());
return new ResponseEntity<>(dataspaceDetails, HttpStatus.OK);
@@ -260,7 +262,7 @@ public class AdminRestController implements CpsAdminApi {
@Override
public ResponseEntity<DataspaceDetails> getDataspace(final String apiVersion, final String dataspaceName) {
- final Dataspace dataspace = cpsAdminService.getDataspace(dataspaceName);
+ final Dataspace dataspace = cpsDataspaceService.getDataspace(dataspaceName);
final DataspaceDetails dataspaceDetails = cpsRestInputMapper.toDataspaceDetails(dataspace);
return new ResponseEntity<>(dataspaceDetails, HttpStatus.OK);
}
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
index f81efd6698..81ac511a9f 100755
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/AdminRestControllerSpec.groovy
@@ -23,6 +23,8 @@
package org.onap.cps.rest.controller
+import org.onap.cps.api.CpsAnchorService
+
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
@@ -30,7 +32,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.mapstruct.factory.Mappers
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsDataspaceService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.spi.exceptions.AlreadyDefinedException
import org.onap.cps.spi.exceptions.SchemaSetInUseException
@@ -56,7 +58,10 @@ class AdminRestControllerSpec extends Specification {
CpsModuleService mockCpsModuleService = Mock()
@SpringBean
- CpsAdminService mockCpsAdminService = Mock()
+ CpsDataspaceService mockCpsDataspaceService = Mock()
+
+ @SpringBean
+ CpsAnchorService mockCpsAnchorService = Mock()
@SpringBean
CpsRestInputMapper cpsRestInputMapper = Mappers.getMapper(CpsRestInputMapper)
@@ -76,26 +81,27 @@ class AdminRestControllerSpec extends Specification {
def 'Create new dataspace with #scenario.'() {
when: 'post is invoked'
def response =
- mvc.perform(
- post("/cps/api/${apiVersion}/dataspaces")
- .param('dataspace-name', dataspaceName))
- .andReturn().response
+ mvc.perform(
+ post("/cps/api/${apiVersion}/dataspaces")
+ .param('dataspace-name', dataspaceName))
+ .andReturn().response
then: 'service method is invoked with expected parameters'
- 1 * mockCpsAdminService.createDataspace(dataspaceName)
+ 1 * mockCpsDataspaceService.createDataspace(dataspaceName)
and: 'dataspace is create successfully'
response.status == HttpStatus.CREATED.value()
assert response.getContentAsString() == expectedResponseBody
where: 'following cases are tested'
- scenario | apiVersion || expectedResponseBody
- 'V1 API' | 'v1' || 'my_dataspace'
- 'V2 API' | 'v2' || ''
- }
+ scenario | apiVersion || expectedResponseBody
+ 'V1 API' | 'v1' || 'my_dataspace'
+ 'V2 API' | 'v2' || ''
+ }
+
def 'Create dataspace over existing with same name.'() {
given: 'an endpoint'
def createDataspaceEndpoint = "$basePath/v1/dataspaces"
and: 'the service method throws an exception indicating the dataspace is already defined'
def thrownException = new AlreadyDefinedException(dataspaceName, new RuntimeException())
- mockCpsAdminService.createDataspace(dataspaceName) >> { throw thrownException }
+ mockCpsDataspaceService.createDataspace(dataspaceName) >> { throw thrownException }
when: 'post is invoked'
def response =
mvc.perform(
@@ -108,7 +114,7 @@ class AdminRestControllerSpec extends Specification {
def 'Get a dataspace.'() {
given: 'service method returns a dataspace'
- mockCpsAdminService.getDataspace(dataspaceName) >> dataspace
+ mockCpsDataspaceService.getDataspace(dataspaceName) >> dataspace
and: 'an endpoint'
def getDataspaceEndpoint = "$basePath/v1/admin/dataspaces/$dataspaceName"
when: 'get dataspace API is invoked'
@@ -120,7 +126,7 @@ class AdminRestControllerSpec extends Specification {
def 'Get all dataspaces.'() {
given: 'service method returns all dataspace'
- mockCpsAdminService.getAllDataspaces() >> [dataspace, new Dataspace(name: "dataspace-test2")]
+ mockCpsDataspaceService.getAllDataspaces() >> [dataspace, new Dataspace(name: "dataspace-test2")]
and: 'an endpoint'
def getAllDataspaceEndpoint = "$basePath/v1/admin/dataspaces"
when: 'get all dataspace API is invoked'
@@ -317,7 +323,7 @@ class AdminRestControllerSpec extends Specification {
.params(requestParams as MultiValueMap))
.andReturn().response
then: 'anchor is created successfully'
- 1 * mockCpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorName)
+ 1 * mockCpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorName)
assert response.status == HttpStatus.CREATED.value()
assert response.getContentAsString() == expectedResponseBody
where: 'following cases are tested'
@@ -328,7 +334,7 @@ class AdminRestControllerSpec extends Specification {
def 'Get existing anchor.'() {
given: 'service method returns a list of anchors'
- mockCpsAdminService.getAnchors(dataspaceName) >> [anchor]
+ mockCpsAnchorService.getAnchors(dataspaceName) >> [anchor]
and: 'an endpoint'
def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors"
when: 'get all anchors API is invoked'
@@ -340,7 +346,7 @@ class AdminRestControllerSpec extends Specification {
def 'Get existing anchor by dataspace and anchor name.'() {
given: 'service method returns an anchor'
- mockCpsAdminService.getAnchor(dataspaceName, anchorName) >>
+ mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >>
new Anchor(name: anchorName, dataspaceName: dataspaceName, schemaSetName: schemaSetName)
and: 'an endpoint'
def anchorEndpoint = "$basePath/v1/dataspaces/$dataspaceName/anchors/$anchorName"
@@ -360,7 +366,7 @@ class AdminRestControllerSpec extends Specification {
when: 'delete method is invoked on anchor endpoint'
def response = mvc.perform(delete(anchorEndpoint)).andReturn().response
then: 'associated service method is invoked with expected parameters'
- 1 * mockCpsAdminService.deleteAnchor(dataspaceName, anchorName)
+ 1 * mockCpsAnchorService.deleteAnchor(dataspaceName, anchorName)
and: 'response code indicates success'
response.status == HttpStatus.NO_CONTENT.value()
}
@@ -373,7 +379,7 @@ class AdminRestControllerSpec extends Specification {
.param('dataspace-name', dataspaceName))
.andReturn().response
then: 'associated service method is invoked with expected parameter'
- 1 * mockCpsAdminService.deleteDataspace(dataspaceName)
+ 1 * mockCpsDataspaceService.deleteDataspace(dataspaceName)
and: 'response code indicates success'
response.status == HttpStatus.NO_CONTENT.value()
}
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
index 535b83df76..ff2bed4347 100644
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
@@ -26,7 +26,8 @@ package org.onap.cps.rest.exceptions
import com.fasterxml.jackson.databind.ObjectMapper
import groovy.json.JsonSlurper
-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.api.CpsQueryService
@@ -63,7 +64,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
class CpsRestExceptionHandlerSpec extends Specification {
@SpringBean
- CpsAdminService mockCpsAdminService = Stub()
+ CpsDataspaceService mockCpsAdminService = Stub()
+
+ @SpringBean
+ CpsAnchorService mockCpsAnchorService = Stub()
@SpringBean
CpsModuleService mockCpsModuleService = Stub()
@@ -198,7 +202,7 @@ class CpsRestExceptionHandlerSpec extends Specification {
*/
def setupTestException(exception) {
- mockCpsAdminService.getAnchors(_) >> { throw exception }
+ mockCpsAnchorService.getAnchors(_) >> { throw exception }
}
def performTestRequest() {
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java
index edd052a51c..a247150c15 100755..100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsAnchorService.java
@@ -1,9 +1,6 @@
/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
- * Modifications Copyright (C) 2020-2022 Bell Canada.
- * Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2022 TechMahindra Ltd.
+ * ============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.
@@ -24,46 +21,10 @@
package org.onap.cps.api;
import java.util.Collection;
-import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.spi.model.Anchor;
-import org.onap.cps.spi.model.Dataspace;
-/**
- * CPS Admin Service.
- */
-public interface CpsAdminService {
-
- /**
- * Create dataspace.
- *
- * @param dataspaceName dataspace name
- * @throws AlreadyDefinedException if dataspace with same name already exists
- */
- void createDataspace(String dataspaceName);
-
- /**
- * Delete dataspace.
- *
- * @param dataspaceName the name of the dataspace to delete
- */
- void deleteDataspace(String dataspaceName);
-
- /**
- * Get dataspace by given dataspace name.
- *
- * @param dataspaceName dataspace name
- * @return a dataspace
- */
- Dataspace getDataspace(String dataspaceName);
-
- /**
- * Get All Dataspaces.
- *
- *
- * @return a collection of dataspaces
- */
- Collection<Dataspace> getAllDataspaces();
+public interface CpsAnchorService {
/**
* Create an Anchor.
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataspaceService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataspaceService.java
new file mode 100644
index 0000000000..7b94604261
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataspaceService.java
@@ -0,0 +1,66 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
+ * Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2022 TechMahindra Ltd.
+ * ================================================================================
+ * 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.api;
+
+import java.util.Collection;
+import org.onap.cps.spi.exceptions.AlreadyDefinedException;
+import org.onap.cps.spi.model.Dataspace;
+
+/**
+ * CPS Admin Service.
+ */
+public interface CpsDataspaceService {
+
+ /**
+ * Create dataspace.
+ *
+ * @param dataspaceName dataspace name
+ * @throws AlreadyDefinedException if dataspace with same name already exists
+ */
+ void createDataspace(String dataspaceName);
+
+ /**
+ * Delete dataspace.
+ *
+ * @param dataspaceName the name of the dataspace to delete
+ */
+ void deleteDataspace(String dataspaceName);
+
+ /**
+ * Get dataspace by given dataspace name.
+ *
+ * @param dataspaceName dataspace name
+ * @return a dataspace
+ */
+ Dataspace getDataspace(String dataspaceName);
+
+ /**
+ * Get All Dataspaces.
+ *
+ *
+ * @return a collection of dataspaces
+ */
+ Collection<Dataspace> getAllDataspaces();
+
+}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java
index d83ee434de..f09a795a66 100755..100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAnchorServiceImpl.java
@@ -1,9 +1,6 @@
/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
- * Modifications Copyright (C) 2020-2022 Bell Canada.
- * Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2022 TechMahindra Ltd.
+ * ============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.
@@ -23,52 +20,25 @@
package org.onap.cps.api.impl;
-import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.api.CpsAdminService;
-import org.onap.cps.api.CpsDataService;
+import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.spi.CpsAdminPersistenceService;
+import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.model.Anchor;
-import org.onap.cps.spi.model.Dataspace;
import org.onap.cps.spi.utils.CpsValidator;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
-@Component("CpsAdminServiceImpl")
-@RequiredArgsConstructor(onConstructor = @__(@Lazy))
-public class CpsAdminServiceImpl implements CpsAdminService {
+@Service
+@RequiredArgsConstructor
+public class CpsAnchorServiceImpl implements CpsAnchorService {
private final CpsAdminPersistenceService cpsAdminPersistenceService;
- @Lazy
- private final CpsDataService cpsDataService;
+ private final CpsDataPersistenceService cpsDataPersistenceService;
private final CpsValidator cpsValidator;
@Override
- public void createDataspace(final String dataspaceName) {
- cpsValidator.validateNameCharacters(dataspaceName);
- cpsAdminPersistenceService.createDataspace(dataspaceName);
- }
-
- @Override
- public void deleteDataspace(final String dataspaceName) {
- cpsValidator.validateNameCharacters(dataspaceName);
- cpsAdminPersistenceService.deleteDataspace(dataspaceName);
- }
-
- @Override
- public Dataspace getDataspace(final String dataspaceName) {
- cpsValidator.validateNameCharacters(dataspaceName);
- return cpsAdminPersistenceService.getDataspace(dataspaceName);
- }
-
- @Override
- public Collection<Dataspace> getAllDataspaces() {
- return cpsAdminPersistenceService.getAllDataspaces();
- }
-
- @Override
public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
cpsValidator.validateNameCharacters(dataspaceName, schemaSetName, anchorName);
cpsAdminPersistenceService.createAnchor(dataspaceName, schemaSetName, anchorName);
@@ -102,7 +72,7 @@ public class CpsAdminServiceImpl implements CpsAdminService {
@Override
public void deleteAnchor(final String dataspaceName, final String anchorName) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- cpsDataService.deleteDataNodes(dataspaceName, anchorName, OffsetDateTime.now());
+ cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName);
cpsAdminPersistenceService.deleteAnchor(dataspaceName, anchorName);
}
@@ -110,7 +80,7 @@ public class CpsAdminServiceImpl implements CpsAdminService {
public void deleteAnchors(final String dataspaceName, final Collection<String> anchorNames) {
cpsValidator.validateNameCharacters(dataspaceName);
cpsValidator.validateNameCharacters(anchorNames);
- cpsDataService.deleteDataNodes(dataspaceName, anchorNames, OffsetDateTime.now());
+ cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorNames);
cpsAdminPersistenceService.deleteAnchors(dataspaceName, anchorNames);
}
@@ -123,8 +93,8 @@ public class CpsAdminServiceImpl implements CpsAdminService {
@Override
public void updateAnchorSchemaSet(final String dataspaceName,
- final String anchorName,
- final String schemaSetName) {
+ final String anchorName,
+ final String schemaSetName) {
cpsAdminPersistenceService.updateAnchorSchemaSet(dataspaceName, anchorName, schemaSetName);
}
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index e74e0ad249..a1bae6a441 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -24,10 +24,6 @@
package org.onap.cps.api.impl;
-import static org.onap.cps.notification.Operation.CREATE;
-import static org.onap.cps.notification.Operation.DELETE;
-import static org.onap.cps.notification.Operation.UPDATE;
-
import io.micrometer.core.annotation.Timed;
import java.io.Serializable;
import java.time.OffsetDateTime;
@@ -39,12 +35,10 @@ import java.util.Map;
import java.util.stream.Collectors;
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.CpsDeltaService;
import org.onap.cps.cpspath.parser.CpsPathUtil;
-import org.onap.cps.notification.NotificationService;
-import org.onap.cps.notification.Operation;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataValidationException;
@@ -68,9 +62,8 @@ public class CpsDataServiceImpl implements CpsDataService {
private static final long DEFAULT_LOCK_TIMEOUT_IN_MILLISECONDS = 300L;
private final CpsDataPersistenceService cpsDataPersistenceService;
- private final CpsAdminService cpsAdminService;
+ private final CpsAnchorService cpsAnchorService;
private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
- private final NotificationService notificationService;
private final CpsValidator cpsValidator;
private final TimedYangParser timedYangParser;
private final CpsDeltaService cpsDeltaService;
@@ -87,10 +80,9 @@ public class CpsDataServiceImpl implements CpsDataService {
public void saveData(final String dataspaceName, final String anchorName, final String nodeData,
final OffsetDateTime observedTimestamp, final ContentType contentType) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodes = buildDataNodes(anchor, ROOT_NODE_XPATH, nodeData, contentType);
cpsDataPersistenceService.storeDataNodes(dataspaceName, anchorName, dataNodes);
- processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, CREATE, observedTimestamp);
}
@Override
@@ -106,10 +98,9 @@ public class CpsDataServiceImpl implements CpsDataService {
final String nodeData, final OffsetDateTime observedTimestamp,
final ContentType contentType) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodes = buildDataNodes(anchor, parentNodeXpath, nodeData, contentType);
cpsDataPersistenceService.addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, dataNodes);
- processDataUpdatedEventAsync(anchor, parentNodeXpath, CREATE, observedTimestamp);
}
@Override
@@ -118,7 +109,7 @@ public class CpsDataServiceImpl implements CpsDataService {
public void saveListElements(final String dataspaceName, final String anchorName,
final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> listElementDataNodeCollection =
buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON);
if (isRootNodeXpath(parentNodeXpath)) {
@@ -127,7 +118,6 @@ public class CpsDataServiceImpl implements CpsDataService {
cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath,
listElementDataNodeCollection);
}
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -136,12 +126,11 @@ public class CpsDataServiceImpl implements CpsDataService {
public void saveListElementsBatch(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final Collection<String> jsonDataList, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<Collection<DataNode>> listElementDataNodeCollections =
buildDataNodes(anchor, parentNodeXpath, jsonDataList, ContentType.JSON);
cpsDataPersistenceService.addMultipleLists(dataspaceName, anchorName, parentNodeXpath,
listElementDataNodeCollections);
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -171,13 +160,12 @@ public class CpsDataServiceImpl implements CpsDataService {
public void updateNodeLeaves(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodesInPatch = buildDataNodes(anchor, parentNodeXpath, jsonData,
ContentType.JSON);
final Map<String, Map<String, Serializable>> xpathToUpdatedLeaves = dataNodesInPatch.stream()
.collect(Collectors.toMap(DataNode::getXpath, DataNode::getLeaves));
cpsDataPersistenceService.batchUpdateDataLeaves(dataspaceName, anchorName, xpathToUpdatedLeaves);
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -188,13 +176,12 @@ public class CpsDataServiceImpl implements CpsDataService {
final String dataNodeUpdatesAsJson,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodeUpdates =
buildDataNodes(anchor, parentNodeXpath, dataNodeUpdatesAsJson, ContentType.JSON);
for (final DataNode dataNodeUpdate : dataNodeUpdates) {
processDataNodeUpdate(anchor, dataNodeUpdate);
}
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -241,10 +228,9 @@ public class CpsDataServiceImpl implements CpsDataService {
final String parentNodeXpath, final String jsonData,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodes = buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON);
cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes);
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -254,11 +240,9 @@ public class CpsDataServiceImpl implements CpsDataService {
final Map<String, String> nodesJsonData,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> dataNodes = buildDataNodes(anchor, nodesJsonData);
cpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName, dataNodes);
- nodesJsonData.keySet().forEach(nodeXpath ->
- processDataUpdatedEventAsync(anchor, nodeXpath, UPDATE, observedTimestamp));
}
@Override
@@ -267,7 +251,7 @@ public class CpsDataServiceImpl implements CpsDataService {
public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
final Collection<DataNode> newListElements =
buildDataNodes(anchor, parentNodeXpath, jsonData, ContentType.JSON);
replaceListContent(dataspaceName, anchorName, parentNodeXpath, newListElements, observedTimestamp);
@@ -279,9 +263,7 @@ public class CpsDataServiceImpl implements CpsDataService {
public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final Collection<DataNode> dataNodes, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
cpsDataPersistenceService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, dataNodes);
- processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
}
@Override
@@ -290,9 +272,7 @@ public class CpsDataServiceImpl implements CpsDataService {
public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
cpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath);
- processDataUpdatedEventAsync(anchor, dataNodeXpath, DELETE, observedTimestamp);
}
@Override
@@ -302,9 +282,6 @@ public class CpsDataServiceImpl implements CpsDataService {
final Collection<String> dataNodeXpaths, final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName, dataNodeXpaths);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
- dataNodeXpaths.forEach(dataNodeXpath ->
- processDataUpdatedEventAsync(anchor, dataNodeXpath, DELETE, observedTimestamp));
}
@Override
@@ -313,8 +290,6 @@ public class CpsDataServiceImpl implements CpsDataService {
public void deleteDataNodes(final String dataspaceName, final String anchorName,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
- processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, DELETE, observedTimestamp);
cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName);
}
@@ -325,9 +300,6 @@ public class CpsDataServiceImpl implements CpsDataService {
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName);
cpsValidator.validateNameCharacters(anchorNames);
- for (final Anchor anchor : cpsAdminService.getAnchors(dataspaceName, anchorNames)) {
- processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, DELETE, observedTimestamp);
- }
cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorNames);
}
@@ -337,9 +309,7 @@ public class CpsDataServiceImpl implements CpsDataService {
public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath,
final OffsetDateTime observedTimestamp) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
cpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, listNodeXpath);
- processDataUpdatedEventAsync(anchor, listNodeXpath, DELETE, observedTimestamp);
}
private Collection<DataNode> buildDataNodes(final Anchor anchor, final Map<String, String> nodesJsonData) {
@@ -385,16 +355,6 @@ public class CpsDataServiceImpl implements CpsDataService {
.collect(Collectors.toList());
}
- private void processDataUpdatedEventAsync(final Anchor anchor, final String xpath,
- final Operation operation, final OffsetDateTime observedTimestamp) {
- try {
- notificationService.processDataUpdatedEvent(anchor, xpath, operation, observedTimestamp);
- } catch (final Exception exception) {
- //If async message can't be queued for notification service, the initial request should not fail.
- log.error("Failed to send message to notification service", exception);
- }
- }
-
private SchemaContext getSchemaContext(final Anchor anchor) {
return yangTextSchemaSourceSetCache
.get(anchor.getDataspaceName(), anchor.getSchemaSetName()).getSchemaContext();
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java
new file mode 100644
index 0000000000..a7f5da4874
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataspaceServiceImpl.java
@@ -0,0 +1,64 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2020-2023 Nordix Foundation
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
+ * Modifications Copyright (C) 2021 Pantheon.tech
+ * Modifications Copyright (C) 2022 TechMahindra Ltd.
+ * ================================================================================
+ * 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.api.impl;
+
+import java.util.Collection;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.api.CpsDataspaceService;
+import org.onap.cps.spi.CpsAdminPersistenceService;
+import org.onap.cps.spi.model.Dataspace;
+import org.onap.cps.spi.utils.CpsValidator;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class CpsDataspaceServiceImpl implements CpsDataspaceService {
+
+ private final CpsAdminPersistenceService cpsAdminPersistenceService;
+ private final CpsValidator cpsValidator;
+
+ @Override
+ public void createDataspace(final String dataspaceName) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ cpsAdminPersistenceService.createDataspace(dataspaceName);
+ }
+
+ @Override
+ public void deleteDataspace(final String dataspaceName) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ cpsAdminPersistenceService.deleteDataspace(dataspaceName);
+ }
+
+ @Override
+ public Dataspace getDataspace(final String dataspaceName) {
+ cpsValidator.validateNameCharacters(dataspaceName);
+ return cpsAdminPersistenceService.getDataspace(dataspaceName);
+ }
+
+ @Override
+ public Collection<Dataspace> getAllDataspaces() {
+ return cpsAdminPersistenceService.getAllDataspaces();
+ }
+
+}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index 5337237846..61a4e623af 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -28,7 +28,7 @@ import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.api.CpsAdminService;
+import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.CpsModulePersistenceService;
@@ -49,7 +49,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
private final CpsModulePersistenceService cpsModulePersistenceService;
private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
- private final CpsAdminService cpsAdminService;
+ private final CpsAnchorService cpsAnchorService;
private final CpsValidator cpsValidator;
private final TimedYangTextSchemaSourceSetBuilder timedYangTextSchemaSourceSetBuilder;
@@ -97,12 +97,12 @@ public class CpsModuleServiceImpl implements CpsModuleService {
public void deleteSchemaSet(final String dataspaceName, final String schemaSetName,
final CascadeDeleteAllowed cascadeDeleteAllowed) {
cpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
- final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName, schemaSetName);
+ final Collection<Anchor> anchors = cpsAnchorService.getAnchors(dataspaceName, schemaSetName);
if (!anchors.isEmpty() && isCascadeDeleteProhibited(cascadeDeleteAllowed)) {
throw new SchemaSetInUseException(dataspaceName, schemaSetName);
}
for (final Anchor anchor : anchors) {
- cpsAdminService.deleteAnchor(dataspaceName, anchor.getName());
+ cpsAnchorService.deleteAnchor(dataspaceName, anchor.getName());
}
cpsModulePersistenceService.deleteSchemaSet(dataspaceName, schemaSetName);
yangTextSchemaSourceSetCache.removeFromCache(dataspaceName, schemaSetName);
@@ -114,9 +114,9 @@ public class CpsModuleServiceImpl implements CpsModuleService {
public void deleteSchemaSetsWithCascade(final String dataspaceName, final Collection<String> schemaSetNames) {
cpsValidator.validateNameCharacters(dataspaceName);
cpsValidator.validateNameCharacters(schemaSetNames);
- final Collection<String> anchorNames = cpsAdminService.getAnchors(dataspaceName, schemaSetNames)
+ final Collection<String> anchorNames = cpsAnchorService.getAnchors(dataspaceName, schemaSetNames)
.stream().map(Anchor::getName).collect(Collectors.toSet());
- cpsAdminService.deleteAnchors(dataspaceName, anchorNames);
+ cpsAnchorService.deleteAnchors(dataspaceName, anchorNames);
cpsModulePersistenceService.deleteUnusedYangResourceModules();
cpsModulePersistenceService.deleteSchemaSets(dataspaceName, schemaSetNames);
for (final String schemaSetName : schemaSetNames) {
diff --git a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java b/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java
deleted file mode 100644
index 696fd60f8c..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021-2022 Bell Canada.
- * Modifications Copyright (c) 2022-2023 Nordix Foundation
- * Modifications Copyright (C) 2023 TechMahindra Ltd.
- * ================================================================================
- * 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.notification;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.OffsetDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.UUID;
-import lombok.AllArgsConstructor;
-import lombok.SneakyThrows;
-import org.onap.cps.api.CpsDataService;
-import org.onap.cps.event.model.Content;
-import org.onap.cps.event.model.CpsDataUpdatedEvent;
-import org.onap.cps.event.model.Data;
-import org.onap.cps.spi.FetchDescendantsOption;
-import org.onap.cps.spi.model.Anchor;
-import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.utils.DataMapUtils;
-import org.onap.cps.utils.PrefixResolver;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-@Component
-@AllArgsConstructor(onConstructor = @__(@Lazy))
-public class CpsDataUpdatedEventFactory {
-
- private static final DateTimeFormatter DATE_TIME_FORMATTER =
- DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
-
- @Lazy
- private final CpsDataService cpsDataService;
-
- @Lazy
- private final PrefixResolver prefixResolver;
-
- /**
- * Generates CPS Data Updated event. If observedTimestamp is not provided, then current timestamp is used.
- *
- * @param anchor anchor
- * @param observedTimestamp observedTimestamp
- * @param operation operation
- * @return CpsDataUpdatedEvent
- */
- public CpsDataUpdatedEvent createCpsDataUpdatedEvent(final Anchor anchor,
- final OffsetDateTime observedTimestamp, final Operation operation) {
- final var dataNode = (operation == Operation.DELETE) ? null :
- cpsDataService.getDataNodes(anchor.getDataspaceName(), anchor.getName(),
- "/", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).iterator().next();
- return toCpsDataUpdatedEvent(anchor, dataNode, observedTimestamp, operation);
- }
-
- @SneakyThrows(URISyntaxException.class)
- private CpsDataUpdatedEvent toCpsDataUpdatedEvent(final Anchor anchor,
- final DataNode dataNode,
- final OffsetDateTime observedTimestamp,
- final Operation operation) {
- final CpsDataUpdatedEvent cpsDataUpdatedEvent = new CpsDataUpdatedEvent();
- cpsDataUpdatedEvent.withContent(createContent(anchor, dataNode, observedTimestamp, operation));
- cpsDataUpdatedEvent.withId(UUID.randomUUID().toString());
- cpsDataUpdatedEvent.withSchema(new URI("urn:cps:org.onap.cps:data-updated-event-schema:v1"));
- cpsDataUpdatedEvent.withSource(new URI("urn:cps:org.onap.cps"));
- cpsDataUpdatedEvent.withType("org.onap.cps.data-updated-event");
- return cpsDataUpdatedEvent;
- }
-
- private Data createData(final DataNode dataNode, final String prefix) {
- final Data data = new Data();
- DataMapUtils.toDataMapWithIdentifier(dataNode, prefix).forEach(data::setAdditionalProperty);
- return data;
- }
-
- private Content createContent(final Anchor anchor, final DataNode dataNode,
- final OffsetDateTime observedTimestamp, final Operation operation) {
- final var content = new Content();
- content.withAnchorName(anchor.getName());
- content.withDataspaceName(anchor.getDataspaceName());
- content.withSchemaSetName(anchor.getSchemaSetName());
- content.withOperation(Content.Operation.fromValue(operation.name()));
- content.withObservedTimestamp(
- DATE_TIME_FORMATTER.format(observedTimestamp == null ? OffsetDateTime.now() : observedTimestamp));
- if (dataNode != null) {
- final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath());
- content.withData(createData(dataNode, prefix));
- }
- return content;
- }
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/KafkaProducerListener.java b/cps-service/src/main/java/org/onap/cps/notification/KafkaProducerListener.java
deleted file mode 100644
index f4b68c0699..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/KafkaProducerListener.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * ================================================================================
- * 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.notification;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.kafka.clients.producer.ProducerRecord;
-import org.apache.kafka.clients.producer.RecordMetadata;
-import org.springframework.kafka.support.ProducerListener;
-import org.springframework.stereotype.Component;
-
-@Slf4j
-@Component
-public class KafkaProducerListener<K, V> implements ProducerListener<K, V> {
-
- private NotificationErrorHandler notificationErrorHandler;
-
- public KafkaProducerListener(final NotificationErrorHandler notificationErrorHandler) {
- this.notificationErrorHandler = notificationErrorHandler;
- }
-
- @Override
- public void onSuccess(final ProducerRecord<K, V> producerRecord, final RecordMetadata recordMetadata) {
- log.debug("Message sent to event-bus topic :'{}' with body : {} ", producerRecord.topic(),
- producerRecord.value());
- }
-
- @Override
- public void onError(final ProducerRecord<K, V> producerRecord,
- final RecordMetadata recordMetadata,
- final Exception exception) {
- notificationErrorHandler.onException("Failed to send message to message bus",
- exception, producerRecord, recordMetadata);
- }
-
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationErrorHandler.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationErrorHandler.java
deleted file mode 100644
index eef028d5f3..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationErrorHandler.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * ================================================================================
- * 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.notification;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-public class NotificationErrorHandler {
-
- void onException(final Exception exception, final Object... context) {
- onException("Failed to process", exception, context);
- }
-
- void onException(final String message, final Exception exception, final Object... context) {
- log.error("{} \n Error cause: {} \n Error context: {}",
- message,
- exception.getCause() != null ? exception.getCause().toString() : exception.getMessage(),
- context,
- exception);
- }
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationProperties.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationProperties.java
deleted file mode 100644
index b8a7144b3d..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationProperties.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * ================================================================================
- * 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.notification;
-
-import jakarta.validation.constraints.NotNull;
-import java.util.Collections;
-import java.util.Map;
-import lombok.Data;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-import org.springframework.validation.annotation.Validated;
-
-@ConfigurationProperties(prefix = "notification.data-updated")
-@Component
-@Data
-@Validated
-public class NotificationProperties {
-
- @NotNull
- private String topic;
- private Map<String, String> filters = Collections.emptyMap();
-
- @Value("${notification.enabled:true}")
- private boolean enabled;
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationPublisher.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationPublisher.java
deleted file mode 100644
index 2d87488245..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationPublisher.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021 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.notification;
-
-import lombok.extern.slf4j.Slf4j;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.onap.cps.event.model.CpsDataUpdatedEvent;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.kafka.core.KafkaTemplate;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-public class NotificationPublisher {
-
- private KafkaTemplate<String, CpsDataUpdatedEvent> kafkaTemplate;
- private String topicName;
-
- /**
- * Create an instance of Notification Publisher.
- *
- * @param kafkaTemplate kafkaTemplate is send event using kafka
- * @param topicName topic, to which cpsDataUpdatedEvent is sent, is provided by setting
- * 'notification.data-updated.topic' in the application properties
- */
- @Autowired
- public NotificationPublisher(
- final KafkaTemplate<String, CpsDataUpdatedEvent> kafkaTemplate,
- final @Value("${notification.data-updated.topic}") String topicName) {
- this.kafkaTemplate = kafkaTemplate;
- this.topicName = topicName;
- }
-
- /**
- * Send event to Kafka with correct message key.
- *
- * @param cpsDataUpdatedEvent event to be sent to kafka
- */
- public void sendNotification(@NonNull final CpsDataUpdatedEvent cpsDataUpdatedEvent) {
- final var messageKey = cpsDataUpdatedEvent.getContent().getDataspaceName() + ","
- + cpsDataUpdatedEvent.getContent().getAnchorName();
- log.debug("Data Updated event is being sent with messageKey: '{}' & body : {} ",
- messageKey, cpsDataUpdatedEvent);
- kafkaTemplate.send(topicName, messageKey, cpsDataUpdatedEvent);
- }
-
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
deleted file mode 100644
index c29d042293..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021-2022 Bell Canada.
- * Modifications Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.notification;
-
-import jakarta.annotation.PostConstruct;
-import java.time.OffsetDateTime;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Future;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.api.CpsAdminService;
-import org.onap.cps.spi.model.Anchor;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
-@Service
-@Slf4j
-@RequiredArgsConstructor
-public class NotificationService {
-
- private final NotificationProperties notificationProperties;
- private final NotificationPublisher notificationPublisher;
- private final CpsDataUpdatedEventFactory cpsDataUpdatedEventFactory;
- private final NotificationErrorHandler notificationErrorHandler;
- private final CpsAdminService cpsAdminService;
- private List<Pattern> dataspacePatterns;
-
- @PostConstruct
- public void init() {
- log.info("Notification Properties {}", notificationProperties);
- this.dataspacePatterns = getDataspaceFilterPatterns(notificationProperties);
- }
-
- private List<Pattern> getDataspaceFilterPatterns(final NotificationProperties notificationProperties) {
- if (notificationProperties.isEnabled()) {
- return Arrays.stream(notificationProperties.getFilters()
- .getOrDefault("enabled-dataspaces", "")
- .split(","))
- .map(filterPattern -> Pattern.compile(filterPattern, Pattern.CASE_INSENSITIVE))
- .collect(Collectors.toList());
- } else {
- return Collections.emptyList();
- }
- }
-
- /**
- * Process Data Updated Event and publishes the notification.
- *
- * @param anchor anchor
- * @param xpath xpath of changed data node
- * @param operation operation
- * @param observedTimestamp observedTimestamp
- * @return future
- */
- @Async("notificationExecutor")
- public Future<Void> processDataUpdatedEvent(final Anchor anchor, final String xpath, final Operation operation,
- final OffsetDateTime observedTimestamp) {
-
- log.debug("process data updated event for anchor '{}'", anchor);
- try {
- if (shouldSendNotification(anchor.getDataspaceName())) {
- final var cpsDataUpdatedEvent =
- cpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor,
- observedTimestamp, getRootNodeOperation(xpath, operation));
- log.debug("data updated event to be published {}", cpsDataUpdatedEvent);
- notificationPublisher.sendNotification(cpsDataUpdatedEvent);
- }
- } catch (final Exception exception) {
- /* All the exceptions are handled to not to propagate it to caller.
- CPS operation should not fail if sending event fails for any reason.
- */
- notificationErrorHandler.onException("Failed to process cps-data-updated-event.",
- exception, anchor, xpath, operation);
- }
- return CompletableFuture.completedFuture(null);
- }
-
- /*
- Add more complex rules based on dataspace and anchor later
- */
- private boolean shouldSendNotification(final String dataspaceName) {
-
- return notificationProperties.isEnabled()
- && dataspacePatterns.stream()
- .anyMatch(pattern -> pattern.matcher(dataspaceName).find());
- }
-
- private Operation getRootNodeOperation(final String xpath, final Operation operation) {
- return isRootXpath(xpath) || isRootContainerNodeXpath(xpath) ? operation : Operation.UPDATE;
- }
-
- private static boolean isRootXpath(final String xpath) {
- return "/".equals(xpath) || "".equals(xpath);
- }
-
- private static boolean isRootContainerNodeXpath(final String xpath) {
- return 0 == xpath.lastIndexOf('/');
- }
-
-}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/Operation.java b/cps-service/src/main/java/org/onap/cps/notification/Operation.java
deleted file mode 100644
index 83e1ccf79f..0000000000
--- a/cps-service/src/main/java/org/onap/cps/notification/Operation.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * 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.notification;
-
-public enum Operation {
- CREATE,
- UPDATE,
- DELETE
-}
diff --git a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
index d58ddf4fa9..35dc7347b2 100644
--- a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
+++ b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java
@@ -26,7 +26,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
-import org.onap.cps.api.CpsAdminService;
+import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.impl.YangTextSchemaSourceSetCache;
import org.onap.cps.cache.AnchorDataCacheEntry;
import org.onap.cps.cpspath.parser.CpsPathPrefixType;
@@ -48,7 +48,7 @@ public class PrefixResolver {
private static final String CACHE_ENTRY_PROPERTY_NAME = "prefixPerContainerName";
- private final CpsAdminService cpsAdminService;
+ private final CpsAnchorService cpsAnchorService;
private final YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
@@ -63,7 +63,7 @@ public class PrefixResolver {
* @return the prefix of the module the top level element of given xpath
*/
public String getPrefix(final String dataspaceName, final String anchorName, final String xpath) {
- final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
return getPrefix(anchor, xpath);
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy
index 12564fb6d4..3546b81671 100755..100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAdminServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsAnchorServiceImplSpec.groovy
@@ -1,9 +1,6 @@
/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
- * Modifications Copyright (C) 2020-2022 Bell Canada.
- * Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2022 TechMahindra Ltd.
+ * ============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.
@@ -23,29 +20,20 @@
package org.onap.cps.api.impl
-import org.onap.cps.api.CpsDataService
import org.onap.cps.spi.CpsAdminPersistenceService
+import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.exceptions.ModuleNamesNotFoundException
import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.model.Dataspace
import org.onap.cps.spi.utils.CpsValidator
import spock.lang.Specification
-import java.time.OffsetDateTime
-class CpsAdminServiceImplSpec extends Specification {
+class CpsAnchorServiceImplSpec extends Specification {
+
def mockCpsAdminPersistenceService = Mock(CpsAdminPersistenceService)
- def mockCpsDataService = Mock(CpsDataService)
+ def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
def mockCpsValidator = Mock(CpsValidator)
- def objectUnderTest = new CpsAdminServiceImpl(mockCpsAdminPersistenceService, mockCpsDataService,mockCpsValidator)
- def 'Create dataspace method invokes persistence service.'() {
- when: 'create dataspace method is invoked'
- objectUnderTest.createDataspace('someDataspace')
- then: 'the persistence service method is invoked with same parameters'
- 1 * mockCpsAdminPersistenceService.createDataspace('someDataspace')
- and: 'the CpsValidator is called on the dataspaceName'
- 1 * mockCpsValidator.validateNameCharacters('someDataspace')
- }
+ def objectUnderTest = new CpsAnchorServiceImpl(mockCpsAdminPersistenceService, mockCpsDataPersistenceService, mockCpsValidator)
def 'Create anchor method invokes persistence service.'() {
when: 'create anchor method is invoked'
@@ -105,29 +93,13 @@ class CpsAdminServiceImplSpec extends Specification {
1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor')
}
- def 'Retrieve dataspace.'() {
- given: 'a dataspace is already created'
- def dataspace = new Dataspace(name: "someDataspace")
- mockCpsAdminPersistenceService.getDataspace('someDataspace') >> dataspace
- expect: 'the dataspace provided by persistence service is returned as result'
- assert objectUnderTest.getDataspace('someDataspace') == dataspace
- }
-
- def 'Retrieve all dataspaces.'() {
- given: 'that all given dataspaces are already created'
- def dataspaces = [new Dataspace(name: "test-dataspace1"), new Dataspace(name: "test-dataspace2")]
- mockCpsAdminPersistenceService.getAllDataspaces() >> dataspaces
- expect: 'the dataspace provided by persistence service is returned as result'
- assert objectUnderTest.getAllDataspaces() == dataspaces
- }
-
def 'Delete anchor.'() {
when: 'delete anchor is invoked'
objectUnderTest.deleteAnchor('someDataspace','someAnchor')
then: 'delete data nodes is invoked on the data service with expected parameters'
- 1 * mockCpsDataService.deleteDataNodes('someDataspace','someAnchor', _ as OffsetDateTime )
+ 1 * mockCpsDataPersistenceService.deleteDataNodes('someDataspace','someAnchor')
and: 'the persistence service method is invoked with same parameters to delete anchor'
- 1 * mockCpsAdminPersistenceService.deleteAnchor('someDataspace','someAnchor')
+ 1 * mockCpsAdminPersistenceService.deleteAnchor('someDataspace','someAnchor')
and: 'the CpsValidator is called on the dataspaceName, anchorName'
1 * mockCpsValidator.validateNameCharacters('someDataspace', 'someAnchor')
}
@@ -136,7 +108,7 @@ class CpsAdminServiceImplSpec extends Specification {
when: 'delete anchors is invoked'
objectUnderTest.deleteAnchors('someDataspace', ['anchor1', 'anchor2'])
then: 'delete data nodes is invoked on the data service with expected parameters'
- 1 * mockCpsDataService.deleteDataNodes('someDataspace', _ as Collection<String>, _ as OffsetDateTime)
+ 1 * mockCpsDataPersistenceService.deleteDataNodes('someDataspace', _ as Collection<String>)
and: 'the persistence service method is invoked with same parameters to delete anchor'
1 * mockCpsAdminPersistenceService.deleteAnchors('someDataspace',_ as Collection<String>)
and: 'the CpsValidator is called on the dataspace name and anchor names'
@@ -157,7 +129,7 @@ class CpsAdminServiceImplSpec extends Specification {
def 'Query all anchors with Module Names Not Found Exception in persistence layer.'() {
given: 'the persistence layer throws a Module Names Not Found Exception'
- def originalException = new ModuleNamesNotFoundException('exception-ds', [ 'm1', 'm2'])
+ def originalException = new ModuleNamesNotFoundException('exception-ds', ['m1', 'm2'])
mockCpsAdminPersistenceService.queryAnchors(*_) >> { throw originalException}
when: 'attempt query anchors'
objectUnderTest.queryAnchorNames('some-dataspace-name', [])
@@ -170,19 +142,11 @@ class CpsAdminServiceImplSpec extends Specification {
assert thrownUp.details.contains('m2')
}
- def 'Delete dataspace.'() {
- when: 'delete dataspace is invoked'
- objectUnderTest.deleteDataspace('someDataspace')
- then: 'associated persistence service method is invoked with correct parameter'
- 1 * mockCpsAdminPersistenceService.deleteDataspace('someDataspace')
- and: 'the CpsValidator is called on the dataspaceName'
- 1 * mockCpsValidator.validateNameCharacters('someDataspace')
- }
-
def 'Update anchor schema set.'() {
when: 'update anchor is invoked'
objectUnderTest.updateAnchorSchemaSet('someDataspace', 'someAnchor', 'someSchemaSetName')
then: 'associated persistence service method is invoked with correct parameter'
1 * mockCpsAdminPersistenceService.updateAnchorSchemaSet('someDataspace', 'someAnchor', 'someSchemaSetName')
}
+
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index a914598521..77e15c320e 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -24,10 +24,8 @@
package org.onap.cps.api.impl
import org.onap.cps.TestUtils
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDeltaService
-import org.onap.cps.notification.NotificationService
-import org.onap.cps.notification.Operation
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.ConcurrencyException
@@ -38,7 +36,6 @@ import org.onap.cps.spi.exceptions.SessionTimeoutException
import org.onap.cps.spi.model.Anchor
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
-import org.onap.cps.spi.model.DeltaReportBuilder
import org.onap.cps.spi.utils.CpsValidator
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.TimedYangParser
@@ -46,27 +43,24 @@ import org.onap.cps.yang.YangTextSchemaSourceSet
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder
import spock.lang.Shared
import spock.lang.Specification
-
import java.time.OffsetDateTime
import java.util.stream.Collectors
class CpsDataServiceImplSpec extends Specification {
def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
- def mockCpsAdminService = Mock(CpsAdminService)
+ def mockCpsAnchorService = Mock(CpsAnchorService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
- def mockNotificationService = Mock(NotificationService)
def mockCpsValidator = Mock(CpsValidator)
def timedYangParser = new TimedYangParser()
def mockCpsDeltaService = Mock(CpsDeltaService);
- def objectUnderTest = new CpsDataServiceImpl(mockCpsDataPersistenceService, mockCpsAdminService,
- mockYangTextSchemaSourceSetCache, mockNotificationService, mockCpsValidator, timedYangParser, mockCpsDeltaService)
+ def objectUnderTest = new CpsDataServiceImpl(mockCpsDataPersistenceService, mockCpsAnchorService,
+ mockYangTextSchemaSourceSetCache, mockCpsValidator, timedYangParser, mockCpsDeltaService)
def setup() {
-
- mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
- mockCpsAdminService.getAnchor(dataspaceName, ANCHOR_NAME_1) >> anchor1
- mockCpsAdminService.getAnchor(dataspaceName, ANCHOR_NAME_2) >> anchor2
+ mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >> anchor
+ mockCpsAnchorService.getAnchor(dataspaceName, ANCHOR_NAME_1) >> anchor1
+ mockCpsAnchorService.getAnchor(dataspaceName, ANCHOR_NAME_2) >> anchor2
}
@Shared
@@ -92,8 +86,6 @@ class CpsDataServiceImplSpec extends Specification {
{ dataNode -> dataNode.xpath[0] == '/test-tree' })
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.CREATE, observedTimestamp)
where: 'given parameters'
scenario | dataFile | contentType
'json' | 'test-tree.json' | ContentType.JSON
@@ -115,18 +107,6 @@ class CpsDataServiceImplSpec extends Specification {
'invalid xml' | '<invalid xml' | ContentType.XML || 'Failed to parse xml data'
}
- def 'Saving #scenarioDesired data exception during notification.'() {
- given: 'schema set for given anchor and dataspace references test-tree model'
- setupSchemaSetMocks('test-tree.yang')
- and: 'the notification service throws an exception'
- mockNotificationService.processDataUpdatedEvent(*_) >> { throw new RuntimeException('to be ignored')}
- when: 'save data method is invoked with test-tree json data'
- def data = TestUtils.getResourceFileContent('test-tree.json')
- objectUnderTest.saveData(dataspaceName, anchorName, data, observedTimestamp)
- then: 'the exception is ignored'
- noExceptionThrown()
- }
-
def 'Saving list element data fragment under Root node.'() {
given: 'schema set for given anchor and dataspace references bookstore model'
setupSchemaSetMocks('bookstore.yang')
@@ -145,8 +125,6 @@ class CpsDataServiceImplSpec extends Specification {
)
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.UPDATE, observedTimestamp)
}
def 'Saving child data fragment under existing node.'() {
@@ -160,8 +138,6 @@ class CpsDataServiceImplSpec extends Specification {
{ dataNode -> dataNode.xpath[0] == '/test-tree/branch[@name=\'New\']' })
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.CREATE, observedTimestamp)
}
def 'Saving list element data fragment under existing node.'() {
@@ -182,8 +158,6 @@ class CpsDataServiceImplSpec extends Specification {
)
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp)
}
def 'Saving collection of a batch with data fragment under existing node.'() {
@@ -202,8 +176,6 @@ class CpsDataServiceImplSpec extends Specification {
assert listOfXpaths.containsAll(['/test-tree/branch[@name=\'B\']','/test-tree/branch[@name=\'A\']'])
}
}
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp)
}
def 'Saving empty list element data fragment.'() {
@@ -266,8 +238,6 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.batchUpdateDataLeaves(dataspaceName, anchorName, {dataNode -> dataNode.keySet()[0] == expectedNodeXpath})
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree'
@@ -300,8 +270,6 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.batchUpdateDataLeaves(dataspaceName, anchorName, {dataNode -> dataNode.keySet()[index] == expectedNodeXpath})
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp)
where: 'the following parameters were used'
index | expectedNodeXpath
0 | '/first-container'
@@ -325,8 +293,6 @@ class CpsDataServiceImplSpec extends Specification {
.iterator().next() == "/bookstore/categories[@code='01']/books[@title='new']"})
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'the data updated event is sent to the notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/bookstore', Operation.UPDATE, observedTimestamp)
}
def 'Replace data node using singular data node: #scenario.'() {
@@ -337,8 +303,6 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath})
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, parentNodeXpath, Operation.UPDATE, observedTimestamp)
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
where: 'following parameters were used'
@@ -356,10 +320,6 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataNodesAndDescendants(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath})
- and: 'data updated event is sent to notification service'
- nodesJsonData.keySet().each {
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, it, Operation.UPDATE, observedTimestamp)
- }
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
where: 'following parameters were used'
@@ -399,8 +359,6 @@ class CpsDataServiceImplSpec extends Specification {
)
and: 'the CpsValidator is called on the dataspaceName and AnchorName twice'
2 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree', Operation.UPDATE, observedTimestamp)
}
def 'Replace whole list content with empty list element.'() {
@@ -420,8 +378,6 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, '/test-tree/branch')
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/test-tree/branch', Operation.DELETE, observedTimestamp)
}
def 'Delete multiple list elements under existing node.'() {
@@ -431,8 +387,6 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName, ['/test-tree/branch[@name="A"]', '/test-tree/branch[@name="B"]'])
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'two data updated events are sent to notification service'
- 2 * mockNotificationService.processDataUpdatedEvent(anchor, _, Operation.DELETE, observedTimestamp)
}
def 'Delete data node under anchor and dataspace.'() {
@@ -442,16 +396,12 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, '/data-node')
and: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
- and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/data-node', Operation.DELETE, observedTimestamp)
}
def 'Delete all data nodes for a given anchor and dataspace.'() {
when: 'delete data nodes method is invoked with correct parameters'
objectUnderTest.deleteDataNodes(dataspaceName, anchorName, observedTimestamp)
- then: 'data updated event is sent to notification service before the delete'
- 1 * mockNotificationService.processDataUpdatedEvent(anchor, '/', Operation.DELETE, observedTimestamp)
- and: 'the CpsValidator is called on the dataspaceName and AnchorName'
+ then: 'the CpsValidator is called on the dataspaceName and AnchorName'
1 * mockCpsValidator.validateNameCharacters(dataspaceName, anchorName)
and: 'the persistence service method is invoked with the correct parameters'
1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName)
@@ -474,14 +424,12 @@ class CpsDataServiceImplSpec extends Specification {
def 'Delete all data nodes for given dataspace and multiple anchors.'() {
given: 'schema set for given anchors and dataspace references test tree model'
setupSchemaSetMocks('test-tree.yang')
- mockCpsAdminService.getAnchors(dataspaceName, ['anchor1', 'anchor2']) >>
+ mockCpsAnchorService.getAnchors(dataspaceName, ['anchor1', 'anchor2']) >>
[new Anchor(name: 'anchor1', dataspaceName: dataspaceName),
new Anchor(name: 'anchor2', dataspaceName: dataspaceName)]
when: 'delete data node method is invoked with correct parameters'
objectUnderTest.deleteDataNodes(dataspaceName, ['anchor1', 'anchor2'], observedTimestamp)
- then: 'data updated events are sent to notification service before the delete'
- 2 * mockNotificationService.processDataUpdatedEvent(_, '/', Operation.DELETE, observedTimestamp)
- and: 'the CpsValidator is called on the dataspace name and the anchor names'
+ then: 'the CpsValidator is called on the dataspace name and the anchor names'
2 * mockCpsValidator.validateNameCharacters(_)
and: 'the persistence service method is invoked with the correct parameters'
1 * mockCpsDataPersistenceService.deleteDataNodes(dataspaceName, _ as Collection<String>)
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy
new file mode 100644
index 0000000000..8e17594bd1
--- /dev/null
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataspaceServiceImplSpec.groovy
@@ -0,0 +1,67 @@
+/*
+ * ============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.api.impl
+
+import org.onap.cps.spi.CpsAdminPersistenceService
+import org.onap.cps.spi.model.Dataspace
+import org.onap.cps.spi.utils.CpsValidator
+import spock.lang.Specification
+
+class CpsDataspaceServiceImplSpec extends Specification {
+ def mockCpsAdminPersistenceService = Mock(CpsAdminPersistenceService)
+ def mockCpsValidator = Mock(CpsValidator)
+ def objectUnderTest = new CpsDataspaceServiceImpl(mockCpsAdminPersistenceService,mockCpsValidator)
+
+ def 'Create dataspace method invokes persistence service.'() {
+ when: 'create dataspace method is invoked'
+ objectUnderTest.createDataspace('someDataspace')
+ then: 'the persistence service method is invoked with same parameters'
+ 1 * mockCpsAdminPersistenceService.createDataspace('someDataspace')
+ and: 'the CpsValidator is called on the dataspaceName'
+ 1 * mockCpsValidator.validateNameCharacters('someDataspace')
+ }
+
+ def 'Retrieve dataspace.'() {
+ given: 'a dataspace is already created'
+ def dataspace = new Dataspace(name: "someDataspace")
+ mockCpsAdminPersistenceService.getDataspace('someDataspace') >> dataspace
+ expect: 'the dataspace provided by persistence service is returned as result'
+ assert objectUnderTest.getDataspace('someDataspace') == dataspace
+ }
+
+ def 'Retrieve all dataspaces.'() {
+ given: 'that all given dataspaces are already created'
+ def dataspaces = [new Dataspace(name: "test-dataspace1"), new Dataspace(name: "test-dataspace2")]
+ mockCpsAdminPersistenceService.getAllDataspaces() >> dataspaces
+ expect: 'the dataspace provided by persistence service is returned as result'
+ assert objectUnderTest.getAllDataspaces() == dataspaces
+ }
+
+ def 'Delete dataspace.'() {
+ when: 'delete dataspace is invoked'
+ objectUnderTest.deleteDataspace('someDataspace')
+ then: 'associated persistence service method is invoked with correct parameter'
+ 1 * mockCpsAdminPersistenceService.deleteDataspace('someDataspace')
+ and: 'the CpsValidator is called on the dataspaceName'
+ 1 * mockCpsValidator.validateNameCharacters('someDataspace')
+ }
+
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
index d8edb02abd..d909e27abf 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
@@ -23,11 +23,12 @@
package org.onap.cps.api.impl
+import org.onap.cps.api.CpsAnchorService
+
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
import org.onap.cps.TestUtils
-import org.onap.cps.api.CpsAdminService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException
import org.onap.cps.spi.exceptions.ModelValidationException
@@ -45,12 +46,12 @@ import spock.lang.Specification
class CpsModuleServiceImplSpec extends Specification {
def mockCpsModulePersistenceService = Mock(CpsModulePersistenceService)
- def mockCpsAdminService = Mock(CpsAdminService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
+ def mockCpsAnchorService = Mock(CpsAnchorService)
def mockCpsValidator = Mock(CpsValidator)
def timedYangTextSchemaSourceSetBuilder = new TimedYangTextSchemaSourceSetBuilder()
- def objectUnderTest = new CpsModuleServiceImpl(mockCpsModulePersistenceService, mockYangTextSchemaSourceSetCache, mockCpsAdminService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)
+ def objectUnderTest = new CpsModuleServiceImpl(mockCpsModulePersistenceService, mockYangTextSchemaSourceSetCache, mockCpsAnchorService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)
def 'Create schema set.'() {
when: 'Create schema set method is invoked'
@@ -133,11 +134,11 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is allowed.'() {
given: '#numberOfAnchors anchors are associated with schemaset'
def associatedAnchors = createAnchors(numberOfAnchors)
- mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> associatedAnchors
+ mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> associatedAnchors
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_ALLOWED)
then: 'anchor deletion is called #numberOfAnchors times'
- numberOfAnchors * mockCpsAdminService.deleteAnchor('my-dataspace', _)
+ numberOfAnchors * mockCpsAnchorService.deleteAnchor('my-dataspace', _)
and: 'persistence service method is invoked with same parameters'
1 * mockCpsModulePersistenceService.deleteSchemaSet('my-dataspace', 'my-schemaset')
and: 'schema set will be removed from the cache'
@@ -152,11 +153,11 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is prohibited.'() {
given: 'no anchors are associated with schemaset'
- mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> Collections.emptyList()
+ mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> Collections.emptyList()
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
then: 'no anchors are deleted'
- 0 * mockCpsAdminService.deleteAnchor(_, _)
+ 0 * mockCpsAnchorService.deleteAnchor(_, _)
and: 'persistence service method is invoked with same parameters'
1 * mockCpsModulePersistenceService.deleteSchemaSet('my-dataspace', 'my-schemaset')
and: 'schema set will be removed from the cache'
@@ -169,7 +170,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete schema-set when cascade is prohibited and schema-set has anchors.'() {
given: '2 anchors are associated with schemaset'
- mockCpsAdminService.getAnchors('my-dataspace', 'my-schemaset') >> createAnchors(2)
+ mockCpsAnchorService.getAnchors('my-dataspace', 'my-schemaset') >> createAnchors(2)
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSet('my-dataspace', 'my-schemaset', CASCADE_DELETE_PROHIBITED)
then: 'Schema-Set in Use exception is thrown'
@@ -178,11 +179,11 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Delete multiple schema-sets when cascade is allowed.'() {
given: '#numberOfAnchors anchors are associated with each schemaset'
- mockCpsAdminService.getAnchors('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2)
+ mockCpsAnchorService.getAnchors('my-dataspace', ['my-schemaset1', 'my-schemaset2']) >> createAnchors(numberOfAnchors * 2)
when: 'schema set deletion is requested with cascade allowed'
objectUnderTest.deleteSchemaSetsWithCascade('my-dataspace', ['my-schemaset1', 'my-schemaset2'])
then: 'anchor deletion is called #numberOfAnchors times'
- mockCpsAdminService.deleteAnchors('my-dataspace', _)
+ mockCpsAnchorService.deleteAnchors('my-dataspace', _)
and: 'persistence service method is invoked with same parameters'
mockCpsModulePersistenceService.deleteSchemaSets('my-dataspace', _)
and: 'schema sets will be removed from the cache'
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
index 1b873ec12b..4782468f19 100755
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/E2ENetworkSliceSpec.groovy
@@ -24,9 +24,9 @@
package org.onap.cps.api.impl
import org.onap.cps.TestUtils
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDeltaService
-import org.onap.cps.notification.NotificationService
+import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.model.Anchor
@@ -40,8 +40,7 @@ import spock.lang.Specification
class E2ENetworkSliceSpec extends Specification {
def mockModuleStoreService = Mock(CpsModulePersistenceService)
def mockDataStoreService = Mock(CpsDataPersistenceService)
- def mockCpsAdminService = Mock(CpsAdminService)
- def mockNotificationService = Mock(NotificationService)
+ def mockCpsAnchorService = Mock(CpsAnchorService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
def mockCpsValidator = Mock(CpsValidator)
def timedYangTextSchemaSourceSetBuilder = new TimedYangTextSchemaSourceSetBuilder()
@@ -49,10 +48,10 @@ class E2ENetworkSliceSpec extends Specification {
def mockCpsDeltaService = Mock(CpsDeltaService)
def cpsModuleServiceImpl = new CpsModuleServiceImpl(mockModuleStoreService,
- mockYangTextSchemaSourceSetCache, mockCpsAdminService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)
+ mockYangTextSchemaSourceSetCache, mockCpsAnchorService, mockCpsValidator,timedYangTextSchemaSourceSetBuilder)
- def cpsDataServiceImpl = new CpsDataServiceImpl(mockDataStoreService, mockCpsAdminService,
- mockYangTextSchemaSourceSetCache, mockNotificationService, mockCpsValidator, timedYangParser, mockCpsDeltaService)
+ def cpsDataServiceImpl = new CpsDataServiceImpl(mockDataStoreService, mockCpsAnchorService,
+ mockYangTextSchemaSourceSetCache, mockCpsValidator, timedYangParser, mockCpsDeltaService)
def dataspaceName = 'someDataspace'
def anchorName = 'someAnchor'
@@ -91,7 +90,7 @@ class E2ENetworkSliceSpec extends Specification {
and : 'a valid json is provided for the model'
def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-Cavsta-Data.txt')
and : 'all the further dependencies are mocked '
- mockCpsAdminService.getAnchor(dataspaceName, anchorName) >>
+ mockCpsAnchorService.getAnchor(dataspaceName, anchorName) >>
new Anchor().builder().name(anchorName).schemaSetName(schemaSetName).dataspaceName(dataspaceName).build()
mockYangTextSchemaSourceSetCache.get(dataspaceName, schemaSetName) >>
YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
@@ -124,7 +123,7 @@ class E2ENetworkSliceSpec extends Specification {
and : 'a valid json is provided for the model'
def jsonData = TestUtils.getResourceFileContent('e2e/basic/cps-ran-inventory-data.json')
and : 'all the further dependencies are mocked '
- mockCpsAdminService.getAnchor('someDataspace', 'someAnchor') >>
+ mockCpsAnchorService.getAnchor('someDataspace', 'someAnchor') >>
new Anchor().builder().name('someAnchor').schemaSetName('someSchemaSet').dataspaceName(dataspaceName).build()
mockYangTextSchemaSourceSetCache.get('someDataspace', 'someSchemaSet') >> YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap)
mockModuleStoreService.getYangSchemaResources('someDataspace', 'someSchemaSet') >> schemaContext
diff --git a/cps-service/src/test/groovy/org/onap/cps/config/AsyncConfigSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/config/AsyncConfigSpec.groovy
new file mode 100644
index 0000000000..9f4e81aabc
--- /dev/null
+++ b/cps-service/src/test/groovy/org/onap/cps/config/AsyncConfigSpec.groovy
@@ -0,0 +1,46 @@
+/*
+ * ============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.config
+
+import spock.lang.Specification
+
+class AsyncConfigSpec extends Specification {
+
+ def objectUnderTest = new AsyncConfig()
+
+ def 'Create Async Config and validate it'() {
+ when: 'we set some test properties to tune taskexecutor'
+ objectUnderTest.setCorePoolSize(5)
+ objectUnderTest.setMaxPoolSize(50)
+ objectUnderTest.setQueueCapacity(100)
+ objectUnderTest.setThreadNamePrefix('Test-')
+ objectUnderTest.setWaitForTasksToCompleteOnShutdown(true)
+ then: 'we can instantiate a Async Config object'
+ assert objectUnderTest != null
+ and: 'taskexector is configured with correct properties'
+ def tasExecutor = objectUnderTest.getThreadAsyncExecutorForNotification()
+ assert tasExecutor.properties['corePoolSize'] == 5
+ assert tasExecutor.properties['maxPoolSize'] == 50
+ assert tasExecutor.properties['queueCapacity'] == 100
+ assert tasExecutor.properties['keepAliveSeconds'] == 60
+ assert tasExecutor.properties['threadNamePrefix'] == 'Test-'
+ }
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdatedEventFactorySpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdatedEventFactorySpec.groovy
deleted file mode 100644
index 49f4bf3850..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdatedEventFactorySpec.groovy
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021-2022 Bell Canada.
- * Modifications Copyright (c) 2022-2023 Nordix Foundation
- * Modifications Copyright (C) 2023 TechMahindra Ltd.
- * ================================================================================
- * 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.notification
-
-import org.onap.cps.spi.model.DataNode
-
-import java.time.OffsetDateTime
-import java.time.format.DateTimeFormatter
-import org.onap.cps.utils.DateTimeUtility
-import org.onap.cps.utils.PrefixResolver
-import org.onap.cps.api.CpsDataService
-import org.onap.cps.event.model.Content
-import org.onap.cps.event.model.Data
-import org.onap.cps.spi.FetchDescendantsOption
-import org.onap.cps.spi.model.Anchor
-import org.onap.cps.spi.model.DataNodeBuilder
-import org.springframework.util.StringUtils
-import spock.lang.Specification
-
-class CpsDataUpdatedEventFactorySpec extends Specification {
-
- def mockCpsDataService = Mock(CpsDataService)
-
- def mockPrefixResolver = Mock(PrefixResolver)
-
- def objectUnderTest = new CpsDataUpdatedEventFactory(mockCpsDataService, mockPrefixResolver)
-
- def dateTimeFormat = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
-
- def 'Create a CPS data updated event successfully: #scenario'() {
- given: 'an anchor which has been updated'
- def anchor = new Anchor('my-anchorname', 'my-dataspace', 'my-schemaset-name')
- and: 'cps data service returns the data node details'
- def xpath = '/xpath'
- def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build()
- mockCpsDataService.getDataNodes(
- 'my-dataspace', 'my-anchorname', '/', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode]
- when: 'CPS data updated event is created'
- def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(anchor,
- DateTimeUtility.toOffsetDateTime(inputObservedTimestamp), Operation.CREATE)
- then: 'CPS data updated event is created with correct envelope'
- with(cpsDataUpdatedEvent) {
- type == 'org.onap.cps.data-updated-event'
- source == new URI('urn:cps:org.onap.cps')
- schema == new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
- StringUtils.hasText(id)
- content != null
- }
- and: 'correct content'
- with(cpsDataUpdatedEvent.content) {
- assert isExpectedDateTimeFormat(observedTimestamp): "$observedTimestamp is not in $dateTimeFormat format"
- if (inputObservedTimestamp != null)
- assert observedTimestamp == inputObservedTimestamp
- else
- assert OffsetDateTime.now().minusSeconds(20).isBefore(
- DateTimeUtility.toOffsetDateTime(observedTimestamp))
- assert anchorName == 'my-anchorname'
- assert dataspaceName == 'my-dataspace'
- assert schemaSetName == 'my-schemaset-name'
- assert operation == Content.Operation.CREATE
- assert data == new Data().withAdditionalProperty('xpath', ['leafName': 'leafValue'])
- }
- where:
- scenario | inputObservedTimestamp
- 'with observed timestamp -0400' | '2021-01-01T23:00:00.345-0400'
- 'with observed timestamp +0400' | '2021-01-01T23:00:00.345+0400'
- 'missing observed timestamp' | null
- }
-
- def 'Create a delete CPS data updated event successfully'() {
- given: 'an anchor which has been deleted'
- def anchor = new Anchor('my-anchorname', 'my-dataspace', 'my-schemaset-name')
- def deletionTimestamp = '2021-01-01T23:00:00.345-0400'
- when: 'a delete root data node event is created'
- def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(anchor,
- DateTimeUtility.toOffsetDateTime(deletionTimestamp), Operation.DELETE)
- then: 'CPS data updated event is created with correct envelope'
- with(cpsDataUpdatedEvent) {
- type == 'org.onap.cps.data-updated-event'
- source == new URI('urn:cps:org.onap.cps')
- schema == new URI('urn:cps:org.onap.cps:data-updated-event-schema:v1')
- StringUtils.hasText(id)
- content != null
- }
- and: 'correct content'
- with(cpsDataUpdatedEvent.content) {
- assert isExpectedDateTimeFormat(observedTimestamp): "$observedTimestamp is not in $dateTimeFormat format"
- assert observedTimestamp == deletionTimestamp
- assert anchorName == 'my-anchorname'
- assert dataspaceName == 'my-dataspace'
- assert schemaSetName == 'my-schemaset-name'
- assert operation == Content.Operation.DELETE
- assert data == null
- }
- }
-
- def 'Create CPS Data Event with URI Syntax Exception'() {
- given: 'an anchor'
- def anchor = new Anchor('my-anchorname', 'my-dataspace', 'my-schemaset-name')
- and: 'a mocked data Node (collection)'
- def mockDataNode = Mock(DataNode)
- mockCpsDataService.getDataNodes(*_) >> [ mockDataNode ]
- and: 'a URI syntax exception is thrown somewhere (using datanode as cannot manipulate hardcoded URIs'
- def originalException = new URISyntaxException('input', 'reason', 0)
- mockDataNode.getXpath() >> { throw originalException }
- when: 'attempt to create data updated event'
- objectUnderTest.createCpsDataUpdatedEvent(anchor, OffsetDateTime.now(), Operation.UPDATE)
- then: 'the same exception is thrown up'
- def thrownUp = thrown(URISyntaxException)
- assert thrownUp == originalException
- }
-
- def isExpectedDateTimeFormat(String observedTimestamp) {
- try {
- DateTimeFormatter.ofPattern(dateTimeFormat).parse(observedTimestamp)
- } catch (DateTimeParseException) {
- return false
- }
- return true
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/KafkaPublisherSpecBase.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/KafkaPublisherSpecBase.groovy
deleted file mode 100644
index b60b38f054..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/KafkaPublisherSpecBase.groovy
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * ================================================================================
- * 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.notification
-
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.kafka.config.TopicBuilder
-import org.springframework.kafka.core.ConsumerFactory
-import org.springframework.kafka.core.KafkaAdmin
-import org.springframework.kafka.core.KafkaTemplate
-import org.springframework.kafka.listener.ConcurrentMessageListenerContainer
-import org.springframework.kafka.listener.ContainerProperties
-import org.springframework.kafka.listener.MessageListener
-import org.springframework.kafka.test.utils.ContainerTestUtils
-import org.springframework.test.context.ContextConfiguration
-import org.springframework.test.context.DynamicPropertyRegistry
-import org.springframework.test.context.DynamicPropertySource
-import spock.lang.Shared
-import spock.lang.Specification
-
-@ContextConfiguration(classes = [KafkaAutoConfiguration, KafkaProducerListener, NotificationErrorHandler])
-@SpringBootTest
-class KafkaPublisherSpecBase extends Specification {
-
- @Autowired
- KafkaTemplate kafkaTemplate
-
- @Autowired
- KafkaAdmin kafkaAdmin
-
- @Autowired
- ConsumerFactory consumerFactory
-
- @Shared volatile topicCreated = false
- @Shared consumedMessages = new ArrayList<>()
-
- def cpsEventTopic = 'cps-events'
-
- @DynamicPropertySource
- static void registerKafkaProperties(DynamicPropertyRegistry registry) {
- registry.add("spring.kafka.bootstrap-servers", KafkaTestContainerConfig::getBootstrapServers)
- }
-
- def setup() {
- // Kafka listener and topic should be created only once for a test-suite.
- // We are also dependent on sprint context to achieve it, and can not execute it in setupSpec
- if (!topicCreated) {
- kafkaAdmin.createOrModifyTopics(TopicBuilder.name(cpsEventTopic).partitions(1).replicas(1).build())
- startListeningToTopic()
- topicCreated = true
- }
- /* kafka message listener stores the messages to consumedMessages.
- It is important to clear the list before each test case so that test cases can fetch the message from index '0'.
- */
- consumedMessages.clear()
- }
-
- def startListeningToTopic() {
- ContainerProperties containerProperties = new ContainerProperties(cpsEventTopic)
- containerProperties.setMessageListener([
- onMessage: {
- record ->
- consumedMessages.add(record.value())
- }] as MessageListener)
-
- ConcurrentMessageListenerContainer container =
- new ConcurrentMessageListenerContainer<>(
- consumerFactory,
- containerProperties)
-
- container.start()
- ContainerTestUtils.waitForAssignment(container, 1)
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/KafkaTestContainerConfig.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/KafkaTestContainerConfig.groovy
deleted file mode 100644
index b07b31a35b..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/KafkaTestContainerConfig.groovy
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * ================================================================================
- * 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.notification
-
-import org.testcontainers.containers.KafkaContainer
-import org.testcontainers.utility.DockerImageName
-
-class KafkaTestContainerConfig {
-
- private static KafkaContainer kafkaContainer
-
- static {
- getKafkaContainer()
- }
-
- // Not the best performance but it is good enough for test case
- private static synchronized KafkaContainer getKafkaContainer() {
- if (kafkaContainer == null) {
- kafkaContainer = new KafkaContainer(DockerImageName.parse("registry.nordix.org/onaptest/confluentinc/cp-kafka:6.2.1").asCompatibleSubstituteFor("confluentinc/cp-kafka"))
- .withEnv("KAFKA_AUTO_CREATE_TOPICS_ENABLE", "false")
- kafkaContainer.start()
- Runtime.getRuntime().addShutdownHook(new Thread(kafkaContainer::stop))
- }
- return kafkaContainer
- }
-
- static String getBootstrapServers() {
- getKafkaContainer()
- return kafkaContainer.getBootstrapServers()
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationErrorHandlerSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationErrorHandlerSpec.groovy
deleted file mode 100644
index 89e305aedb..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationErrorHandlerSpec.groovy
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.notification
-
-import ch.qos.logback.classic.Logger
-import ch.qos.logback.classic.spi.ILoggingEvent
-import ch.qos.logback.core.read.ListAppender
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
-import org.slf4j.LoggerFactory
-
-import spock.lang.Specification
-
-class NotificationErrorHandlerSpec extends Specification{
-
- NotificationErrorHandler objectUnderTest = new NotificationErrorHandler()
- def logWatcher = Spy(ListAppender<ILoggingEvent>)
-
- @BeforeEach
- void setup() {
- ((Logger) LoggerFactory.getLogger(NotificationErrorHandler.class)).addAppender(logWatcher);
- logWatcher.start();
- }
-
- @AfterEach
- void teardown() {
- ((Logger) LoggerFactory.getLogger(NotificationErrorHandler.class)).detachAndStopAllAppenders();
- }
-
- def 'Logging exception via notification error handler #scenario'() {
- when: 'exception #scenario occurs'
- objectUnderTest.onException(exception, 'some context')
- then: 'log output results contains the correct error details'
- def logMessage = logWatcher.list[0].getFormattedMessage()
- assert logMessage.contains('Failed to process')
- assert logMessage.contains("Error cause: ${exptectedCauseString}")
- assert logMessage.contains("Error context: [some context]")
- where:
- scenario | exception || exptectedCauseString
- 'with cause' | new Exception('message') || 'message'
- 'without cause' | new Exception('message', new RuntimeException('cause')) || 'java.lang.RuntimeException: cause'
- }
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationPublisherSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationPublisherSpec.groovy
deleted file mode 100644
index 6cd9ae1b20..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationPublisherSpec.groovy
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021 Bell Canada. All rights reserved.
- * Modifications Copyright (C) 2021-2022 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.notification
-
-import org.apache.kafka.clients.producer.ProducerRecord
-import org.onap.cps.event.model.Content
-import org.onap.cps.event.model.CpsDataUpdatedEvent
-import org.spockframework.spring.SpringBean
-import org.springframework.kafka.KafkaException
-import org.springframework.kafka.core.KafkaTemplate
-import spock.util.concurrent.PollingConditions
-
-class NotificationPublisherSpec extends KafkaPublisherSpecBase {
-
- @SpringBean
- NotificationErrorHandler spyNotificationErrorHandler = Spy(new NotificationErrorHandler())
-
- @SpringBean
- KafkaProducerListener spyKafkaProducerListener = Spy(new KafkaProducerListener<>(spyNotificationErrorHandler))
-
- KafkaTemplate spyKafkaTemplate
- NotificationPublisher objectUnderTest
-
- def myAnchorName = 'my-anchor'
- def myDataspaceName = 'my-dataspace'
-
- def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- .withContent(new Content()
- .withDataspaceName(myDataspaceName)
- .withAnchorName(myAnchorName))
-
- def setup() {
- spyKafkaTemplate = Spy(kafkaTemplate)
- objectUnderTest = new NotificationPublisher(spyKafkaTemplate, cpsEventTopic);
- }
-
- def 'Sending event to message bus with correct message Key.'() {
-
- when: 'event is sent to publisher'
- objectUnderTest.sendNotification(cpsDataUpdatedEvent)
- kafkaTemplate.flush()
-
- then: 'event is sent to correct topic with the expected messageKey'
- interaction {
- def messageKey = myDataspaceName + "," + myAnchorName
- 1 * spyKafkaTemplate.send(cpsEventTopic, messageKey, cpsDataUpdatedEvent)
- }
- and: 'received a successful response'
- 1 * spyKafkaProducerListener.onSuccess(_ as ProducerRecord, _)
- and: 'kafka consumer returns expected message'
- def conditions = new PollingConditions(timeout: 60, initialDelay: 0, factor: 1)
- conditions.eventually {
- assert cpsDataUpdatedEvent == consumedMessages.get(0)
- }
- }
-
- def 'Handling of async errors from message bus.'() {
- given: 'topic does not exist'
- objectUnderTest.topicName = 'non-existing-topic'
-
- when: 'message to sent to a non-existing topic'
- objectUnderTest.sendNotification(cpsDataUpdatedEvent)
- kafkaTemplate.flush()
-
- then: 'error is thrown'
- thrown KafkaException
- and: 'error handler is called with exception details'
- 1 * spyKafkaProducerListener.onError(_ as ProducerRecord, _, _ as Exception)
- 1 * spyNotificationErrorHandler.onException(_ as String, _ as Exception,
- _ as ProducerRecord, _)
- }
-
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
deleted file mode 100644
index f07f89b391..0000000000
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (c) 2021-2022 Bell Canada.
- * Modifications Copyright (C) 2022-2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.notification
-
-import org.onap.cps.api.CpsAdminService
-import org.onap.cps.config.AsyncConfig
-import org.onap.cps.event.model.CpsDataUpdatedEvent
-import org.onap.cps.spi.model.Anchor
-import org.spockframework.spring.SpringBean
-import org.spockframework.spring.SpringSpy
-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 spock.lang.Shared
-import spock.lang.Specification
-
-import java.time.OffsetDateTime
-import java.util.concurrent.TimeUnit
-
-@SpringBootTest
-@EnableConfigurationProperties
-@ContextConfiguration(classes = [NotificationProperties, NotificationService, NotificationErrorHandler, AsyncConfig])
-class NotificationServiceSpec extends Specification {
-
- @SpringSpy
- NotificationProperties spyNotificationProperties
- @SpringBean
- NotificationPublisher mockNotificationPublisher = Mock()
- @SpringBean
- CpsDataUpdatedEventFactory mockCpsDataUpdatedEventFactory = Mock()
- @SpringSpy
- NotificationErrorHandler spyNotificationErrorHandler
- @SpringBean
- CpsAdminService mockCpsAdminService = Mock()
-
- @Autowired
- NotificationService objectUnderTest
-
- @Shared
- def dataspaceName = 'my-dataspace-published'
- @Shared
- def anchorName = 'my-anchorname'
- @Shared
- def anchor = new Anchor('my-anchorname', 'my-dataspace-published', 'my-schemaset-name')
- def myObservedTimestamp = OffsetDateTime.now()
-
- def setup() {
- mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
- }
-
- def 'Skip sending notification when disabled.'() {
- given: 'notification is disabled'
- spyNotificationProperties.isEnabled() >> false
- when: 'dataUpdatedEvent is received'
- objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp)
- then: 'the notification is not sent'
- 0 * mockNotificationPublisher.sendNotification(_)
- }
-
- def 'Send notification when enabled: #scenario.'() {
- given: 'notification is enabled'
- spyNotificationProperties.isEnabled() >> true
- and: 'an anchor is in dataspace where #scenario'
- def anchor = new Anchor('my-anchorname', dataspaceName, 'my-schemaset-name')
- and: 'event factory can create event successfully'
- def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >> cpsDataUpdatedEvent
- when: 'dataUpdatedEvent is received'
- def future = objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp)
- and: 'wait for async processing to complete'
- future.get(10, TimeUnit.SECONDS)
- then: 'async process completed successfully'
- future.isDone()
- and: 'notification is sent'
- expectedSendNotificationCount * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
- where:
- scenario | dataspaceName || expectedSendNotificationCount
- 'dataspace name does not match filter' | 'does-not-match-pattern' || 0
- 'dataspace name matches filter' | 'my-dataspace-published' || 1
- }
-
- def '#scenario are changed with xpath #xpath and operation #operation'() {
- given: 'notification is enabled'
- spyNotificationProperties.isEnabled() >> true
- and: 'event factory creates event if operation is #operation'
- def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, expectedOperationInEvent) >>
- cpsDataUpdatedEvent
- when: 'dataUpdatedEvent is received for #xpath'
- def future = objectUnderTest.processDataUpdatedEvent(anchor, xpath, operation, myObservedTimestamp)
- and: 'wait for async processing to complete'
- future.get(10, TimeUnit.SECONDS)
- then: 'async process completed successfully'
- future.isDone()
- and: 'notification is sent'
- 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
- where:
- scenario | xpath | operation || expectedOperationInEvent
- 'Same event is sent when root nodes' | '' | Operation.CREATE || Operation.CREATE
- 'Same event is sent when root nodes' | '' | Operation.UPDATE || Operation.UPDATE
- 'Same event is sent when root nodes' | '' | Operation.DELETE || Operation.DELETE
- 'Same event is sent when root nodes' | '/' | Operation.CREATE || Operation.CREATE
- 'Same event is sent when root nodes' | '/' | Operation.UPDATE || Operation.UPDATE
- 'Same event is sent when root nodes' | '/' | Operation.DELETE || Operation.DELETE
- 'Same event is sent when container nodes' | '/parent' | Operation.CREATE || Operation.CREATE
- 'Same event is sent when container nodes' | '/parent' | Operation.UPDATE || Operation.UPDATE
- 'Same event is sent when container nodes' | '/parent' | Operation.DELETE || Operation.DELETE
- 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.CREATE || Operation.UPDATE
- 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.UPDATE || Operation.UPDATE
- 'UPDATE event is sent when non root nodes' | '/parent/child' | Operation.DELETE || Operation.UPDATE
- }
-
- def 'Error handling in notification service.'() {
- given: 'notification is enabled'
- spyNotificationProperties.isEnabled() >> true
- and: 'event factory can not create event successfully'
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(anchor, myObservedTimestamp, Operation.CREATE) >>
- { throw new Exception("Could not create event") }
- when: 'event is sent for processing'
- def future = objectUnderTest.processDataUpdatedEvent(anchor, '/', Operation.CREATE, myObservedTimestamp)
- and: 'wait for async processing to complete'
- future.get(10, TimeUnit.SECONDS)
- then: 'async process completed successfully'
- future.isDone()
- and: 'error is handled and not thrown to caller'
- notThrown Exception
- 1 * spyNotificationErrorHandler.onException(_, _, _, '/', Operation.CREATE)
- }
-
- def 'Disabled Notification services'() {
- given: 'a notification service that is disabled'
- spyNotificationProperties.enabled >> false
- NotificationService notificationService = new NotificationService(spyNotificationProperties, mockNotificationPublisher, mockCpsDataUpdatedEventFactory, spyNotificationErrorHandler, mockCpsAdminService)
- notificationService.init()
- expect: 'it will not send notifications'
- assert notificationService.shouldSendNotification('') == false
- }
-}
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
index ff6ab346f2..b975de6555 100644
--- a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy
@@ -24,7 +24,7 @@ package org.onap.cps.utils
import com.hazelcast.map.IMap
import org.onap.cps.TestUtils
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.impl.YangTextSchemaSourceSetCache
import org.onap.cps.cache.AnchorDataCacheEntry
import org.onap.cps.spi.model.Anchor
@@ -34,13 +34,13 @@ import spock.lang.Specification
class PrefixResolverSpec extends Specification {
- def mockCpsAdminService = Mock(CpsAdminService)
+ def mockCpsAnchorService = Mock(CpsAnchorService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
def mockAnchorDataCache = Mock(IMap<String, AnchorDataCacheEntry>)
- def objectUnderTest = new PrefixResolver(mockCpsAdminService, mockYangTextSchemaSourceSetCache, mockAnchorDataCache)
+ def objectUnderTest = new PrefixResolver(mockCpsAnchorService, mockYangTextSchemaSourceSetCache, mockAnchorDataCache)
def mockYangTextSchemaSourceSet = Mock(YangTextSchemaSourceSet)
@@ -52,7 +52,7 @@ class PrefixResolverSpec extends Specification {
given: 'an anchor for the test-tree model'
def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor')
and: 'the system can get this anchor'
- mockCpsAdminService.getAnchor('testDataspace', 'testAnchor') >> anchor
+ mockCpsAnchorService.getAnchor('testDataspace', 'testAnchor') >> anchor
and: 'the schema source cache contains the schema context for the test-tree module'
mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext
}
diff --git a/docker-compose/README.md b/docker-compose/README.md
index 8cc6e57d59..de1fbe296c 100644
--- a/docker-compose/README.md
+++ b/docker-compose/README.md
@@ -57,9 +57,7 @@ It starts both Postgres database and CPS services.
2. To send data-updated events to kafka,
* uncomment the `zookeeper` and `kafka` services.
* uncomment environment variables
- * `notification.data-updated.enabled: 'true'`
* `KAFKA_BOOTSTRAP_SERVER: kafka:9092`
- * `NOTIFICATION_DATASPACE_FILTER_PATTERNS: '.*'`
2. Execute following command from `docker-compose` folder:
Use one of the below version type that has been generated in the local system's docker image list after the build.
diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml
index acfe984976..80f8782af0 100644
--- a/docker-compose/docker-compose.yml
+++ b/docker-compose/docker-compose.yml
@@ -101,8 +101,6 @@ services:
DMI_USERNAME: ${DMI_USERNAME:-cpsuser}
DMI_PASSWORD: ${DMI_PASSWORD:-cpsr0cks!}
KAFKA_BOOTSTRAP_SERVER: kafka:29092
- notification.data-updated.enabled: 'true'
- NOTIFICATION_DATASPACE_FILTER_PATTERNS: '.*'
restart: unless-stopped
profiles:
- dmi-service
diff --git a/docs/deployment.rst b/docs/deployment.rst
index eb5804e5bf..76d2151c44 100644
--- a/docs/deployment.rst
+++ b/docs/deployment.rst
@@ -235,9 +235,6 @@ Any spring supported property can be configured by providing in ``config.additio
| ssl.endpoint.identification.algorithm | | |
| | * ``""``, empty string to disable | |
+---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
-| config.additional. | If asynchronous messaging, user notifications, and updated event persistence should be enabled | ``true`` |
-| notification.data-updated.enabled | | |
-+---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+
| config.additional. | Core pool size in asynchronous execution of notification. | ``2`` |
| notification.async.executor. | | |
| core-pool-size | | |
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 63a877d811..1dc24bf3f2 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -44,6 +44,7 @@ Features
--------
- CPS-Temporal is no longer supported and any related documentation has been removed.
- `CPS-1980 <https://jira.onap.org/browse/CPS-1980>`_ Exposing health and cluster metrics for hazelcast.
+ - `CPS-2005 <https://jira.onap.org/browse/CPS-2005>`_ Removing notification feature for cps updated events ( exclusively used by cps-temporal )
Version: 3.4.0
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
index 40fe030184..6dec3dbf95 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
@@ -20,10 +20,11 @@
package org.onap.cps.integration.base
+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.api.CpsQueryService
-import org.onap.cps.api.impl.CpsAdminServiceImpl
-import org.onap.cps.api.impl.CpsDataServiceImpl
-import org.onap.cps.api.impl.CpsModuleServiceImpl
import org.onap.cps.integration.DatabaseTestContainer
import org.onap.cps.spi.config.CpsSessionFactory
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
@@ -44,7 +45,7 @@ import spock.lang.Specification
import java.time.OffsetDateTime
-@SpringBootTest(classes = [TestConfig, CpsAdminServiceImpl, CpsValidatorImpl, SessionManager, CpsSessionFactory])
+@SpringBootTest(classes = [TestConfig, CpsValidatorImpl, SessionManager, CpsSessionFactory])
@Testcontainers
@EnableAutoConfiguration
@EnableJpaRepositories(basePackageClasses = [DataspaceRepository])
@@ -57,15 +58,19 @@ class CpsIntegrationSpecBase extends Specification {
@Autowired
@Lazy
- CpsAdminServiceImpl cpsAdminService
+ CpsDataspaceService cpsDataspaceService
@Autowired
@Lazy
- CpsDataServiceImpl cpsDataService
+ CpsAnchorService cpsAnchorService
@Autowired
@Lazy
- CpsModuleServiceImpl cpsModuleService
+ CpsDataService cpsDataService
+
+ @Autowired
+ @Lazy
+ CpsModuleService cpsModuleService
@Autowired
@Lazy
@@ -83,7 +88,7 @@ class CpsIntegrationSpecBase extends Specification {
def setup() {
if (!initialized) {
- cpsAdminService.createDataspace(GENERAL_TEST_DATASPACE)
+ cpsDataspaceService.createDataspace(GENERAL_TEST_DATASPACE)
def bookstoreModelFileContent = readResourceDataFile('bookstore/bookstore.yang')
cpsModuleService.createSchemaSet(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore : bookstoreModelFileContent])
initialized = true;
@@ -108,7 +113,7 @@ class CpsIntegrationSpecBase extends Specification {
def dataspaceExists(dataspaceName) {
try {
- cpsAdminService.getDataspace(dataspaceName)
+ cpsDataspaceService.getDataspace(dataspaceName)
} catch (DataspaceNotFoundException dataspaceNotFoundException) {
return false
}
@@ -117,7 +122,7 @@ class CpsIntegrationSpecBase extends Specification {
def addAnchorsWithData(numberOfAnchors, dataspaceName, schemaSetName, anchorNamePrefix, data) {
(1..numberOfAnchors).each {
- cpsAdminService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
+ cpsAnchorService.createAnchor(dataspaceName, schemaSetName, anchorNamePrefix + it)
cpsDataService.saveData(dataspaceName, anchorNamePrefix + it, data.replace("Easons", "Easons-"+it.toString()), OffsetDateTime.now())
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
index 14612d6c13..b10194560a 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/FunctionalSpecBase.groovy
@@ -50,9 +50,9 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
}
def setupBookstoreInfraStructure() {
- cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1)
- cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2)
- cpsAdminService.createDataspace(FUNCTIONAL_TEST_DATASPACE_3)
+ cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_1)
+ cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_2)
+ cpsDataspaceService.createDataspace(FUNCTIONAL_TEST_DATASPACE_3)
def bookstoreYangModelAsString = readResourceDataFile('bookstore/bookstore.yang')
cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
cpsModuleService.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_2, BOOKSTORE_SCHEMA_SET, [bookstore: bookstoreYangModelAsString])
@@ -73,8 +73,8 @@ class FunctionalSpecBase extends CpsIntegrationSpecBase {
def restoreBookstoreDataAnchor(anchorNumber) {
def anchorName = 'bookstoreAnchor' + anchorNumber
- cpsAdminService.deleteAnchor(FUNCTIONAL_TEST_DATASPACE_1, anchorName)
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, anchorName)
+ cpsAnchorService.deleteAnchor(FUNCTIONAL_TEST_DATASPACE_1, anchorName)
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, anchorName)
cpsDataService.saveData(FUNCTIONAL_TEST_DATASPACE_1, anchorName, bookstoreJsonData.replace("Easons", "Easons-"+anchorNumber.toString()), OffsetDateTime.now())
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy
index f4cc8b733f..e1ccdaa6ee 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/TestConfig.groovy
@@ -21,7 +21,6 @@
package org.onap.cps.integration.base
import com.fasterxml.jackson.databind.ObjectMapper
-import org.onap.cps.notification.NotificationService
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.impl.CpsAdminPersistenceServiceImpl
@@ -99,11 +98,6 @@ class TestConfig extends Specification{
}
@Bean
- NotificationService notificationService() {
- return Stub(NotificationService)
- }
-
- @Bean
TimedYangParser timedYangParser() {
return new TimedYangParser()
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
index f8eca61990..99dab84260 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAdminServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsAnchorServiceIntegrationSpec.groovy
@@ -20,76 +20,19 @@
package org.onap.cps.integration.functional
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.integration.base.CpsIntegrationSpecBase
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.AlreadyDefinedException
import org.onap.cps.spi.exceptions.AnchorNotFoundException
-import org.onap.cps.spi.exceptions.DataspaceInUseException
-import org.onap.cps.spi.exceptions.DataspaceNotFoundException
-import java.time.OffsetDateTime
-
-class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase {
-
- CpsAdminService objectUnderTest
- def setup() { objectUnderTest = cpsAdminService }
-
- def 'Dataspace CRUD operations.'() {
- when: 'a dataspace is created'
- objectUnderTest.createDataspace('newDataspace')
- then: 'the dataspace can be read'
- assert objectUnderTest.getDataspace('newDataspace').name == 'newDataspace'
- and: 'it can be deleted'
- objectUnderTest.deleteDataspace('newDataspace')
- then: 'the dataspace no longer exists i.e. an exception is thrown if an attempt is made to retrieve it'
- def thrown = null
- try {
- objectUnderTest.getDataspace('newDataspace')
- } catch(Exception exception) {
- thrown = exception
- }
- assert thrown instanceof DataspaceNotFoundException
- }
+import java.time.OffsetDateTime
- def 'Delete dataspace with error; #scenario.'() {
- setup: 'add some anchors if needed'
- numberOfAnchors.times {
- objectUnderTest.createAnchor(GENERAL_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'anchor' + it)
- }
- when: 'attempt to delete dataspace'
- objectUnderTest.deleteDataspace(dataspaceName)
- then: 'the correct exception is thrown with the relevant details'
- def thrownException = thrown(expectedException)
- thrownException.details.contains(expectedMessageDetails)
- cleanup:
- numberOfAnchors.times {
- objectUnderTest.deleteAnchor(GENERAL_TEST_DATASPACE, 'anchor' + it)
- }
- where: 'the following data is used'
- scenario | dataspaceName | numberOfAnchors || expectedException | expectedMessageDetails
- 'dataspace name does not exist' | 'unknown' | 0 || DataspaceNotFoundException | 'unknown does not exist'
- 'dataspace contains schemasets' | GENERAL_TEST_DATASPACE | 0 || DataspaceInUseException | 'contains 1 schemaset(s)'
- 'dataspace contains anchors' | GENERAL_TEST_DATASPACE | 2 || DataspaceInUseException | 'contains 2 anchor(s)'
- }
+class CpsAnchorServiceIntegrationSpec extends CpsIntegrationSpecBase {
- def 'Retrieve all dataspaces (depends on total test suite).'() {
- given: 'two addtional dataspaces are created'
- objectUnderTest.createDataspace('dataspace1')
- objectUnderTest.createDataspace('dataspace2')
- when: 'all datespaces are retreived'
- def result = objectUnderTest.getAllDataspaces()
- then: 'there are at least 3 dataspaces (2 new ones plus the general test dataspace)'
- result.size() >= 3
- assert result.name.containsAll([GENERAL_TEST_DATASPACE, 'dataspace1', 'dataspace2'])
- }
+ CpsAnchorService objectUnderTest
- def 'Duplicate dataspaces.'() {
- when: 'attempting to create a dataspace with the same name as an existing one'
- objectUnderTest.createDataspace(GENERAL_TEST_DATASPACE)
- then: 'an exception is thrown indicating the dataspace already exists'
- thrown(AlreadyDefinedException)
- }
+ def setup() { objectUnderTest = cpsAnchorService }
def 'Anchor CRUD operations.'() {
when: 'an anchor is created'
@@ -148,9 +91,9 @@ class CpsAdminServiceIntegrationSpec extends CpsIntegrationSpecBase {
then: 'an empty result is returned (no error)'
assert result == []
where:
- scenario | dataspaceName
- 'non existing database' | 'nonExistingDataspace'
- 'just unknown module(s)' | GENERAL_TEST_DATASPACE
+ scenario | dataspaceName
+ 'non existing database' | 'nonExistingDataspace'
+ 'just unknown module(s)' | GENERAL_TEST_DATASPACE
}
def 'Update anchor schema set.'() {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
index 017ede7de2..b107a87e88 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataServiceIntegrationSpec.groovy
@@ -34,8 +34,6 @@ import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
import org.onap.cps.spi.model.DeltaReport
-import java.time.OffsetDateTime
-
import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
@@ -174,7 +172,7 @@ class CpsDataServiceIntegrationSpec extends FunctionalSpecBase {
def 'Attempt to create a top level data node using root.'() {
given: 'a new anchor'
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, 'newAnchor1');
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_SCHEMA_SET, 'newAnchor1');
when: 'attempt to save new top level datanode'
def json = '{"bookstore": {"bookstore-name": "New Store"} }'
objectUnderTest.saveData(FUNCTIONAL_TEST_DATASPACE_1, 'newAnchor1' , '/', json, now)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataspaceServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataspaceServiceIntegrationSpec.groovy
new file mode 100644
index 0000000000..739e802244
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsDataspaceServiceIntegrationSpec.groovy
@@ -0,0 +1,107 @@
+/*
+ * ============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.integration.functional
+
+import org.onap.cps.api.CpsDataspaceService
+import org.onap.cps.integration.base.CpsIntegrationSpecBase
+import org.onap.cps.spi.exceptions.AlreadyDefinedException
+import org.onap.cps.spi.exceptions.DataspaceInUseException
+import org.onap.cps.spi.exceptions.DataspaceNotFoundException
+
+class CpsDataspaceServiceIntegrationSpec extends CpsIntegrationSpecBase {
+
+ CpsDataspaceService objectUnderTest
+
+ def setup() { objectUnderTest = cpsDataspaceService }
+
+ def 'Dataspace CRUD operations.'() {
+ when: 'a dataspace is created'
+ objectUnderTest.createDataspace('newDataspace')
+ then: 'the dataspace can be read'
+ assert objectUnderTest.getDataspace('newDataspace').name == 'newDataspace'
+ and: 'it can be deleted'
+ objectUnderTest.deleteDataspace('newDataspace')
+ then: 'the dataspace no longer exists i.e. an exception is thrown if an attempt is made to retrieve it'
+ def thrown = null
+ try {
+ objectUnderTest.getDataspace('newDataspace')
+ } catch(Exception exception) {
+ thrown = exception
+ }
+ assert thrown instanceof DataspaceNotFoundException
+ }
+
+ def 'Attempt to delete a non-existing dataspace'() {
+ when: 'attempt to delete a non-existing dataspace'
+ objectUnderTest.deleteDataspace('non-existing-name')
+ then: 'a not found exception is thrown with the relevant dataspace name'
+ def thrownException = thrown(DataspaceNotFoundException)
+ assert thrownException.details.contains('non-existing-name does not exist')
+ }
+
+ def 'Attempt Delete dataspace with a schema set and anchor'() {
+ setup: 'a dataspace with a schema set and anchor'
+ objectUnderTest.createDataspace('targetDataspace')
+ cpsModuleService.createSchemaSet('targetDataspace','someSchemaSet',[:])
+ cpsAnchorService.createAnchor('targetDataspace', 'someSchemaSet', 'some_anchor')
+ when: 'attempt to delete dataspace'
+ objectUnderTest.deleteDataspace('targetDataspace')
+ then: 'an in-use exception is thrown mentioning anchors'
+ def thrownException = thrown(DataspaceInUseException)
+ assert thrownException.details.contains('contains 1 anchor(s)')
+ cleanup:
+ cpsModuleService.deleteSchemaSetsWithCascade('targetDataspace',['someSchemaSet'])
+ objectUnderTest.deleteDataspace('targetDataspace')
+ }
+
+ def 'Attempt to delete dataspace with just a schema set'() {
+ setup: 'a dataspace with a schema set'
+ objectUnderTest.createDataspace('targetDataspace')
+ cpsModuleService.createSchemaSet('targetDataspace','someSchemaSet',[:])
+ when: 'attempt to delete dataspace'
+ objectUnderTest.deleteDataspace('targetDataspace')
+ then: 'an in-use exception is thrown mentioning schemasets'
+ def thrownException = thrown(DataspaceInUseException)
+ assert thrownException.details.contains('contains 1 schemaset(s)')
+ cleanup:
+ cpsModuleService.deleteSchemaSetsWithCascade('targetDataspace',['someSchemaSet'])
+ objectUnderTest.deleteDataspace('targetDataspace')
+ }
+
+ def 'Retrieve all dataspaces (depends on total test suite).'() {
+ given: 'two addtional dataspaces are created'
+ objectUnderTest.createDataspace('dataspace1')
+ objectUnderTest.createDataspace('dataspace2')
+ when: 'all datespaces are retreived'
+ def result = objectUnderTest.getAllDataspaces()
+ then: 'there are at least 3 dataspaces (2 new ones plus the general test dataspace)'
+ result.size() >= 3
+ assert result.name.containsAll([GENERAL_TEST_DATASPACE, 'dataspace1', 'dataspace2'])
+ }
+
+ def 'Duplicate dataspaces.'() {
+ when: 'attempting to create a dataspace with the same name as an existing one'
+ objectUnderTest.createDataspace(GENERAL_TEST_DATASPACE)
+ then: 'an exception is thrown indicating the dataspace already exists'
+ thrown(AlreadyDefinedException)
+ }
+
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
index 2e1b082c00..cf0e0b5944 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
@@ -20,6 +20,7 @@
package org.onap.cps.integration.functional
+import org.onap.cps.api.CpsModuleService
import org.onap.cps.api.impl.CpsModuleServiceImpl
import org.onap.cps.integration.base.FunctionalSpecBase
import org.onap.cps.spi.CascadeDeleteAllowed
@@ -33,7 +34,7 @@ import org.onap.cps.spi.model.ModuleReference
class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
- CpsModuleServiceImpl objectUnderTest
+ CpsModuleService objectUnderTest
private static def originalNumberOfModuleReferences = 1
private static def existingModuleReference = new ModuleReference('stores','2020-09-15')
@@ -97,7 +98,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
def schemaSetName = "NewSchemaWith${numberOfNewModules}Modules"
objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, newYangResourcesNameToContentMap, moduleReferences)
and: 'associated with a new anchor'
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, schemaSetName, 'newAnchor')
then: 'the new anchor has the correct number of modules'
def yangResourceModuleReferences = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'newAnchor')
assert expectedNumberOfModulesForAnchor == yangResourceModuleReferences.size()
@@ -204,7 +205,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
objectUnderTest.createSchemaSet(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', newYangResourcesNameToContentMap)
and: 'optionally create anchor for the schema set'
if (associateWithAnchor) {
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'newSchemaSet', 'newAnchor')
}
when: 'attempt to delete the schema set'
try {
@@ -270,7 +271,7 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
given: 'an anchor and schema set with 2 modules (to be upgraded)'
populateNewYangResourcesNameToContentMapAndAllModuleReferences('original', 2)
objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
def yangResourceModuleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
assert yangResourceModuleReferencesBeforeUpgrade.size() == 2
assert yangResourceModuleReferencesBeforeUpgrade.containsAll([new ModuleReference('original_0','2000-01-01'),new ModuleReference('original_1','2001-01-01')])
@@ -291,18 +292,18 @@ class CpsModuleServiceIntegrationSpec extends FunctionalSpecBase {
cleanup:
objectUnderTest.deleteSchemaSetsWithCascade(FUNCTIONAL_TEST_DATASPACE_1, ['targetSchema'])
}
-
+
def 'Upgrade existing schema set from another anchor (used in NCMP for matching module set tag)'() {
given: 'an anchor and schema set with 1 module (target)'
populateNewYangResourcesNameToContentMapAndAllModuleReferences('target', 1)
objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', newYangResourcesNameToContentMap, [])
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'targetSchema', 'targetAnchor')
def moduleReferencesBeforeUpgrade = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'targetAnchor')
assert moduleReferencesBeforeUpgrade.size() == 1
and: 'another anchor and schema set with 2 other modules (source for upgrade)'
populateNewYangResourcesNameToContentMapAndAllModuleReferences('source', 2)
objectUnderTest.createSchemaSetFromModules(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', newYangResourcesNameToContentMap, [])
- cpsAdminService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
+ cpsAnchorService.createAnchor(FUNCTIONAL_TEST_DATASPACE_1, 'sourceSchema', 'sourceAnchor')
assert objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor').size() == 2
when: 'the target schema is upgraded using the module references from the source anchor'
def moduleReferencesFromSourceAnchor = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, 'sourceAnchor')
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
index d8012ec6d4..816aeff71b 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/CpsPerfTestBase.groovy
@@ -43,7 +43,7 @@ class CpsPerfTestBase extends PerfTestBase {
}
def setupPerformanceInfraStructure() {
- cpsAdminService.createDataspace(CPS_PERFORMANCE_TEST_DATASPACE)
+ cpsDataspaceService.createDataspace(CPS_PERFORMANCE_TEST_DATASPACE)
def modelAsString = readResourceDataFile('bookstore/bookstore.yang')
cpsModuleService.createSchemaSet(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, [bookstore: modelAsString])
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpPerfTestBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpPerfTestBase.groovy
index bef42248f9..0557d5bb7e 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpPerfTestBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/base/NcmpPerfTestBase.groovy
@@ -59,20 +59,20 @@ class NcmpPerfTestBase extends PerfTestBase {
}
def setupPerformanceInfraStructure() {
- cpsAdminService.createDataspace(NCMP_PERFORMANCE_TEST_DATASPACE)
+ cpsDataspaceService.createDataspace(NCMP_PERFORMANCE_TEST_DATASPACE)
createRegistrySchemaSet()
createCmDataSubscriptionsSchemaSet()
addCmSubscriptionData()
}
def createInitialData() {
- cpsAdminService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, REGISTRY_ANCHOR)
+ cpsDataspaceService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, REGISTRY_ANCHOR)
def data = readResourceDataFile('ncmp-registry/1000-cmhandles.json')
cpsDataService.saveData(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_ANCHOR, data, OffsetDateTime.now())
}
def createRegistrySchemaSet() {
- def modelAsString = readResourceDataFile('ncmp-registry/dmi-registry@2022-05-10.yang')
+ def modelAsString = readResourceDataFile('ncmp-registry/dmi-registry@2023-11-27.yang')
cpsModuleService.createSchemaSet(NCMP_PERFORMANCE_TEST_DATASPACE, REGISTRY_SCHEMA_SET, [registry: modelAsString])
}
@@ -82,7 +82,7 @@ class NcmpPerfTestBase extends PerfTestBase {
}
def addCmSubscriptionData() {
- cpsAdminService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, CM_DATA_SUBSCRIPTIONS_SCHEMA_SET, CM_DATA_SUBSCRIPTIONS_ANCHOR)
+ cpsDataspaceService.createAnchor(NCMP_PERFORMANCE_TEST_DATASPACE, CM_DATA_SUBSCRIPTIONS_SCHEMA_SET, CM_DATA_SUBSCRIPTIONS_ANCHOR)
cpsDataService.saveData(NCMP_PERFORMANCE_TEST_DATASPACE, CM_DATA_SUBSCRIPTIONS_ANCHOR, datastore1cmHandlePlaceHolder, now)
def subscribers = createLeafList('subscribers',numberOfCmDataSubscribers, subscriberIdPrefix)
def filters = '"filters":' + createJsonArray('filter',numberOfFiltersPerCmHandle,'xpath',xpathPrefix,subscribers)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
index ce66cb08a2..4d4d6125c6 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataServiceLimitsPerfTest.groovy
@@ -35,7 +35,7 @@ class CpsDataServiceLimitsPerfTest extends CpsPerfTestBase {
def 'Create 33,000 books (note further tests depend on this running first).'() {
given: 'an anchor containing a bookstore with one category'
- cpsAdminService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'limitsAnchor')
+ cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'limitsAnchor')
def parentNodeData = '{"bookstore": { "categories": [{ "code": 1, "name": "Test", "books" : [] }] }}'
cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, 'limitsAnchor', parentNodeData, OffsetDateTime.now())
when: '33,000 books are added'
@@ -84,7 +84,7 @@ class CpsDataServiceLimitsPerfTest extends CpsPerfTestBase {
when:
resourceMeter.start()
cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'limitsAnchor', OffsetDateTime.now())
- cpsAdminService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'limitsAnchor')
+ cpsAnchorService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'limitsAnchor')
resourceMeter.stop()
def durationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'test data is deleted in 1 second'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimitsPerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataspaceServiceLimitsPerfTest.groovy
index 9ea7a7b53a..e1235272fe 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsAdminServiceLimitsPerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/CpsDataspaceServiceLimitsPerfTest.groovy
@@ -20,14 +20,14 @@
package org.onap.cps.integration.performance.cps
-import org.onap.cps.api.CpsAdminService
+import org.onap.cps.api.CpsAnchorService
import org.onap.cps.integration.performance.base.CpsPerfTestBase
-class CpsAdminServiceLimitsPerfTest extends CpsPerfTestBase {
+class CpsDataspaceServiceLimitsPerfTest extends CpsPerfTestBase {
- CpsAdminService objectUnderTest
+ CpsAnchorService objectUnderTest
- def setup() { objectUnderTest = cpsAdminService }
+ def setup() { objectUnderTest = cpsAnchorService }
def 'Get anchors from multiple schema set names limit exceeded: 32,766 (~ 2^15) schema set names.'() {
given: 'more than 32,766 schema set names'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy
index 818c300a56..e7bfabefb5 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/DeletePerfTest.groovy
@@ -182,7 +182,7 @@ class DeletePerfTest extends CpsPerfTestBase {
def anchorNames = (1..10).collect {'delete' + it}
when: 'data nodes are deleted'
resourceMeter.start()
- cpsAdminService.deleteAnchors(CPS_PERFORMANCE_TEST_DATASPACE, anchorNames)
+ cpsAnchorService.deleteAnchors(CPS_PERFORMANCE_TEST_DATASPACE, anchorNames)
resourceMeter.stop()
def deleteDurationInSeconds = resourceMeter.getTotalTimeInSeconds()
then: 'delete duration is within expected time and memory used is within limit'
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
index 0c7107a56d..2d38a0dfb6 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/WritePerfTest.groovy
@@ -27,7 +27,7 @@ class WritePerfTest extends CpsPerfTestBase {
def 'Writing openroadm data has linear time.'() {
given: 'an empty anchor exists for openroadm'
- cpsAdminService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'writeAnchor')
+ cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, LARGE_SCHEMA_SET, 'writeAnchor')
and: 'a list of device nodes to add'
def jsonData = generateOpenRoadData(totalNodes)
when: 'device nodes are added'
@@ -39,7 +39,7 @@ class WritePerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Writing ${totalNodes} devices", expectedDuration, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
cleanup:
cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor', OffsetDateTime.now())
- cpsAdminService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
+ cpsAnchorService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
where:
totalNodes || expectedDuration | memoryLimit
50 || 4 | 100
@@ -50,7 +50,7 @@ class WritePerfTest extends CpsPerfTestBase {
def 'Writing bookstore data has exponential time.'() {
given: 'an anchor containing a bookstore with a single category'
- cpsAdminService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'writeAnchor')
+ cpsAnchorService.createAnchor(CPS_PERFORMANCE_TEST_DATASPACE, BOOKSTORE_SCHEMA_SET, 'writeAnchor')
def parentNodeData = '{"bookstore": { "categories": [{ "code": 1, "name": "Test", "books" : [] }] }}'
cpsDataService.saveData(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor', parentNodeData, OffsetDateTime.now())
and: 'a list of books to add'
@@ -64,7 +64,7 @@ class WritePerfTest extends CpsPerfTestBase {
recordAndAssertResourceUsage("Writing ${totalBooks} books", expectedDuration, durationInSeconds, memoryLimit, resourceMeter.getTotalMemoryUsageInMB())
cleanup:
cpsDataService.deleteDataNodes(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor', OffsetDateTime.now())
- cpsAdminService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
+ cpsAnchorService.deleteAnchor(CPS_PERFORMANCE_TEST_DATASPACE, 'writeAnchor')
where:
totalBooks || expectedDuration | memoryLimit
800 || 1 | 50
diff --git a/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-08-23.yang b/integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2023-11-27.yang
index bb7604d91a..e3152cb4a1 100644
--- a/cps-ncmp-service/src/main/resources/models/dmi-registry@2023-08-23.yang
+++ b/integration-test/src/test/resources/data/ncmp-registry/dmi-registry@2023-11-27.yang
@@ -8,6 +8,11 @@ module dmi-registry {
contact "toine.siebelink@est.tech";
+ revision "2023-11-27" {
+ description
+ "Added alternateId";
+ }
+
revision "2023-08-23" {
description
"Added ModuleSetTag";
@@ -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 {
}
}
}
+