summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checkstyle/pom.xml2
-rw-r--r--cps-application/pom.xml2
-rw-r--r--cps-application/src/main/resources/application.yml2
-rw-r--r--cps-bom/pom.xml2
-rw-r--r--cps-dependencies/pom.xml7
-rw-r--r--cps-events/pom.xml2
-rw-r--r--cps-ncmp-events/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml2
-rw-r--r--cps-ncmp-rest-stub/pom.xml2
-rw-r--r--cps-ncmp-rest/pom.xml2
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java21
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java3
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy47
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy33
-rw-r--r--cps-ncmp-service/pom.xml6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java)39
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java)22
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java)49
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java122
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/HttpClientConfiguration.java46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java)4
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy (renamed from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy)54
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/HttpClientConfigurationSpec.groovy3
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy (renamed from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy)5
-rw-r--r--cps-ncmp-service/src/test/resources/application.yml2
-rw-r--r--cps-parent/pom.xml2
-rw-r--r--cps-path-parser/pom.xml2
-rw-r--r--cps-rest/pom.xml2
-rw-r--r--cps-ri/pom.xml2
-rw-r--r--cps-service/pom.xml2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java10
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml2
-rw-r--r--dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml2
-rw-r--r--dmi-plugin-demo-and-csit-stub/pom.xml2
-rw-r--r--docs/api/swagger/cps/openapi.yaml138
-rw-r--r--docs/release-notes.rst51
-rw-r--r--integration-test/pom.xml2
-rw-r--r--jacoco-report/pom.xml2
-rw-r--r--k6-tests/ncmp/1-create-cmhandles.js36
-rw-r--r--k6-tests/ncmp/10-mixed-load-test.js15
-rw-r--r--k6-tests/ncmp/11-delete-cmhandles.js22
-rw-r--r--k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js34
-rw-r--r--k6-tests/ncmp/3-passthrough-read.js16
-rw-r--r--k6-tests/ncmp/4-id-search-no-filter.js4
-rw-r--r--k6-tests/ncmp/5-search-no-filter.js4
-rw-r--r--k6-tests/ncmp/6-id-search-public-property.js4
-rw-r--r--k6-tests/ncmp/7-search-public-property.js4
-rw-r--r--k6-tests/ncmp/8-id-search-module.js4
-rw-r--r--k6-tests/ncmp/9-search-module.js4
-rw-r--r--k6-tests/ncmp/common/cmhandle-crud.js90
-rw-r--r--k6-tests/ncmp/common/passthrough-read.js36
-rw-r--r--k6-tests/ncmp/common/search-base.js (renamed from k6-tests/ncmp/search-base.js)14
-rw-r--r--k6-tests/ncmp/common/utils.js (renamed from k6-tests/ncmp/utils.js)13
-rwxr-xr-xk6-tests/ncmp/run-all-tests.sh6
-rw-r--r--pom.xml2
-rw-r--r--releases/3.5.0-container.yaml8
-rw-r--r--releases/3.5.0.yaml4
-rw-r--r--spotbugs/pom.xml2
-rw-r--r--version.properties2
63 files changed, 643 insertions, 389 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml
index 9ecfa2d329..0f328e6ceb 100644
--- a/checkstyle/pom.xml
+++ b/checkstyle/pom.xml
@@ -26,7 +26,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>checkstyle</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<profiles>
<profile>
diff --git a/cps-application/pom.xml b/cps-application/pom.xml
index abcb88f4a3..8ab314ea5b 100644
--- a/cps-application/pom.xml
+++ b/cps-application/pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index 4f08bb61a0..6f0807113d 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -194,12 +194,14 @@ ncmp:
readTimeoutInSeconds: 30
writeTimeoutInSeconds: 30
maximumConnectionsTotal: 100
+ pendingAcquireMaxCount: 50
maximumInMemorySizeInMegabytes: 16
model-services:
connectionTimeoutInSeconds: 30
readTimeoutInSeconds: 30
writeTimeoutInSeconds: 30
maximumConnectionsTotal: 100
+ pendingAcquireMaxCount: 50
maximumInMemorySizeInMegabytes: 16
auth:
username: ${DMI_USERNAME:cpsuser}
diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml
index 4548eb21c3..93274b810a 100644
--- a/cps-bom/pom.xml
+++ b/cps-bom/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-bom</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<packaging>pom</packaging>
<description>This artifact contains dependencyManagement declarations of all published CPS components.</description>
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index a50a420b05..380c00a391 100644
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -27,7 +27,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-dependencies</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
@@ -129,6 +129,11 @@
<version>4.2.3</version>
</dependency>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>annotations</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
diff --git a/cps-events/pom.xml b/cps-events/pom.xml
index ec0c96bc24..1af13cc918 100644
--- a/cps-events/pom.xml
+++ b/cps-events/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-events/pom.xml b/cps-ncmp-events/pom.xml
index 3804e5bd21..befae04f8d 100644
--- a/cps-ncmp-events/pom.xml
+++ b/cps-ncmp-events/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
index 7b277cdb3a..6e21c0475c 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-app/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-ncmp-rest-stub</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
</parent>
<artifactId>cps-ncmp-rest-stub-app</artifactId>
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
index cb655320f5..15c79683f2 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-ncmp-rest-stub</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
</parent>
<artifactId>cps-ncmp-rest-stub-service</artifactId>
diff --git a/cps-ncmp-rest-stub/pom.xml b/cps-ncmp-rest-stub/pom.xml
index 441ce43f45..9fad293173 100644
--- a/cps-ncmp-rest-stub/pom.xml
+++ b/cps-ncmp-rest-stub/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index e333344798..7faec78ec7 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
index 5b54ac243e..58d6ce7108 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
@@ -39,6 +39,9 @@ import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler;
+import org.onap.cps.ncmp.api.impl.NcmpDatastoreRequestHandler;
+import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler;
import org.onap.cps.ncmp.api.impl.config.embeddedcache.TrustLevelCacheConfig;
import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
@@ -48,9 +51,6 @@ import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
import org.onap.cps.ncmp.api.models.CmResourceAddress;
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler;
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreRequestHandler;
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler;
import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper;
import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper;
import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
@@ -62,6 +62,7 @@ import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState;
import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
import org.onap.cps.ncmp.rest.util.DeprecationHelper;
+import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleDefinition;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -112,16 +113,18 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final String authorization) {
final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName);
final CmResourceAddress cmResourceAddress = new CmResourceAddress(datastoreName, cmHandle, resourceIdentifier);
- return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, topicParamInQuery,
- includeDescendants, authorization);
+ final Object result = ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery,
+ topicParamInQuery, includeDescendants, authorization);
+ return ResponseEntity.ok(result);
}
@Override
public ResponseEntity<Object> executeDataOperationForCmHandles(final String topicParamInQuery,
final DataOperationRequest dataOperationRequest,
final String authorization) {
- return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery,
+ final Object result = ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery,
dataOperationRequestMapper.toDataOperationRequest(dataOperationRequest), authorization);
+ return ResponseEntity.ok(result);
}
/**
@@ -133,7 +136,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* @param optionsParamInQuery options query parameter
* @param topicParamInQuery topic query parameter
* @param includeDescendants whether to include descendants or not
- * @return {@code ResponseEntity} response from dmi plugin
+ * @return {@code ResponseEntity} response. Body contains a collection of DataNodes
*/
@Override
@@ -144,7 +147,9 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final String topicParamInQuery,
final Boolean includeDescendants) {
validateDataStore(OPERATIONAL, datastoreName);
- return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants);
+ final Collection<DataNode> dataNodes = ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath,
+ includeDescendants);
+ return ResponseEntity.ok(dataNodes);
}
/**
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
index 7263000896..ba39178c7b 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
@@ -29,6 +29,9 @@ import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
+import org.onap.cps.ncmp.exceptions.InvalidTopicException;
+import org.onap.cps.ncmp.exceptions.OperationNotSupportedException;
+import org.onap.cps.ncmp.exceptions.PayloadTooLargeException;
import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController;
import org.onap.cps.ncmp.rest.controller.NetworkCmProxyInventoryController;
import org.onap.cps.ncmp.rest.model.DmiErrorMessage;
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
index 3a5748f002..34b9dbe950 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
@@ -23,42 +23,26 @@
package org.onap.cps.ncmp.rest.controller
-import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores
-import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational
-import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL
-import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL
-import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING
-import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE
-import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE
-import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH
-import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
-
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.read.ListAppender
import com.fasterxml.jackson.databind.ObjectMapper
+import groovy.json.JsonSlurper
import org.mapstruct.factory.Mappers
import org.onap.cps.TestUtils
import org.onap.cps.events.EventsPublisher
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.NetworkCmProxyQueryService
+import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler
+import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler
import org.onap.cps.ncmp.api.impl.inventory.CmHandleState
import org.onap.cps.ncmp.api.impl.inventory.CompositeState
import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState
import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory
import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.ncmp.api.models.CmResourceAddress
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper
import org.onap.cps.ncmp.rest.model.DataOperationDefinition
@@ -75,15 +59,32 @@ import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
import org.springframework.test.web.servlet.MockMvc
+import reactor.core.publisher.Mono
import spock.lang.Shared
import spock.lang.Specification
+
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
-import groovy.json.JsonSlurper
-import org.springframework.http.ResponseEntity
-import reactor.core.publisher.Mono
+
+import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores
+import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational
+import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL
+import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL
+import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING
+import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE
+import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE
+import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH
+import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE
+import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
@WebMvcTest(NetworkCmProxyController)
class NetworkCmProxyControllerSpec extends Specification {
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
index 33eb48ffa2..af8a8ea12a 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -21,28 +21,17 @@
package org.onap.cps.ncmp.rest.exceptions
-import static org.springframework.http.HttpStatus.BAD_GATEWAY
-import static org.springframework.http.HttpStatus.BAD_REQUEST
-import static org.springframework.http.HttpStatus.CONFLICT
-import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
-import static org.springframework.http.HttpStatus.NOT_FOUND
-import static org.springframework.http.HttpStatus.PAYLOAD_TOO_LARGE
-import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP
-import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA
-
import groovy.json.JsonSlurper
import org.mapstruct.factory.Mappers
import org.onap.cps.TestUtils
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
+import org.onap.cps.ncmp.api.impl.NcmpCachedResourceRequestHandler
+import org.onap.cps.ncmp.api.impl.NcmpPassthroughResourceRequestHandler
import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException
+import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
+import org.onap.cps.ncmp.exceptions.PayloadTooLargeException
import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler
-import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler
import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper
import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper
import org.onap.cps.ncmp.rest.util.DeprecationHelper
@@ -60,6 +49,18 @@ import org.springframework.test.web.servlet.MockMvc
import spock.lang.Shared
import spock.lang.Specification
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA
+import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP
+import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY
+import static org.springframework.http.HttpStatus.BAD_GATEWAY
+import static org.springframework.http.HttpStatus.BAD_REQUEST
+import static org.springframework.http.HttpStatus.CONFLICT
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
+import static org.springframework.http.HttpStatus.NOT_FOUND
+import static org.springframework.http.HttpStatus.PAYLOAD_TOO_LARGE
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
+
@WebMvcTest
class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@@ -125,7 +126,7 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
'Data Node Not Found' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | 'DataNode not found'
'Existing entry' | new AlreadyDefinedException('name',null) || CONFLICT | 'Already defined exception' | 'name already exists'
'Existing entries' | AlreadyDefinedException.forDataNodes(['A', 'B'], 'myAnchorName') || CONFLICT | 'Already defined exception' | '2 data node(s) already exist'
- 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs'
+ 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs'
}
def 'Post request with exception returns correct HTTP Status.'() {
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index 55abffc9bf..1f94b34ea6 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
@@ -74,6 +74,10 @@
<artifactId>cps-path-parser</artifactId>
</dependency>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>annotations</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
</dependency>
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java
index 80e1c442e9..eb43718f02 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpCachedResourceRequestHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandler.java
@@ -18,50 +18,39 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.controller.handlers;
+package org.onap.cps.ncmp.api.impl;
import java.util.Collection;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
import org.onap.cps.ncmp.api.NetworkCmProxyQueryService;
import org.onap.cps.ncmp.api.models.CmResourceAddress;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
-@Component
+@Service
+@RequiredArgsConstructor
public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandler {
private final NetworkCmProxyDataService networkCmProxyDataService;
private final NetworkCmProxyQueryService networkCmProxyQueryService;
/**
- * Constructor.
- *
- * @param networkCmProxyDataService @see org.onap.cps.ncmp.api.NetworkCmProxyDataService
- * @param networkCmProxyQueryService @see org.onap.cps.ncmp.api.NetworkCmProxyQueryService
- */
- public NcmpCachedResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService,
- final NetworkCmProxyQueryService networkCmProxyQueryService) {
- this.networkCmProxyDataService = networkCmProxyDataService;
- this.networkCmProxyQueryService = networkCmProxyQueryService;
- }
-
- /**
* Executes a synchronous query request for given cm handle.
* Note. Currently only ncmp-datastore:operational supports query operations.
*
* @param cmHandleId the cm handle
* @param resourceIdentifier the resource identifier
* @param includeDescendants whether include descendants
- * @return the response entity
+ * @return a collection of data nodes
*/
- public ResponseEntity<Object> executeRequest(final String cmHandleId, final String resourceIdentifier,
+ public Collection<DataNode> executeRequest(final String cmHandleId, final String resourceIdentifier,
final boolean includeDescendants) {
- final Collection<DataNode> dataNodes = getTaskSupplierForQueryRequest(cmHandleId, resourceIdentifier,
- includeDescendants);
- return ResponseEntity.ok(dataNodes);
+ final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
+ return networkCmProxyQueryService.queryResourceDataOperational(cmHandleId, resourceIdentifier,
+ fetchDescendantsOption);
}
@Override
@@ -76,14 +65,6 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle
() -> networkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, fetchDescendantsOption));
}
- private Collection<DataNode> getTaskSupplierForQueryRequest(final String cmHandleId,
- final String resourceIdentifier,
- final boolean includeDescendants) {
- final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
- return networkCmProxyQueryService.queryResourceDataOperational(cmHandleId, resourceIdentifier,
- fetchDescendantsOption);
- }
-
private static FetchDescendantsOption getFetchDescendantsOption(final boolean includeDescendants) {
return includeDescendants ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
: FetchDescendantsOption.OMIT_DESCENDANTS;
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java
index 20059e20f4..dbd2bb4938 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandler.java
@@ -18,22 +18,19 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.controller.handlers;
+package org.onap.cps.ncmp.api.impl;
import java.util.Map;
import java.util.UUID;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.models.CmResourceAddress;
-import org.onap.cps.ncmp.rest.util.TopicValidator;
+import org.onap.cps.ncmp.utils.TopicValidator;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Slf4j
@Service
-@RequiredArgsConstructor
public abstract class NcmpDatastoreRequestHandler {
private static final String NO_REQUEST_ID = null;
@@ -52,9 +49,10 @@ public abstract class NcmpDatastoreRequestHandler {
* @param topicParamInQuery the topic param in query
* @param includeDescendants whether include descendants
* @param authorization contents of Authorization header, or null if not present
- * @return the response entity
+ * @return the result object, depends on use op topic. With topic a map object with request id is returned
+ * otherwise the result of the request.
*/
- public ResponseEntity<Object> executeRequest(final CmResourceAddress cmResourceAddress,
+ public Object executeRequest(final CmResourceAddress cmResourceAddress,
final String optionsParamInQuery,
final String topicParamInQuery,
final boolean includeDescendants,
@@ -72,14 +70,10 @@ public abstract class NcmpDatastoreRequestHandler {
}
final Mono<Object> resourceDataMono = getResourceDataForCmHandle(cmResourceAddress, optionsParamInQuery,
NO_TOPIC, NO_REQUEST_ID, includeDescendants, authorization);
- return fetchResourceDataSynchronously(resourceDataMono);
+ return resourceDataMono.block();
}
- private ResponseEntity<Object> fetchResourceDataSynchronously(final Mono<Object> resourceDataMono) {
- return ResponseEntity.ok(resourceDataMono.block());
- }
-
- private ResponseEntity<Object> fetchResourceDataAsynchronously(final CmResourceAddress cmResourceAddress,
+ private Map<String, String> fetchResourceDataAsynchronously(final CmResourceAddress cmResourceAddress,
final String optionsParamInQuery,
final String topicParamInQuery,
final boolean includeDescendants,
@@ -93,7 +87,7 @@ public abstract class NcmpDatastoreRequestHandler {
log.error("Async operation failed for request id {}: {}", requestId, error.getMessage()))
.subscribe();
log.debug("Received Async request with id {}", requestId);
- return ResponseEntity.ok(Map.of("requestId", requestId));
+ return Map.of("requestId", requestId);
}
protected abstract Mono<Object> getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress,
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java
index 53e374d30a..90d9a23d6d 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/handlers/NcmpPassthroughResourceRequestHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NcmpPassthroughResourceRequestHandler.java
@@ -18,27 +18,28 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.controller.handlers;
+package org.onap.cps.ncmp.api.impl;
import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL;
import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ;
import java.util.Map;
import java.util.UUID;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
import org.onap.cps.ncmp.api.impl.operations.OperationType;
import org.onap.cps.ncmp.api.models.CmResourceAddress;
import org.onap.cps.ncmp.api.models.DataOperationRequest;
-import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException;
-import org.onap.cps.ncmp.rest.exceptions.PayloadTooLargeException;
-import org.onap.cps.ncmp.rest.util.TopicValidator;
-import org.springframework.http.ResponseEntity;
+import org.onap.cps.ncmp.exceptions.OperationNotSupportedException;
+import org.onap.cps.ncmp.exceptions.PayloadTooLargeException;
+import org.onap.cps.ncmp.utils.TopicValidator;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Service
+@RequiredArgsConstructor
public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestHandler {
private final NetworkCmProxyDataService networkCmProxyDataService;
@@ -46,32 +47,26 @@ public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestH
private static final String PAYLOAD_TOO_LARGE_TEMPLATE = "Operation '%s' affects too many (%d) cm handles";
/**
- * Constructor.
- *
- * @param networkCmProxyDataService @see org.onap.cps.ncmp.api.NetworkCmProxyDataService
- */
- public NcmpPassthroughResourceRequestHandler(final NetworkCmProxyDataService networkCmProxyDataService) {
- this.networkCmProxyDataService = networkCmProxyDataService;
- }
-
- /**
* Executes asynchronous request for group of cm handles to resource data.
*
* @param topicParamInQuery the topic param in query
* @param dataOperationRequest data operation request details for resource data
* @param authorization contents of Authorization header, or null if not present
- * @return the response entity
+ * @return a map with one entry of request Id for success or status and error when async feature is disabled
*/
- public ResponseEntity<Object> executeRequest(final String topicParamInQuery,
- final DataOperationRequest dataOperationRequest,
- final String authorization) {
+ public Map<String, String> executeRequest(final String topicParamInQuery,
+ final DataOperationRequest dataOperationRequest,
+ final String authorization) {
validateDataOperationRequest(topicParamInQuery, dataOperationRequest);
if (!notificationFeatureEnabled) {
- return ResponseEntity.ok(Map.of("status",
- "Asynchronous request is unavailable as notification feature is currently disabled."));
+ return Map.of("status",
+ "Asynchronous request is unavailable as notification feature is currently disabled.");
}
- return getRequestIdAndSendDataOperationRequestToDmiService(topicParamInQuery, dataOperationRequest,
- authorization);
+ final String requestId = UUID.randomUUID().toString();
+ networkCmProxyDataService.executeDataOperationForCmHandles(topicParamInQuery, dataOperationRequest, requestId,
+ authorization);
+ return Map.of("requestId", requestId);
+
}
@Override
@@ -85,16 +80,6 @@ public class NcmpPassthroughResourceRequestHandler extends NcmpDatastoreRequestH
topicParamInQuery, requestId, authorization);
}
- private ResponseEntity<Object> getRequestIdAndSendDataOperationRequestToDmiService(
- final String topicParamInQuery,
- final DataOperationRequest dataOperationRequest,
- final String authorization) {
- final String requestId = UUID.randomUUID().toString();
- networkCmProxyDataService.executeDataOperationForCmHandles(topicParamInQuery, dataOperationRequest, requestId,
- authorization);
- return ResponseEntity.ok(Map.of("requestId", requestId));
- }
-
private void validateDataOperationRequest(final String topicParamInQuery,
final DataOperationRequest dataOperationRequest) {
TopicValidator.validateTopicName(topicParamInQuery);
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
index 08885a9e04..3a861a68b4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
@@ -20,9 +20,12 @@
package org.onap.cps.ncmp.api.impl.config;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
+import io.netty.resolver.DefaultAddressResolverGroup;
+import java.time.Duration;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
@@ -35,8 +38,9 @@ import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
/**
- * Configures and creates a WebClient bean that triggers an initialization (warmup) of the host name resolver and
- * loads the necessary native libraries to avoid the extra time needed to load resources for first request.
+ * Configures and creates WebClient beans for various DMI services including data, model, and health check services.
+ * The configuration utilizes Netty-based HttpClient with custom connection settings, read and write timeouts,
+ * and initializes WebClient with these settings to ensure optimal performance and resource management.
*/
@Configuration
@RequiredArgsConstructor
@@ -44,82 +48,98 @@ public class DmiWebClientConfiguration {
private final HttpClientConfiguration httpClientConfiguration;
+ private static final Duration DEFAULT_RESPONSE_TIMEOUT = Duration.ofSeconds(30);
+
/**
- * Configures and create a WebClient bean for DMI data service.
+ * Configures and creates a WebClient bean for DMI data services.
*
- * @return a WebClient instance for data services.
+ * @return a WebClient instance configured for data services.
*/
@Bean
public WebClient dataServicesWebClient() {
- final HttpClientConfiguration.DataServices httpClientConfiguration
- = this.httpClientConfiguration.getDataServices();
-
- final HttpClient httpClient = createHttpClient("dataConnectionPool",
- httpClientConfiguration.getMaximumConnectionsTotal(),
- httpClientConfiguration.getConnectionTimeoutInSeconds(),
- httpClientConfiguration.getReadTimeoutInSeconds(),
- httpClientConfiguration.getWriteTimeoutInSeconds());
- return buildAndGetWebClient(httpClient, httpClientConfiguration.getMaximumInMemorySizeInMegabytes());
+ final HttpClientConfiguration.DataServices dataServiceConfig = httpClientConfiguration.getDataServices();
+ final ConnectionProvider dataServicesConnectionProvider
+ = getConnectionProvider(dataServiceConfig.getConnectionProviderName(),
+ dataServiceConfig.getMaximumConnectionsTotal(), dataServiceConfig.getPendingAcquireMaxCount());
+ final HttpClient dataServicesHttpClient = createHttpClient(dataServiceConfig, dataServicesConnectionProvider);
+ return buildAndGetWebClient(dataServicesHttpClient, dataServiceConfig.getMaximumInMemorySizeInMegabytes());
}
/**
- * Configures and creates a WebClient bean for DMI model service.
+ * Configures and creates a WebClient bean for DMI model services.
*
- * @return a WebClient instance for model services.
+ * @return a WebClient instance configured for model services.
*/
@Bean
public WebClient modelServicesWebClient() {
- final HttpClientConfiguration.ModelServices httpClientConfiguration
- = this.httpClientConfiguration.getModelServices();
-
- final HttpClient httpClient = createHttpClient("modelConnectionPool",
- httpClientConfiguration.getMaximumConnectionsTotal(),
- httpClientConfiguration.getConnectionTimeoutInSeconds(),
- httpClientConfiguration.getReadTimeoutInSeconds(),
- httpClientConfiguration.getWriteTimeoutInSeconds());
- return buildAndGetWebClient(httpClient, httpClientConfiguration.getMaximumInMemorySizeInMegabytes());
+ final HttpClientConfiguration.ModelServices modelServiceConfig = httpClientConfiguration.getModelServices();
+ final ConnectionProvider modelServicesConnectionProvider
+ = getConnectionProvider(modelServiceConfig.getConnectionProviderName(),
+ modelServiceConfig.getMaximumConnectionsTotal(),
+ modelServiceConfig.getPendingAcquireMaxCount());
+ final HttpClient modelServicesHttpClient
+ = createHttpClient(modelServiceConfig, modelServicesConnectionProvider);
+ return buildAndGetWebClient(modelServicesHttpClient, modelServiceConfig.getMaximumInMemorySizeInMegabytes());
}
/**
- * Configures and creates a WebClient bean for DMI health service.
+ * Configures and creates a WebClient bean for DMI health check services.
*
- * @return a WebClient instance for health checks.
+ * @return a WebClient instance configured for health check services.
*/
@Bean
public WebClient healthChecksWebClient() {
- final HttpClientConfiguration.HealthCheckServices httpClientConfiguration
- = this.httpClientConfiguration.getHealthCheckServices();
+ final HttpClientConfiguration.HealthCheckServices healthCheckServiceConfig
+ = httpClientConfiguration.getHealthCheckServices();
+ final ConnectionProvider healthChecksConnectionProvider
+ = getConnectionProvider(healthCheckServiceConfig.getConnectionProviderName(),
+ healthCheckServiceConfig.getMaximumConnectionsTotal(),
+ healthCheckServiceConfig.getPendingAcquireMaxCount());
+ final HttpClient healthChecksHttpClient
+ = createHttpClient(healthCheckServiceConfig, healthChecksConnectionProvider);
+ return buildAndGetWebClient(healthChecksHttpClient,
+ healthCheckServiceConfig.getMaximumInMemorySizeInMegabytes());
+ }
- final HttpClient httpClient = createHttpClient("healthConnectionPool",
- httpClientConfiguration.getMaximumConnectionsTotal(),
- httpClientConfiguration.getConnectionTimeoutInSeconds(),
- httpClientConfiguration.getReadTimeoutInSeconds(),
- httpClientConfiguration.getWriteTimeoutInSeconds());
- return buildAndGetWebClient(httpClient, httpClientConfiguration.getMaximumInMemorySizeInMegabytes());
+ /**
+ * Provides a WebClient.Builder bean for creating WebClient instances.
+ *
+ * @return a WebClient.Builder instance.
+ */
+ @Bean
+ public WebClient.Builder webClientBuilder() {
+ return WebClient.builder();
}
- private static HttpClient createHttpClient(final String connectionProviderName,
- final Integer maximumConnectionsTotal,
- final Integer connectionTimeoutInSeconds,
- final Integer readTimeoutInSeconds,
- final Integer writeTimeoutInSeconds) {
- final ConnectionProvider dmiWebClientConnectionProvider = ConnectionProvider.create(connectionProviderName,
- maximumConnectionsTotal);
+ private static HttpClient createHttpClient(final HttpClientConfiguration.ServiceConfig serviceConfig,
+ final ConnectionProvider connectionProvider) {
+ return HttpClient.create(connectionProvider)
+ .responseTimeout(DEFAULT_RESPONSE_TIMEOUT)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, serviceConfig.getConnectionTimeoutInSeconds() * 1000)
+ .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(
+ serviceConfig.getReadTimeoutInSeconds(), TimeUnit.SECONDS)).addHandlerLast(
+ new WriteTimeoutHandler(serviceConfig.getWriteTimeoutInSeconds(), TimeUnit.SECONDS)))
+ .resolver(DefaultAddressResolverGroup.INSTANCE)
+ .compress(true);
+ }
- return HttpClient.create(dmiWebClientConnectionProvider)
- .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeoutInSeconds * 1000)
- .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(readTimeoutInSeconds,
- TimeUnit.SECONDS)).addHandlerLast(new WriteTimeoutHandler(writeTimeoutInSeconds,
- TimeUnit.SECONDS)));
+ @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE")
+ private static ConnectionProvider getConnectionProvider(final String connectionProviderName,
+ final int maximumConnectionsTotal,
+ final int pendingAcquireMaxCount) {
+ return ConnectionProvider.builder(connectionProviderName)
+ .maxConnections(maximumConnectionsTotal)
+ .pendingAcquireMaxCount(pendingAcquireMaxCount)
+ .build();
}
- private static WebClient buildAndGetWebClient(final HttpClient httpClient,
- final Integer maximumInMemorySizeInMegabytes) {
- return WebClient.builder()
+ private WebClient buildAndGetWebClient(final HttpClient httpClient,
+ final int maximumInMemorySizeInMegabytes) {
+ return webClientBuilder()
.defaultHeaders(header -> header.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))
.defaultHeaders(header -> header.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
.clientConnector(new ReactorClientHttpConnector(httpClient))
- .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(
- maximumInMemorySizeInMegabytes * 1024 * 1024)).build();
+ .codecs(configurer -> configurer.defaultCodecs()
+ .maxInMemorySize(maximumInMemorySizeInMegabytes * 1024 * 1024)).build();
}
}
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
index 62432f6cae..0acbabbbaf 100644
--- 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
@@ -23,11 +23,11 @@ package org.onap.cps.ncmp.api.impl.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
+import org.springframework.context.annotation.Configuration;
@Getter
@Setter
-@Component
+@Configuration
@ConfigurationProperties(prefix = "ncmp.dmi.httpclient")
public class HttpClientConfiguration {
@@ -37,30 +37,36 @@ public class HttpClientConfiguration {
@Getter
@Setter
- public static class DataServices {
- private Integer maximumConnectionsTotal = 100;
- private Integer connectionTimeoutInSeconds = 30;
- private Integer readTimeoutInSeconds = 30;
- private Integer writeTimeoutInSeconds = 30;
- private Integer maximumInMemorySizeInMegabytes = 1;
+ public static class DataServices extends ServiceConfig {
+ private String connectionProviderName = "dataConnectionPool";
}
@Getter
@Setter
- public static class ModelServices {
- private Integer maximumConnectionsTotal = 100;
- private Integer connectionTimeoutInSeconds = 30;
- private Integer readTimeoutInSeconds = 30;
- private Integer writeTimeoutInSeconds = 30;
- private Integer maximumInMemorySizeInMegabytes = 1;
+ public static class ModelServices extends ServiceConfig {
+ private String connectionProviderName = "modelConnectionPool";
+ }
+
+ @Getter
+ @Setter
+ public static class HealthCheckServices extends ServiceConfig {
+ private String connectionProviderName = "healthConnectionPool";
+ private int maximumConnectionsTotal = 10;
+ private int pendingAcquireMaxCount = 5;
}
+ /**
+ * Base configuration properties for all services.
+ */
@Getter
- public static class HealthCheckServices {
- private final Integer maximumConnectionsTotal = 10;
- private final Integer connectionTimeoutInSeconds = 30;
- private final Integer readTimeoutInSeconds = 30;
- private final Integer writeTimeoutInSeconds = 30;
- private final Integer maximumInMemorySizeInMegabytes = 1;
+ @Setter
+ public static class ServiceConfig {
+ private String connectionProviderName = "cpsConnectionPool";
+ private int maximumConnectionsTotal = 100;
+ private int pendingAcquireMaxCount = 50;
+ private Integer connectionTimeoutInSeconds = 30;
+ private long readTimeoutInSeconds = 30;
+ private long writeTimeoutInSeconds = 30;
+ private int maximumInMemorySizeInMegabytes = 1;
}
}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java
index 6a52d5861e..fcf2a28ccc 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/InvalidTopicException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/InvalidTopicException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.exceptions;
+package org.onap.cps.ncmp.exceptions;
import lombok.Getter;
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java
index e1daf3df6f..d75c0bd47a 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/OperationNotSupportedException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/OperationNotSupportedException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.exceptions;
+package org.onap.cps.ncmp.exceptions;
public class OperationNotSupportedException extends RuntimeException {
/**
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java
index cddbd08379..dc7057af79 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/PayloadTooLargeException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/exceptions/PayloadTooLargeException.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.exceptions;
+package org.onap.cps.ncmp.exceptions;
public class PayloadTooLargeException extends RuntimeException {
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java
index 6a46fbd638..f9fed8d437 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/util/TopicValidator.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/TopicValidator.java
@@ -18,12 +18,12 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.util;
+package org.onap.cps.ncmp.utils;
import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
-import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException;
+import org.onap.cps.ncmp.exceptions.InvalidTopicException;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TopicValidator {
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy
index 00b0cb04c5..b73f9a46d4 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/handlers/NcmpDatastoreRequestHandlerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy
@@ -18,20 +18,20 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.controller.handlers
+package org.onap.cps.ncmp.api.impl
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException
import org.onap.cps.ncmp.api.impl.exception.InvalidOperationException
+import org.onap.cps.ncmp.api.models.CmResourceAddress
import org.onap.cps.ncmp.api.models.DataOperationDefinition
import org.onap.cps.ncmp.api.models.DataOperationRequest
-import org.onap.cps.ncmp.api.models.CmResourceAddress
-import org.onap.cps.ncmp.rest.exceptions.OperationNotSupportedException
-import org.onap.cps.ncmp.rest.exceptions.PayloadTooLargeException
+import org.onap.cps.ncmp.exceptions.OperationNotSupportedException
+import org.onap.cps.ncmp.exceptions.PayloadTooLargeException
import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
import reactor.core.publisher.Mono
import spock.lang.Specification
-import spock.util.concurrent.PollingConditions
class NcmpDatastoreRequestHandlerSpec extends Specification {
@@ -50,19 +50,26 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled
and: 'a CM resource address'
def cmResourceAddress = new CmResourceAddress('ds', 'ch1', 'resource1')
- and: 'the (mocked) service is called with the correct parameters returns OK'
- 1 * mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >> Mono.just(HttpStatus.OK)
+ and: 'the (mocked) service when called with the correct parameters returns a response from dmi'
+ def resultFromDmi = new ResponseEntity('response from dmi',HttpStatus.I_AM_A_TEAPOT)
+ def synchronousResult = Mono.justOrEmpty(resultFromDmi)
+ mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >> synchronousResult
when: 'get request is executed with topic = #topic'
- def response= objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER)
- then: 'a successful response with/without request id is returned'
- assert response.statusCode.value == 200
- assert response.body instanceof Map == expectedResponseBodyIsMap
+ def response = objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER)
+ then: 'a successful result with/without request id is returned'
+ if (expectSynchronousResponse) {
+ assert response.toString().contains('response from dmi')
+ assert response.toString().contains("I'm a teapot")
+ } else {
+ // expect request id in a map
+ assert response.keySet()[0] == 'requestId'
+ }
where: 'the following parameters are used'
- scenario | notificationFeatureEnabled | topic || expectedCalls | expectedResponseBodyIsMap
- 'feature on, valid topic' | true | 'valid' || 1 | true
- 'feature on, no topic' | true | null || 0 | false
- 'feature off, valid topic' | false | 'valid' || 0 | false
- 'feature off, no topic' | false | null || 0 | false
+ scenario | notificationFeatureEnabled | topic || expectSynchronousResponse
+ 'feature on, valid topic' | true | 'valid' || false
+ 'feature on, no topic' | true | null || true
+ 'feature off, valid topic' | false | 'valid' || true
+ 'feature off, no topic' | false | null || true
}
def 'Attempt to execute async data operation request with feature #scenario.'() {
@@ -86,21 +93,12 @@ class NcmpDatastoreRequestHandlerSpec extends Specification {
and: 'a data operation request with datastore: #datastore'
def dataOperationDefinition = new DataOperationDefinition(operation: 'read', datastore: datastore)
def dataOperationRequest = new DataOperationRequest(dataOperationDefinitions: [dataOperationDefinition])
- and: ' a flag to track the network service call'
- def networkServiceMethodCalled = false
- and: 'the (mocked) service will use the flag to indicate it is called'
- mockNetworkCmProxyDataService.executeDataOperationForCmHandles('myTopic', dataOperationRequest, _, NO_AUTH_HEADER) >> {
- networkServiceMethodCalled = true
- }
when: 'data operation request is executed'
def response = objectUnderTest.executeRequest('myTopic', dataOperationRequest, NO_AUTH_HEADER)
- and: 'a successful response with request id is returned'
- assert response.statusCode.value == 200
- assert response.body.requestId != null
+ and: 'a map with request id is returned'
+ assert response.keySet()[0] == 'requestId'
then: 'the network service is invoked'
- new PollingConditions().within(1) {
- assert networkServiceMethodCalled == true
- }
+ 1 * mockNetworkCmProxyDataService.executeDataOperationForCmHandles('myTopic', dataOperationRequest, _, NO_AUTH_HEADER)
where: 'the following datastores are used'
datastore << ['ncmp-datastore:passthrough-running', 'ncmp-datastore:passthrough-operational']
}
diff --git a/cps-ncmp-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
index b7ced23828..228f412779 100644
--- 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
@@ -43,6 +43,7 @@ class HttpClientConfigurationSpec extends Specification {
assert readTimeoutInSeconds == 789
assert writeTimeoutInSeconds == 30
assert maximumConnectionsTotal == 100
+ assert pendingAcquireMaxCount == 22
assert maximumInMemorySizeInMegabytes == 7
}
}
@@ -54,6 +55,7 @@ class HttpClientConfigurationSpec extends Specification {
assert readTimeoutInSeconds == 30
assert writeTimeoutInSeconds == 30
assert maximumConnectionsTotal == 111
+ assert pendingAcquireMaxCount == 44
assert maximumInMemorySizeInMegabytes == 8
}
}
@@ -65,6 +67,7 @@ class HttpClientConfigurationSpec extends Specification {
assert readTimeoutInSeconds == 30
assert writeTimeoutInSeconds == 30
assert maximumConnectionsTotal == 10
+ assert pendingAcquireMaxCount == 5
assert maximumInMemorySizeInMegabytes == 1
}
}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy
index 15e2c1c6a0..f96502984d 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/TopicValidatorSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/utils/TopicValidatorSpec.groovy
@@ -18,9 +18,10 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.rest.util
+package org.onap.cps.ncmp.utils
-import org.onap.cps.ncmp.rest.exceptions.InvalidTopicException
+import org.onap.cps.ncmp.exceptions.InvalidTopicException
+import org.onap.cps.ncmp.utils.TopicValidator
import spock.lang.Specification
class TopicValidatorSpec extends Specification {
diff --git a/cps-ncmp-service/src/test/resources/application.yml b/cps-ncmp-service/src/test/resources/application.yml
index e35f471005..5b10e7376b 100644
--- a/cps-ncmp-service/src/test/resources/application.yml
+++ b/cps-ncmp-service/src/test/resources/application.yml
@@ -38,9 +38,11 @@ ncmp:
dmi:
httpclient:
data-services:
+ pendingAcquireMaxCount: 22
connectionTimeoutInSeconds: 123
maximumInMemorySizeInMegabytes: 7
model-services:
+ pendingAcquireMaxCount: 44
connectionTimeoutInSeconds: 456
maximumInMemorySizeInMegabytes: 8
auth:
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index 594aa1f0f5..591095abae 100644
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml
index 3176d9a471..633ec6bb80 100644
--- a/cps-path-parser/pom.xml
+++ b/cps-path-parser/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml
index ccfb77fb69..f7ddd6c382 100644
--- a/cps-rest/pom.xml
+++ b/cps-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 221e1a9bf2..14a091fcbd 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index 4224968778..2564ceb989 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -29,7 +29,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
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 6386d38ffc..5a48428772 100644
--- 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
@@ -65,6 +65,7 @@ public class CpsDataServiceImpl implements CpsDataService {
private static final String ROOT_NODE_XPATH = "/";
private static final long DEFAULT_LOCK_TIMEOUT_IN_MILLISECONDS = 300L;
+ private static final String NO_DATA_NODES = "No data nodes.";
private final CpsDataPersistenceService cpsDataPersistenceService;
private final CpsDataUpdateEventsService cpsDataUpdateEventsService;
@@ -425,7 +426,7 @@ public class CpsDataServiceImpl implements CpsDataService {
.withContainerNode(containerNode)
.buildCollection();
if (dataNodes.isEmpty()) {
- throw new DataValidationException("No data nodes.", "No data nodes provided");
+ throw new DataValidationException(NO_DATA_NODES, "No data nodes provided");
}
return dataNodes;
}
@@ -437,7 +438,7 @@ public class CpsDataServiceImpl implements CpsDataService {
.withContainerNode(containerNode)
.buildCollection();
if (dataNodes.isEmpty()) {
- throw new DataValidationException("No data nodes.", "No data nodes provided");
+ throw new DataValidationException(NO_DATA_NODES, "No data nodes provided");
}
return dataNodes;
}
@@ -453,8 +454,7 @@ public class CpsDataServiceImpl implements CpsDataService {
.withContainerNode(containerNode)
.buildCollection();
if (dataNodes.isEmpty()) {
- throw new DataValidationException("No data nodes.",
- "Data nodes were not found under the xpath " + xpath);
+ throw new DataValidationException(NO_DATA_NODES, "Data nodes were not found under the xpath " + xpath);
}
return dataNodes;
}
@@ -466,7 +466,7 @@ public class CpsDataServiceImpl implements CpsDataService {
.withContainerNode(containerNode)
.buildCollection();
if (dataNodes.isEmpty()) {
- throw new DataValidationException("No data nodes.", "Data nodes were not found under the xpath " + xpath);
+ throw new DataValidationException(NO_DATA_NODES, "Data nodes were not found under the xpath " + xpath);
}
return dataNodes;
}
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
index e62c01d6ca..3a678f6ddb 100644
--- a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-app/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
</parent>
<artifactId>dmi-plugin-demo-and-csit-stub-app</artifactId>
diff --git a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
index c0b4eadb1e..73469de596 100644
--- a/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/dmi-plugin-demo-and-csit-stub-service/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>dmi-plugin-demo-and-csit-stub</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
</parent>
<artifactId>dmi-plugin-demo-and-csit-stub-service</artifactId>
diff --git a/dmi-plugin-demo-and-csit-stub/pom.xml b/dmi-plugin-demo-and-csit-stub/pom.xml
index 0719272523..a61c985792 100644
--- a/dmi-plugin-demo-and-csit-stub/pom.xml
+++ b/dmi-plugin-demo-and-csit-stub/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/docs/api/swagger/cps/openapi.yaml b/docs/api/swagger/cps/openapi.yaml
index 2798b78643..7cba5816f2 100644
--- a/docs/api/swagger/cps/openapi.yaml
+++ b/docs/api/swagger/cps/openapi.yaml
@@ -1346,6 +1346,13 @@ paths:
schema:
example: 2021-03-21T00:10:34.030-0100
type: string
+ - description: Content type header
+ in: header
+ name: Content-Type
+ required: true
+ schema:
+ example: application/json
+ type: string
requestBody:
content:
application/json:
@@ -1354,7 +1361,16 @@ paths:
$ref: '#/components/examples/dataSample'
value: null
schema:
+ type: string
+ application/xml:
+ examples:
+ dataSample:
+ $ref: '#/components/examples/dataSampleXml'
+ value: null
+ schema:
type: object
+ xml:
+ name: stores
required: true
responses:
"200":
@@ -1896,7 +1912,7 @@ paths:
summary: Replace list content
tags:
- cps-data
- /v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/delta:
+ /v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/deltaAnchors:
get:
description: Get delta between two anchors within a given dataspace
operationId: getDeltaByDataspaceAndAnchors
@@ -1989,6 +2005,96 @@ paths:
tags:
- cps-data
x-codegen-request-body-name: xpath
+ /v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/deltaPayload:
+ post:
+ description: Get delta between an anchor in a dataspace and JSON payload
+ operationId: getDeltaByDataspaceAnchorAndPayload
+ parameters:
+ - description: dataspace-name
+ in: path
+ name: dataspace-name
+ required: true
+ schema:
+ example: my-dataspace
+ type: string
+ - description: anchor-name
+ in: path
+ name: anchor-name
+ required: true
+ schema:
+ example: my-anchor
+ type: string
+ - description: "For more details on xpath, please refer https://docs.onap.org/projects/onap-cps/en/latest/xpath.html"
+ examples:
+ container xpath:
+ value: /shops/bookstore
+ list attributes xpath:
+ value: "/shops/bookstore/categories[@code=1]"
+ in: query
+ name: xpath
+ required: false
+ schema:
+ default: /
+ type: string
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ $ref: '#/components/schemas/getDeltaByDataspaceAnchorAndPayload_request'
+ responses:
+ "200":
+ content:
+ application/json:
+ examples:
+ dataSample:
+ $ref: '#/components/examples/deltaReportSample'
+ value: null
+ schema:
+ type: object
+ description: OK
+ "400":
+ content:
+ application/json:
+ example:
+ status: 400
+ message: Bad Request
+ details: The provided request is not valid
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Bad Request
+ "401":
+ content:
+ application/json:
+ example:
+ status: 401
+ message: Unauthorized request
+ details: This request is unauthorized
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Unauthorized
+ "403":
+ content:
+ application/json:
+ example:
+ status: 403
+ message: Request Forbidden
+ details: This request is forbidden
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Forbidden
+ "500":
+ content:
+ application/json:
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Internal Server Error
+ summary: Get delta between an anchor and JSON payload
+ tags:
+ - cps-data
/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query:
get:
deprecated: true
@@ -2270,7 +2376,7 @@ components:
dataSampleXml:
value: <stores xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <bookstore xmlns="org:onap:ccsdk:sample">
<bookstore-name>Chapters</bookstore-name> <categories> <code>1</code> <name>SciFi</name>
- </categories> </bookstore> </stores>
+ <code>2</code> <name>kids</name> </categories> </bookstore> </stores>
deltaReportSample:
value:
- action: ADD
@@ -2530,6 +2636,16 @@ components:
schema:
type: object
description: OK
+ Unauthorized:
+ content:
+ application/json:
+ example:
+ status: 401
+ message: Unauthorized request
+ details: This request is unauthorized
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Unauthorized
schemas:
ErrorMessage:
properties:
@@ -2619,6 +2735,24 @@ components:
type: string
title: Module reference object
type: object
+ getDeltaByDataspaceAnchorAndPayload_request:
+ properties:
+ json:
+ example:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: 1
+ name: SciFi
+ - code: 2
+ name: kids
+ type: object
+ file:
+ format: binary
+ type: string
+ required:
+ - json
+ type: object
securitySchemes:
basicAuth:
scheme: basic
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index b9df799c9e..e14a725f72 100644
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -12,12 +12,12 @@ CPS Release Notes
:depth: 2
..
-.. =========================
-.. * * * NEW DELHI * * *
-.. =========================
+.. ====================
+.. * * * OSLO * * *
+.. ====================
-Version: 3.4.10
-===============
+Version: 3.5.1
+==============
Release Data
------------
@@ -26,10 +26,10 @@ Release Data
| **CPS Project** | |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Docker images** | onap/cps-and-ncmp:3.4.10 |
+| **Docker images** | onap/cps-and-ncmp:3.5.1 |
| | |
+--------------------------------------+--------------------------------------------------------+
-| **Release designation** | 3.4.10 New Delhi |
+| **Release designation** | 3.5.1 Oslo |
| | |
+--------------------------------------+--------------------------------------------------------+
| **Release date** | Not yet released |
@@ -38,10 +38,45 @@ Release Data
Bug Fixes
---------
-3.4.10
+3.5.1
+
+Features
+--------
+3.5.1
+
+Version: 3.5.0
+==============
+
+Release Data
+------------
+
++--------------------------------------+--------------------------------------------------------+
+| **CPS Project** | |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Docker images** | onap/cps-and-ncmp:3.5.0 |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release designation** | 3.5.0 Oslo |
+| | |
++--------------------------------------+--------------------------------------------------------+
+| **Release date** | 2024 June 20 |
+| | |
++--------------------------------------+--------------------------------------------------------+
+
+Bug Fixes
+---------
+3.5.0
Features
--------
+3.5.0
+ - `CPS-989 <https://jira.onap.org/browse/CPS-989>`_ Replace RestTemplate with WebClient.
+ - `CPS-2172 <https://jira.onap.org/browse/CPS-2172>`_ Support for OpenTelemetry Tracing.
+
+.. =========================
+.. * * * NEW DELHI * * *
+.. =========================
Version: 3.4.9
==============
diff --git a/integration-test/pom.xml b/integration-test/pom.xml
index f228e01194..a3112661e9 100644
--- a/integration-test/pom.xml
+++ b/integration-test/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml
index 447614f396..01d47bfb03 100644
--- a/jacoco-report/pom.xml
+++ b/jacoco-report/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/k6-tests/ncmp/1-create-cmhandles.js b/k6-tests/ncmp/1-create-cmhandles.js
index 60594c7127..1c64ab011c 100644
--- a/k6-tests/ncmp/1-create-cmhandles.js
+++ b/k6-tests/ncmp/1-create-cmhandles.js
@@ -18,21 +18,13 @@
* ============LICENSE_END=========================================================
*/
-import http from 'k6/http';
import exec from 'k6/execution';
-import { check } from 'k6';
-import {
- NCMP_BASE_URL,
- DMI_PLUGIN_URL,
- TOTAL_CM_HANDLES,
- makeBatchOfCmHandleIds,
- makeCustomSummaryReport
-} from './utils.js';
+import { TOTAL_CM_HANDLES, REGISTRATION_BATCH_SIZE, makeBatchOfCmHandleIds, makeCustomSummaryReport } from './common/utils.js';
+import { createCmHandles } from './common/cmhandle-crud.js';
-const BATCH_SIZE = 100;
export const options = {
vus: 1,
- iterations: Math.ceil(TOTAL_CM_HANDLES / BATCH_SIZE),
+ iterations: Math.ceil(TOTAL_CM_HANDLES / REGISTRATION_BATCH_SIZE),
thresholds: {
http_req_failed: ['rate == 0'],
http_req_duration: ['avg <= 850'],
@@ -40,25 +32,9 @@ export const options = {
};
export default function () {
- const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(BATCH_SIZE, exec.scenario.iterationInTest);
- const payload = {
- "dmiPlugin": DMI_PLUGIN_URL,
- "createdCmHandles": nextBatchOfCmHandleIds.map(cmHandleId => ({
- "cmHandle": cmHandleId,
- "cmHandleProperties": {"neType": "RadioNode"},
- "publicCmHandleProperties": {
- "Color": "yellow",
- "Size": "small",
- "Shape": "cube"
- }
- })),
- };
- const response = http.post(NCMP_BASE_URL + '/ncmpInventory/v1/ch', JSON.stringify(payload), {
- headers: {'Content-Type': 'application/json'},
- });
- check(response, {
- 'status equals 200': (r) => r.status === 200,
- });
+ const batchNumber = exec.scenario.iterationInTest;
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(REGISTRATION_BATCH_SIZE, batchNumber);
+ createCmHandles(nextBatchOfCmHandleIds);
}
export function handleSummary(data) {
diff --git a/k6-tests/ncmp/10-mixed-load-test.js b/k6-tests/ncmp/10-mixed-load-test.js
index 4bb0297d63..afa91af203 100644
--- a/k6-tests/ncmp/10-mixed-load-test.js
+++ b/k6-tests/ncmp/10-mixed-load-test.js
@@ -18,10 +18,9 @@
* ============LICENSE_END=========================================================
*/
-import http from 'k6/http';
-import { check } from 'k6';
-import { NCMP_BASE_URL, getRandomCmHandleId, makeCustomSummaryReport } from './utils.js'
-import { executeCmHandleSearch, executeCmHandleIdSearch } from './search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js'
+import { executeCmHandleSearch, executeCmHandleIdSearch } from './common/search-base.js';
+import { passthroughRead } from './common/passthrough-read.js';
export const options = {
scenarios: {
@@ -56,13 +55,7 @@ export const options = {
};
export function passthrough_read() {
- const cmHandleId = getRandomCmHandleId();
- const datastoreName = 'ncmp-datastore%3Apassthrough-operational';
- const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${cmHandleId}/data/ds/${datastoreName}?resourceIdentifier=x&include-descendants=true`
- const response = http.get(url);
- check(response, {
- 'status equals 200': (r) => r.status === 200,
- });
+ passthroughRead();
}
export function id_search_module() {
diff --git a/k6-tests/ncmp/11-delete-cmhandles.js b/k6-tests/ncmp/11-delete-cmhandles.js
index 073d1d0836..542754b5f9 100644
--- a/k6-tests/ncmp/11-delete-cmhandles.js
+++ b/k6-tests/ncmp/11-delete-cmhandles.js
@@ -18,15 +18,13 @@
* ============LICENSE_END=========================================================
*/
-import http from 'k6/http';
import exec from 'k6/execution';
-import { check } from 'k6';
-import { NCMP_BASE_URL, TOTAL_CM_HANDLES, makeBatchOfCmHandleIds, makeCustomSummaryReport } from './utils.js';
+import { TOTAL_CM_HANDLES, REGISTRATION_BATCH_SIZE, makeBatchOfCmHandleIds, makeCustomSummaryReport } from './common/utils.js';
+import { deleteCmHandles } from './common/cmhandle-crud.js';
-const BATCH_SIZE = 100;
export const options = {
vus: 1,
- iterations: Math.ceil(TOTAL_CM_HANDLES / BATCH_SIZE),
+ iterations: Math.ceil(TOTAL_CM_HANDLES / REGISTRATION_BATCH_SIZE),
thresholds: {
http_req_failed: ['rate == 0'],
http_req_duration: ['avg <= 1050'],
@@ -34,17 +32,9 @@ export const options = {
};
export default function () {
- const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(BATCH_SIZE, exec.scenario.iterationInTest);
- const payload = {
- "dmiPlugin": "http://ncmp-dmi-plugin-demo-and-csit-stub:8092",
- "removedCmHandles": nextBatchOfCmHandleIds,
- };
- const response = http.post(NCMP_BASE_URL + '/ncmpInventory/v1/ch', JSON.stringify(payload), {
- headers: {'Content-Type': 'application/json'},
- });
- check(response, {
- 'status equals 200': (r) => r.status === 200,
- });
+ const batchNumber = exec.scenario.iterationInTest;
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(REGISTRATION_BATCH_SIZE, batchNumber);
+ deleteCmHandles(nextBatchOfCmHandleIds);
}
export function handleSummary(data) {
diff --git a/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js b/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js
index 5d54c60f47..cce85ab7cb 100644
--- a/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js
+++ b/k6-tests/ncmp/2-wait-for-cmhandles-to-be-ready.js
@@ -18,9 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import http from 'k6/http';
-import { sleep, fail } from 'k6';
-import { makeCustomSummaryReport, NCMP_BASE_URL, TOTAL_CM_HANDLES } from './utils.js';
+import { makeCustomSummaryReport } from './common/utils.js';
+import { waitForCmHandlesToBeReady } from './common/cmhandle-crud.js';
export const options = {
vus: 1,
@@ -32,35 +31,8 @@ export const options = {
};
export default function () {
- waitForCmHandlesToBeReady(TOTAL_CM_HANDLES);
-}
-
-function waitForCmHandlesToBeReady(totalCmHandles) {
const timeOutInSeconds = 6 * 60;
- const pollingIntervalInSeconds = 10;
- const maxRetries = Math.ceil(timeOutInSeconds / pollingIntervalInSeconds);
- let cmHandlesReady = 0;
- for (let currentTry = 0; currentTry <= maxRetries; currentTry++) {
- sleep(pollingIntervalInSeconds);
- try {
- cmHandlesReady = getNumberOfReadyCmHandles();
- } catch (error) {
- console.error(`Attempt ${currentTry + 1} - Error fetching CM handles: ${error.message}`);
- }
- console.log(`Attempt ${currentTry + 1} - ${cmHandlesReady}/${totalCmHandles} CM handles are READY`);
- if (cmHandlesReady === totalCmHandles) {
- console.log(`All ${totalCmHandles} CM handles are READY`);
- return;
- }
- }
- fail(`Timed out after ${timeoutInSeconds} seconds waiting for ${totalCmHandles} CM handles to be READY`);
-}
-
-function getNumberOfReadyCmHandles() {
- const endpointUrl = `${NCMP_BASE_URL}/cps/api/v2/dataspaces/NCMP-Admin/anchors/ncmp-dmi-registry/node?xpath=/dmi-registry&descendants=all`;
- const jsonData = http.get(endpointUrl).json();
- const cmHandles = jsonData[0]["dmi-reg:dmi-registry"]["cm-handles"];
- return cmHandles.filter(cmhandle => cmhandle['state']['cm-handle-state'] === 'READY').length;
+ waitForCmHandlesToBeReady(timeOutInSeconds);
}
export function handleSummary(data) {
diff --git a/k6-tests/ncmp/3-passthrough-read.js b/k6-tests/ncmp/3-passthrough-read.js
index 84050b83ab..39eb4ad673 100644
--- a/k6-tests/ncmp/3-passthrough-read.js
+++ b/k6-tests/ncmp/3-passthrough-read.js
@@ -18,10 +18,9 @@
* ============LICENSE_END=========================================================
*/
-import http from 'k6/http';
-import { check } from 'k6';
-import { Trend } from "k6/metrics";
-import { NCMP_BASE_URL, getRandomCmHandleId, makeCustomSummaryReport } from './utils.js'
+import { Trend } from 'k6/metrics';
+import { passthroughRead } from './common/passthrough-read.js'
+import { makeCustomSummaryReport } from './common/utils.js'
let ncmpOverheadTrend = new Trend("ncmp_overhead");
@@ -36,14 +35,7 @@ export const options = {
// The function that defines VU logic.
export default function () {
- const cmHandleId = getRandomCmHandleId();
- const datastoreName = 'ncmp-datastore%3Apassthrough-operational';
- const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${cmHandleId}/data/ds/${datastoreName}?resourceIdentifier=x&include-descendants=true`
- const response = http.get(url);
- check(response, {
- 'status equals 200': (r) => r.status === 200,
- });
-
+ const response = passthroughRead();
// Calculate overhead assuming DMI data delay is 2500ms.
const dmiDelay = 2500; // This should be same as value DATA_FOR_CM_HANDLE_DELAY_MS in docker-compose.yml
const overhead = response.timings.duration - dmiDelay;
diff --git a/k6-tests/ncmp/4-id-search-no-filter.js b/k6-tests/ncmp/4-id-search-no-filter.js
index ed8d77f2e7..3863b5d789 100644
--- a/k6-tests/ncmp/4-id-search-no-filter.js
+++ b/k6-tests/ncmp/4-id-search-no-filter.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleIdSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleIdSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 5,
diff --git a/k6-tests/ncmp/5-search-no-filter.js b/k6-tests/ncmp/5-search-no-filter.js
index 73fa82787b..67c9d59827 100644
--- a/k6-tests/ncmp/5-search-no-filter.js
+++ b/k6-tests/ncmp/5-search-no-filter.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 4,
diff --git a/k6-tests/ncmp/6-id-search-public-property.js b/k6-tests/ncmp/6-id-search-public-property.js
index 543ee1a87d..25bffaf25d 100644
--- a/k6-tests/ncmp/6-id-search-public-property.js
+++ b/k6-tests/ncmp/6-id-search-public-property.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleIdSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleIdSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 5,
diff --git a/k6-tests/ncmp/7-search-public-property.js b/k6-tests/ncmp/7-search-public-property.js
index cb39b54d9c..53f069d022 100644
--- a/k6-tests/ncmp/7-search-public-property.js
+++ b/k6-tests/ncmp/7-search-public-property.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 4,
diff --git a/k6-tests/ncmp/8-id-search-module.js b/k6-tests/ncmp/8-id-search-module.js
index d058a1bf14..8200ea28ca 100644
--- a/k6-tests/ncmp/8-id-search-module.js
+++ b/k6-tests/ncmp/8-id-search-module.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleIdSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleIdSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 5,
diff --git a/k6-tests/ncmp/9-search-module.js b/k6-tests/ncmp/9-search-module.js
index c6bbb06db1..eafef99b34 100644
--- a/k6-tests/ncmp/9-search-module.js
+++ b/k6-tests/ncmp/9-search-module.js
@@ -18,8 +18,8 @@
* ============LICENSE_END=========================================================
*/
-import { executeCmHandleSearch } from './search-base.js';
-import { makeCustomSummaryReport } from "./utils.js";
+import { executeCmHandleSearch } from './common/search-base.js';
+import { makeCustomSummaryReport } from './common/utils.js';
export const options = {
vus: 4,
diff --git a/k6-tests/ncmp/common/cmhandle-crud.js b/k6-tests/ncmp/common/cmhandle-crud.js
new file mode 100644
index 0000000000..0c3e116a19
--- /dev/null
+++ b/k6-tests/ncmp/common/cmhandle-crud.js
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { check, sleep, fail } from 'k6';
+import { NCMP_BASE_URL, DMI_PLUGIN_URL, TOTAL_CM_HANDLES } from './utils.js';
+
+export function createCmHandles(cmHandleIds) {
+ const url = `${NCMP_BASE_URL}/ncmpInventory/v1/ch`;
+ const payload = {
+ "dmiPlugin": DMI_PLUGIN_URL,
+ "createdCmHandles": cmHandleIds.map(cmHandleId => ({
+ "cmHandle": cmHandleId,
+ "cmHandleProperties": {"neType": "RadioNode"},
+ "publicCmHandleProperties": {
+ "Color": "yellow",
+ "Size": "small",
+ "Shape": "cube"
+ }
+ })),
+ };
+ const params = {
+ headers: {'Content-Type': 'application/json'}
+ };
+ const response = http.post(url, JSON.stringify(payload), params);
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+ return response;
+}
+
+export function deleteCmHandles(cmHandleIds) {
+ const url = `${NCMP_BASE_URL}/ncmpInventory/v1/ch`;
+ const payload = {
+ "dmiPlugin": DMI_PLUGIN_URL,
+ "removedCmHandles": cmHandleIds,
+ };
+ const params = {
+ headers: {'Content-Type': 'application/json'}
+ };
+ const response = http.post(url, JSON.stringify(payload), params);
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+ return response;
+}
+
+export function waitForCmHandlesToBeReady(timeOutInSeconds) {
+ const pollingIntervalInSeconds = 10;
+ const maxRetries = Math.ceil(timeOutInSeconds / pollingIntervalInSeconds);
+ let cmHandlesReady = 0;
+ for (let currentTry = 0; currentTry <= maxRetries; currentTry++) {
+ sleep(pollingIntervalInSeconds);
+ try {
+ cmHandlesReady = getNumberOfReadyCmHandles();
+ } catch (error) {
+ console.error(`Attempt ${currentTry + 1} - Error fetching CM handles: ${error.message}`);
+ }
+ console.log(`Attempt ${currentTry + 1} - ${cmHandlesReady}/${TOTAL_CM_HANDLES} CM handles are READY`);
+ if (cmHandlesReady === TOTAL_CM_HANDLES) {
+ console.log(`All ${TOTAL_CM_HANDLES} CM handles are READY`);
+ return;
+ }
+ }
+ fail(`Timed out after ${timeOutInSeconds} seconds waiting for ${TOTAL_CM_HANDLES} CM handles to be READY`);
+}
+
+function getNumberOfReadyCmHandles() {
+ const endpointUrl = `${NCMP_BASE_URL}/cps/api/v2/dataspaces/NCMP-Admin/anchors/ncmp-dmi-registry/node?xpath=/dmi-registry&descendants=all`;
+ const jsonData = http.get(endpointUrl).json();
+ const cmHandles = jsonData[0]["dmi-reg:dmi-registry"]["cm-handles"];
+ return cmHandles.filter(cmhandle => cmhandle['state']['cm-handle-state'] === 'READY').length;
+}
diff --git a/k6-tests/ncmp/common/passthrough-read.js b/k6-tests/ncmp/common/passthrough-read.js
new file mode 100644
index 0000000000..e4e937c9c0
--- /dev/null
+++ b/k6-tests/ncmp/common/passthrough-read.js
@@ -0,0 +1,36 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import http from 'k6/http';
+import { check } from 'k6';
+import { NCMP_BASE_URL, getRandomCmHandleId } from './utils.js';
+
+export function passthroughRead() {
+ const cmHandleId = getRandomCmHandleId();
+ const resourceIdentifier = 'my-resource-identifier';
+ const includeDescendants = true;
+ const datastoreName = 'ncmp-datastore:passthrough-operational';
+ const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${cmHandleId}/data/ds/${datastoreName}?resourceIdentifier=${resourceIdentifier}&include-descendants=${includeDescendants}`
+ const response = http.get(url);
+ check(response, {
+ 'status equals 200': (r) => r.status === 200,
+ });
+ return response;
+}
diff --git a/k6-tests/ncmp/search-base.js b/k6-tests/ncmp/common/search-base.js
index 04b644425d..f833a5388a 100644
--- a/k6-tests/ncmp/search-base.js
+++ b/k6-tests/ncmp/common/search-base.js
@@ -51,14 +51,18 @@ export function executeCmHandleIdSearch(scenario) {
}
function executeSearchRequest(searchType, scenario) {
- const searchParameter = JSON.stringify(SEARCH_PARAMETERS_PER_SCENARIO[scenario]);
- const response = http.post(NCMP_BASE_URL + '/ncmp/v1/ch/' + searchType, searchParameter, {
- headers: {'Content-Type': 'application/json'},
- });
+ const searchParameters = SEARCH_PARAMETERS_PER_SCENARIO[scenario];
+ const payload = JSON.stringify(searchParameters);
+ const url = `${NCMP_BASE_URL}/ncmp/v1/ch/${searchType}`;
+ const params = {
+ headers: {'Content-Type': 'application/json'}
+ };
+ const response = http.post(url, payload, params);
check(response, {
'status equals 200': (r) => r.status === 200,
});
- check(JSON.parse(response.body), {
+ const responseData = JSON.parse(response.body);
+ check(responseData, {
'returned list has expected CM-handles': (arr) => arr.length === TOTAL_CM_HANDLES,
});
}
diff --git a/k6-tests/ncmp/utils.js b/k6-tests/ncmp/common/utils.js
index 18a8940523..55ef60a2e7 100644
--- a/k6-tests/ncmp/utils.js
+++ b/k6-tests/ncmp/common/utils.js
@@ -20,11 +20,14 @@
export const NCMP_BASE_URL = 'http://localhost:8883';
export const DMI_PLUGIN_URL = 'http://ncmp-dmi-plugin-demo-and-csit-stub:8092';
-export const TOTAL_CM_HANDLES = 20000
+export const TOTAL_CM_HANDLES = Number(__ENV.TOTAL_CM_HANDLES) || 20000;
+export const REGISTRATION_BATCH_SIZE = Number(__ENV.REGISTRATION_BATCH_SIZE) || 100;
-/*
- * Makes a batch of CM-handle IDs.
- * Given a batchSize=100 and batchNumber=2, it will generate ['ch-201', 'ch-202' ... 'ch-300']
+/**
+ * Generates a batch of CM-handle IDs based on batch size and number.
+ * @param {number} batchSize - Size of each batch.
+ * @param {number} batchNumber - Number of the batch.
+ * @returns {string[]} Array of CM-handle IDs, for example ['ch-201', 'ch-202' ... 'ch-300']
*/
export function makeBatchOfCmHandleIds(batchSize, batchNumber) {
const batchOfIds = [];
@@ -37,7 +40,7 @@ export function makeBatchOfCmHandleIds(batchSize, batchNumber) {
}
export function getRandomCmHandleId() {
- return 'ch-' + (Math.floor(Math.random() * TOTAL_CM_HANDLES) + 1);
+ return `ch-${Math.floor(Math.random() * TOTAL_CM_HANDLES) + 1}`;
}
function removeBracketsAndQuotes(str) {
diff --git a/k6-tests/ncmp/run-all-tests.sh b/k6-tests/ncmp/run-all-tests.sh
index 80231b9809..f67b6ef069 100755
--- a/k6-tests/ncmp/run-all-tests.sh
+++ b/k6-tests/ncmp/run-all-tests.sh
@@ -31,6 +31,12 @@ ALL_TEST_SCRIPTS=( \
pushd "$(dirname "$0")" || exit 1
+echo 'Warming up JVM (warmup results will not be recorded)'
+for test_script in "${ALL_TEST_SCRIPTS[@]}"; do
+ echo "[warmup] k6 run $test_script"
+ k6 --quiet -e TOTAL_CM_HANDLES=1000 -e REGISTRATION_BATCH_SIZE=10 -e K6_MODULE_NAME="$test_script" run "$test_script" > /dev/null
+done
+
printf "Test Case\tCondition\tLimit\tActual\tResult\n" > summary.log
number_of_failures=0
diff --git a/pom.xml b/pom.xml
index 4d0460237c..fcead19e87 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
diff --git a/releases/3.5.0-container.yaml b/releases/3.5.0-container.yaml
new file mode 100644
index 0000000000..d6e3b63dbf
--- /dev/null
+++ b/releases/3.5.0-container.yaml
@@ -0,0 +1,8 @@
+distribution_type: container
+container_release_tag: 3.5.0
+project: cps
+log_dir: cps-maven-docker-stage-master/942/
+ref: 59575279e36572be4386f1c644db52fcb570fc9e
+containers:
+ - name: 'cps-and-ncmp'
+ version: '3.5.0-20240620T123504Z' \ No newline at end of file
diff --git a/releases/3.5.0.yaml b/releases/3.5.0.yaml
new file mode 100644
index 0000000000..81dc74660b
--- /dev/null
+++ b/releases/3.5.0.yaml
@@ -0,0 +1,4 @@
+distribution_type: maven
+log_dir: cps-maven-stage-master/950/
+project: cps
+version: 3.5.0 \ No newline at end of file
diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml
index bab9551909..7edfaac7c7 100644
--- a/spotbugs/pom.xml
+++ b/spotbugs/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>spotbugs</artifactId>
- <version>3.5.0-SNAPSHOT</version>
+ <version>3.5.1-SNAPSHOT</version>
<properties>
<nexusproxy>https://nexus.onap.org</nexusproxy>
diff --git a/version.properties b/version.properties
index 5fdc4e3576..6345596e1e 100644
--- a/version.properties
+++ b/version.properties
@@ -22,7 +22,7 @@
major=3
minor=5
-patch=0
+patch=1
base_version=${major}.${minor}.${patch}