summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cps-application/src/main/resources/application.yml25
-rw-r--r--cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java3
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java30
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java7
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy9
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy29
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java42
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java41
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/HttpClientConfiguration.java)17
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java41
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java36
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java17
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/PolicyExecutor.java74
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java174
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java1
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java68
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java32
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java16
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java34
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java6
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java81
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilder.java)39
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/UrlTemplateParameters.java)2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfiguration.java)55
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy (renamed from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy)56
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy48
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy9
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy45
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy125
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy1
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy77
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfigurationSpec.groovy70
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy8
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy36
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy11
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy4
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy73
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfigurationSpec.groovy53
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy (renamed from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy)15
-rw-r--r--cps-ncmp-service/src/test/java/org/onap/cps/ncmp/utils/WebClientBuilderTestConfig.java40
-rw-r--r--cps-ncmp-service/src/test/resources/application.yml39
-rw-r--r--cps-parent/pom.xml24
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/data/dmi/generated-csv/README.md23
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2021-12-13.yang63
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-02-10.yang81
-rw-r--r--cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-05-10.yang123
-rw-r--r--cps-ri/src/main/resources/yangResourceCsvGenerator.py66
-rwxr-xr-xcsit/install-deps.sh36
-rwxr-xr-xcsit/plans/cps/setup.sh9
-rwxr-xr-xcsit/run-project-csit.sh3
-rw-r--r--csit/tests/cps-trust-level/cps-trust-level.robot6
-rw-r--r--docs/schemas/policy-executor/ncmp-create-schema-1.0.0.json2
-rw-r--r--docs/schemas/policy-executor/ncmp-delete-schema-1.0.0.json2
-rw-r--r--docs/schemas/policy-executor/ncmp-patch-schema-1.0.0.json2
-rw-r--r--docs/schemas/policy-executor/ncmp-update-schema-1.0.0.json2
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy13
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy18
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/base/PolicyDispatcher.groovy74
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobResultServiceSpec.groovy1
-rw-r--r--integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/PolicyExecutorIntegrationSpec.groovy63
-rw-r--r--integration-test/src/test/resources/application.yml14
-rwxr-xr-xk6-tests/install-deps.sh47
-rw-r--r--k6-tests/ncmp/common/cmhandle-crud.js34
-rw-r--r--k6-tests/ncmp/common/search-base.js2
-rw-r--r--k6-tests/ncmp/common/utils.js19
-rw-r--r--k6-tests/ncmp/ncmp-kpi.js103
-rwxr-xr-xk6-tests/run-k6-tests.sh4
-rwxr-xr-xk6-tests/teardown.sh8
-rw-r--r--spotbugs/src/main/resources/spotbugs-exclude.xml1
82 files changed, 1527 insertions, 997 deletions
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index f61a09ba17..8ca6b0fe02 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -188,22 +188,35 @@ logging:
onap:
cps: INFO
ncmp:
- dmi:
+ policy-executor:
+ enabled: false
+ server:
+ address: http://localhost
+ port: 8785
httpclient:
- data-services:
+ all-services:
+ maximumInMemorySizeInMegabytes: 16
+ maximumConnectionsTotal: 100
+ pendingAcquireMaxCount: 50
connectionTimeoutInSeconds: 30
readTimeoutInSeconds: 30
writeTimeoutInSeconds: 30
+ dmi:
+ httpclient:
+ data-services:
+ maximumInMemorySizeInMegabytes: 16
maximumConnectionsTotal: 100
pendingAcquireMaxCount: 50
- maximumInMemorySizeInMegabytes: 16
- model-services:
connectionTimeoutInSeconds: 30
readTimeoutInSeconds: 30
writeTimeoutInSeconds: 30
+ model-services:
+ maximumInMemorySizeInMegabytes: 16
maximumConnectionsTotal: 100
pendingAcquireMaxCount: 50
- maximumInMemorySizeInMegabytes: 16
+ connectionTimeoutInSeconds: 30
+ readTimeoutInSeconds: 30
+ writeTimeoutInSeconds: 30
auth:
username: ${DMI_USERNAME:cpsuser}
password: ${DMI_PASSWORD:cpsr0cks!}
@@ -244,4 +257,4 @@ otel:
exporter:
otlp:
traces:
- protocol: ${ONAP_OTEL_EXPORTER_OTLP_TRACES_PROTOCOL:grpc} \ No newline at end of file
+ protocol: ${ONAP_OTEL_EXPORTER_OTLP_TRACES_PROTOCOL:grpc}
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
index 11adc84a1f..183698c4f5 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
@@ -165,7 +165,8 @@ public class NetworkCmProxyStubController implements NetworkCmProxyApi {
}
@Override
- public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(final String cmHandle) {
+ public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(
+ final String cmHandleReference) {
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
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 af5f226a4f..6a2e9a1541 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
@@ -148,7 +148,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Patch resource data.
*
* @param datastoreName name of the datastore (currently only supports "ncmp-datastore:passthrough-running")
- * @param cmHandle cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @param resourceIdentifier resource identifier
* @param requestBody the request body
* @param contentType content type of body
@@ -158,7 +158,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
@Override
public ResponseEntity<Object> patchResourceDataRunningForCmHandle(final String datastoreName,
- final String cmHandle,
+ final String cmHandleReference,
final String resourceIdentifier,
final Object requestBody,
final String contentType,
@@ -168,7 +168,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final Object responseObject = networkCmProxyFacade
.writeResourceDataPassThroughRunningForCmHandle(
- cmHandle, resourceIdentifier, PATCH,
+ cmHandleReference, resourceIdentifier, PATCH,
jsonObjectMapper.asJsonString(requestBody), contentType, authorization);
return ResponseEntity.ok(responseObject);
}
@@ -177,7 +177,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Create resource data for given cm-handle.
*
* @param datastoreName name of the datastore (currently only supports "ncmp-datastore:passthrough-running")
- * @param cmHandle cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @param resourceIdentifier resource identifier
* @param requestBody the request body
* @param contentType content type of body
@@ -186,14 +186,14 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
*/
@Override
public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String datastoreName,
- final String cmHandle,
+ final String cmHandleReference,
final String resourceIdentifier,
final Object requestBody,
final String contentType,
final String authorization) {
validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
- networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
+ networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandleReference,
resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -202,7 +202,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Update resource data for given cm-handle.
*
* @param datastoreName name of the datastore (currently only supports "ncmp-datastore:passthrough-running")
- * @param cmHandle cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @param resourceIdentifier resource identifier
* @param requestBody the request body
* @param contentType content type of the body
@@ -212,14 +212,14 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
@Override
public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String datastoreName,
- final String cmHandle,
+ final String cmHandleReference,
final String resourceIdentifier,
final Object requestBody,
final String contentType,
final String authorization) {
validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
- networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
+ networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandleReference,
resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType, authorization);
return new ResponseEntity<>(HttpStatus.OK);
}
@@ -228,7 +228,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
* Delete resource data for a given cm-handle.
*
* @param datastoreName name of the datastore (currently only supports "ncmp-datastore:passthrough-running")
- * @param cmHandle cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @param resourceIdentifier resource identifier
* @param contentType content type of the body
* @param authorization contents of Authorization header, or null if not present
@@ -236,14 +236,14 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
*/
@Override
public ResponseEntity<Void> deleteResourceDataRunningForCmHandle(final String datastoreName,
- final String cmHandle,
+ final String cmHandleReference,
final String resourceIdentifier,
final String contentType,
final String authorization) {
validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
- networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
+ networkCmProxyFacade.writeResourceDataPassThroughRunningForCmHandle(cmHandleReference,
resourceIdentifier, DELETE, NO_BODY, contentType, authorization);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@@ -317,13 +317,13 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
/**
* Get Cm Handle State by Cm Handle Id.
*
- * @param cmHandleId cm-handle identifier
+ * @param cmHandleReference cm-handle or alternate identifier
* @return cm handle state
*/
@Override
public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(
- final String cmHandleId) {
- final CompositeState cmHandleState = networkCmProxyInventoryFacade.getCmHandleCompositeState(cmHandleId);
+ final String cmHandleReference) {
+ final CompositeState cmHandleState = networkCmProxyInventoryFacade.getCmHandleCompositeState(cmHandleReference);
final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState =
new RestOutputCmHandleCompositeState();
restOutputCmHandleCompositeState.setState(
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java
index d61d30dc2b..6910003c54 100644
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandler.java
@@ -31,6 +31,7 @@ import org.onap.cps.ncmp.api.exceptions.DmiRequestException;
import org.onap.cps.ncmp.api.exceptions.InvalidTopicException;
import org.onap.cps.ncmp.api.exceptions.NcmpException;
import org.onap.cps.ncmp.api.exceptions.PayloadTooLargeException;
+import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException;
import org.onap.cps.ncmp.api.exceptions.ServerNcmpException;
import org.onap.cps.ncmp.rest.model.DmiErrorMessage;
import org.onap.cps.ncmp.rest.model.DmiErrorMessageDmiResponse;
@@ -84,8 +85,8 @@ public class NetworkCmProxyRestExceptionHandler {
return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
}
- @ExceptionHandler({AlreadyDefinedException.class})
- public static ResponseEntity<Object> handleAlreadyDefinedExceptions(final Exception exception) {
+ @ExceptionHandler({AlreadyDefinedException.class, PolicyExecutorException.class})
+ public static ResponseEntity<Object> handleConflictExceptions(final Exception exception) {
return buildErrorResponse(HttpStatus.CONFLICT, exception);
}
@@ -113,8 +114,6 @@ public class NetworkCmProxyRestExceptionHandler {
} else {
errorMessage.setDetails(CHECK_LOGS_FOR_DETAILS);
}
- errorMessage.setDetails(
- exception instanceof CpsException ? ((CpsException) exception).getDetails() : CHECK_LOGS_FOR_DETAILS);
return new ResponseEntity<>(errorMessage, status);
}
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 9f5331dbc3..92b47c6c8b 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
@@ -32,7 +32,6 @@ 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.data.models.CmResourceAddress
import org.onap.cps.ncmp.api.inventory.NetworkCmProxyInventoryFacade
import org.onap.cps.ncmp.api.inventory.models.CompositeState
import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
@@ -95,7 +94,7 @@ class NetworkCmProxyControllerSpec extends Specification {
NetworkCmProxyInventoryFacade mockNetworkCmProxyInventoryFacade = Mock()
@SpringBean
- AlternateIdMatcher mockalternateIdMatcher = Mock()
+ AlternateIdMatcher mockAlternateIdMatcher = Mock()
@SpringBean
ObjectMapper objectMapper = new ObjectMapper()
@@ -324,13 +323,13 @@ class NetworkCmProxyControllerSpec extends Specification {
assertContainsPublicProperties(response)
}
- def 'Get Cm Handle composite state by Cm Handle id.'() {
+ def 'Get Cm Handle composite state by Cm Handle Reference.'() {
given: 'a cm handle state endpoint'
- def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/state"
+ def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle-reference/state"
and: 'some cm handle composite state'
def compositeState = compositeStateTestObject()
and: 'the service method is invoked with the cm handle id returning the cm handle composite state'
- 1 * mockNetworkCmProxyInventoryFacade.getCmHandleCompositeState('some-cm-handle') >> compositeState
+ 1 * mockNetworkCmProxyInventoryFacade.getCmHandleCompositeState('some-cm-handle-reference') >> compositeState
when: 'the cm handle state api is invoked'
def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response
then: 'the correct response is returned'
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy
index e6288ffbec..9d36d106c7 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -29,11 +29,13 @@ import org.onap.cps.ncmp.api.data.exceptions.OperationNotSupportedException
import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException
import org.onap.cps.ncmp.api.exceptions.DmiRequestException
import org.onap.cps.ncmp.api.exceptions.PayloadTooLargeException
+import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException
import org.onap.cps.ncmp.api.exceptions.ServerNcmpException
import org.onap.cps.ncmp.api.inventory.NetworkCmProxyInventoryFacade
import org.onap.cps.ncmp.impl.data.NcmpCachedResourceRequestHandler
import org.onap.cps.ncmp.impl.data.NcmpPassthroughResourceRequestHandler
import org.onap.cps.ncmp.impl.data.NetworkCmProxyFacade
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor
import org.onap.cps.ncmp.impl.inventory.InventoryPersistence
import org.onap.cps.ncmp.rest.util.CmHandleStateMapper
import org.onap.cps.ncmp.rest.util.DataOperationRequestMapper
@@ -120,25 +122,26 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
dataNodeBaseEndpointNcmpInventory = "$basePathNcmpInventory/v1"
}
- def 'Get request with #scenario exception returns correct HTTP Status with #scenario'() {
+ def 'Get request with #scenario exception returns correct HTTP Status with #scenario exception'() {
when: 'an exception is thrown by the service'
setupTestException(exception, NCMP)
def response = performTestRequest(NCMP)
then: 'an HTTP response is returned with correct message and details'
assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails)
where:
- scenario | exception || expectedErrorCode | expectedErrorMessage | expectedErrorDetails
- 'CPS' | new CpsException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | sampleErrorDetails
- 'NCMP-server' | new ServerNcmpException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null
- 'DMI Request' | new DmiRequestException(sampleErrorMessage, sampleErrorDetails) || BAD_REQUEST | sampleErrorMessage | null
- 'Invalid Operation' | new InvalidOperationException('some reason') || BAD_REQUEST | 'some reason' | null
- 'Unsupported Operation' | new OperationNotSupportedException('not yet') || BAD_REQUEST | 'not yet' | null
- 'DataNode Validation' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | null
- 'other' | new IllegalStateException(sampleErrorMessage) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null
- 'Data Node Not Found' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | 'DataNode not found'
- 'Existing entry' | new AlreadyDefinedException('name',null) || CONFLICT | 'Already defined exception' | 'name already exists'
- 'Existing entries' | AlreadyDefinedException.forDataNodes(['A', 'B'], 'myAnchorName') || CONFLICT | 'Already defined exception' | '2 data node(s) already exist'
- 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs'
+ scenario | exception || expectedErrorCode | expectedErrorMessage | expectedErrorDetails
+ 'CPS' | new CpsException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | sampleErrorDetails
+ 'NCMP-server' | new ServerNcmpException(sampleErrorMessage, sampleErrorDetails) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null
+ 'DMI Request' | new DmiRequestException(sampleErrorMessage, sampleErrorDetails) || BAD_REQUEST | sampleErrorMessage | null
+ 'Invalid Operation' | new InvalidOperationException('some reason') || BAD_REQUEST | 'some reason' | null
+ 'Unsupported Operation' | new OperationNotSupportedException('not yet') || BAD_REQUEST | 'not yet' | null
+ 'DataNode Validation' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | null
+ 'other' | new IllegalStateException(sampleErrorMessage) || INTERNAL_SERVER_ERROR | sampleErrorMessage | null
+ 'Data Node Not Found' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || NOT_FOUND | 'DataNode not found' | 'DataNode not found'
+ 'Existing entry' | new AlreadyDefinedException('name',null) || CONFLICT | 'Already defined exception' | 'name already exists'
+ 'Existing entries' | AlreadyDefinedException.forDataNodes(['A', 'B'], 'myAnchorName') || CONFLICT | 'Already defined exception' | '2 data node(s) already exist'
+ 'Operation too large' | new PayloadTooLargeException(sampleErrorMessage) || PAYLOAD_TOO_LARGE | sampleErrorMessage | 'Check logs'
+ 'Policy Executor' | new PolicyExecutorException(sampleErrorMessage, sampleErrorDetails) || CONFLICT | sampleErrorMessage | sampleErrorDetails
}
def 'Post request with exception returns correct HTTP Status.'() {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java
new file mode 100644
index 0000000000..333c12271b
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/exceptions/PolicyExecutorException.java
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.exceptions;
+
+import lombok.Getter;
+
+/**
+ * Exception to be used when policy execution fails or does not allow to proceed.
+ */
+@Getter
+public class PolicyExecutorException extends NcmpException {
+
+ private static final long serialVersionUID = 6659897770659834798L;
+
+ /**
+ * Constructor to form exception for policy executor responses.
+ *
+ * @param message response message
+ * @param details response details
+ */
+ public PolicyExecutorException(final String message, final String details) {
+ super(message, details);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
index 794bc238f4..e678159d9f 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
@@ -26,6 +26,7 @@ package org.onap.cps.ncmp.api.inventory;
import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCmHandleQueryParameters;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import lombok.RequiredArgsConstructor;
@@ -36,7 +37,6 @@ import org.onap.cps.ncmp.api.inventory.models.CompositeState;
import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistrationResponse;
import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
-import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
import org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationService;
import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
@@ -44,12 +44,13 @@ import org.onap.cps.ncmp.impl.inventory.ParameterizedCmHandleQueryService;
import org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions;
import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
-import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
+import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
import org.onap.cps.ncmp.impl.utils.YangDataConverter;
import org.onap.cps.spi.model.ModuleDefinition;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Slf4j
@@ -62,9 +63,8 @@ public class NetworkCmProxyInventoryFacade {
private final ParameterizedCmHandleQueryService parameterizedCmHandleQueryService;
private final InventoryPersistence inventoryPersistence;
private final JsonObjectMapper jsonObjectMapper;
-
- @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE)
- private final Map<String, TrustLevel> trustLevelPerCmHandle;
+ private final TrustLevelManager trustLevelManager;
+ private final AlternateIdMatcher alternateIdMatcher;
/**
* Registration of Created, Removed, Updated or Upgraded CM Handles.
@@ -72,7 +72,6 @@ public class NetworkCmProxyInventoryFacade {
* @param dmiPluginRegistration Dmi Plugin Registration details
* @return dmiPluginRegistrationResponse
*/
-
public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
final DmiPluginRegistration dmiPluginRegistration) {
return cmHandleRegistrationService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
@@ -146,9 +145,13 @@ public class NetworkCmProxyInventoryFacade {
final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
- final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles =
+ final Collection<YangModelCmHandle> yangModelCmHandles =
parameterizedCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters);
- ncmpServiceCmHandles.forEach(this::applyCurrentTrustLevel);
+ final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelCmHandles.size());
+ for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandles) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = toNcmpServiceCmHandleWithTrustLevel(yangModelCmHandle);
+ ncmpServiceCmHandles.add(ncmpServiceCmHandle);
+ }
return ncmpServiceCmHandles;
}
@@ -183,10 +186,8 @@ public class NetworkCmProxyInventoryFacade {
* @return cm handle details
*/
public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
- final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.toNcmpServiceCmHandle(
- inventoryPersistence.getYangModelCmHandle(cmHandleId));
- applyCurrentTrustLevel(ncmpServiceCmHandle);
- return ncmpServiceCmHandle;
+ final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ return toNcmpServiceCmHandleWithTrustLevel(yangModelCmHandle);
}
/**
@@ -203,16 +204,20 @@ public class NetworkCmProxyInventoryFacade {
/**
* Get cm handle composite state for a given cm handle id.
*
- * @param cmHandleId cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @return cm handle state
*/
- public CompositeState getCmHandleCompositeState(final String cmHandleId) {
+ public CompositeState getCmHandleCompositeState(final String cmHandleReference) {
+ final String cmHandleId = alternateIdMatcher.getCmHandleId(cmHandleReference);
return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
}
- private void applyCurrentTrustLevel(final NcmpServiceCmHandle ncmpServiceCmHandle) {
- ncmpServiceCmHandle.setCurrentTrustLevel(trustLevelPerCmHandle.get(ncmpServiceCmHandle.getCmHandleId()));
+ private NcmpServiceCmHandle toNcmpServiceCmHandleWithTrustLevel(final YangModelCmHandle yangModelCmHandle) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.toNcmpServiceCmHandle(yangModelCmHandle);
+ final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ ncmpServiceCmHandle.setCurrentTrustLevel(
+ trustLevelManager.getEffectiveTrustLevel(dmiServiceName, ncmpServiceCmHandle.getCmHandleId()));
+ return ncmpServiceCmHandle;
}
-
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/HttpClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java
index 583d4bb6ad..8eebb89a0a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/HttpClientConfiguration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/DmiHttpClientConfig.java
@@ -29,7 +29,7 @@ import org.springframework.context.annotation.Configuration;
@Setter
@Configuration
@ConfigurationProperties(prefix = "ncmp.dmi.httpclient")
-public class HttpClientConfiguration {
+public class DmiHttpClientConfig {
private final DataServices dataServices = new DataServices();
private final ModelServices modelServices = new ModelServices();
@@ -54,19 +54,4 @@ public class HttpClientConfiguration {
private int maximumConnectionsTotal = 10;
private int pendingAcquireMaxCount = 5;
}
-
- /**
- * Base configuration properties for all services.
- */
- @Getter
- @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-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java
new file mode 100644
index 0000000000..0903c671b5
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfig.java
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Getter
+@Setter
+@Configuration
+@ConfigurationProperties(prefix = "ncmp.policy-executor.httpclient")
+public class PolicyExecutorHttpClientConfig {
+
+ private final AllServices allServices = new AllServices();
+
+ @Getter
+ @Setter
+ public static class AllServices extends ServiceConfig {
+ private String connectionProviderName = "policyExecutorConfig";
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java
new file mode 100644
index 0000000000..f1fce0c7c6
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/config/ServiceConfig.java
@@ -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=========================================================
+ */
+
+package org.onap.cps.ncmp.config;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public abstract class ServiceConfig {
+ private String connectionProviderName = "";
+ private int maximumInMemorySizeInMegabytes = 1;
+ private int maximumConnectionsTotal = 1;
+ private int pendingAcquireMaxCount = 1;
+ private Integer connectionTimeoutInSeconds = 1;
+ private long readTimeoutInSeconds = 1;
+ private long writeTimeoutInSeconds = 1;
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
index 90783a829a..301b8195e4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
@@ -41,15 +41,16 @@ import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException;
import org.onap.cps.ncmp.impl.data.models.DmiDataOperation;
import org.onap.cps.ncmp.impl.data.models.DmiDataOperationRequest;
import org.onap.cps.ncmp.impl.data.models.DmiOperationCmHandle;
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor;
import org.onap.cps.ncmp.impl.data.utils.DmiDataOperationsHelper;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.ncmp.impl.models.DmiRequestBody;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
@@ -138,8 +139,7 @@ public class DmiDataOperations {
final String requestId,
final String authorization) {
- final Set<String> cmHandlesIds
- = getDistinctCmHandleIds(dataOperationRequest);
+ final Set<String> cmHandlesIds = getDistinctCmHandleIds(dataOperationRequest);
final Collection<YangModelCmHandle> yangModelCmHandles
= inventoryPersistence.getYangModelCmHandles(cmHandlesIds);
@@ -170,7 +170,10 @@ public class DmiDataOperations {
final String requestData,
final String dataType,
final String authorization) {
- final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId);
+ final CmResourceAddress cmResourceAddress =
+ new CmResourceAddress(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleId, resourceId);
+
+ final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId());
policyExecutor.checkPermission(yangModelCmHandle, operationType, authorization, resourceId, requestData);
@@ -212,7 +215,7 @@ public class DmiDataOperations {
final String optionsParamInQuery,
final String topicParamInQuery) {
final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(DATA);
- return DmiServiceUrlTemplateBuilder.newInstance()
+ return RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("ch")
.variablePathSegment("cmHandleId", yangModelCmHandle.getId())
.fixedPathSegment("data")
@@ -227,7 +230,7 @@ public class DmiDataOperations {
private UrlTemplateParameters getUrlTemplateParameters(final String dmiServiceName,
final String requestId,
final String topicParamInQuery) {
- return DmiServiceUrlTemplateBuilder.newInstance()
+ return RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("data")
.queryParameter("requestId", requestId)
.queryParameter("topic", topicParamInQuery)
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java
index b97088a5e0..5343a2e131 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java
@@ -101,7 +101,7 @@ public class NetworkCmProxyFacade {
/**
* Write resource data for data store pass-through running using dmi for given cm-handle.
*
- * @param cmHandleId cm handle identifier
+ * @param cmHandleReference cm handle or alternate identifier
* @param resourceIdentifier resource identifier
* @param operationType required operation type
* @param requestData request body to create resource
@@ -109,13 +109,13 @@ public class NetworkCmProxyFacade {
* @param authorization contents of Authorization header, or null if not present
* @return {@code Object} return data
*/
- public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
+ public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleReference,
final String resourceIdentifier,
final OperationType operationType,
final String requestData,
final String dataType,
final String authorization) {
- return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier,
+ return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleReference, resourceIdentifier,
operationType, requestData, dataType, authorization);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/PolicyExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/PolicyExecutor.java
deleted file mode 100644
index 2b5eb9e792..0000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/PolicyExecutor.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.impl.data;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.data.models.OperationType;
-import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class PolicyExecutor {
-
- @Value("${ncmp.policy-executor.enabled:false}")
- private boolean enabled;
-
- @Value("${ncmp.policy-executor.server.address:http://policy-executor}")
- private String serverAddress;
-
- @Value("${ncmp.policy-executor.server.port:8080}")
- private String serverPort;
-
- private static final String PAYLOAD_TYPE_PREFIX = "cm_";
-
- /**
- * Use the Policy Executor to check permission for a cm write operation.
- * Wil throw an exception when the operation is not permitted (work in progress)
- *
- * @param yangModelCmHandle the cm handle involved
- * @param operationType the write operation
- * @param authorization the original rest authorization token (can be used to determine the client)
- * @param resourceIdentifier the resource identifier (can be blank)
- * @param changeRequestAsJson the change details from the original rest request in json format
- */
- public void checkPermission(final YangModelCmHandle yangModelCmHandle,
- final OperationType operationType,
- final String authorization,
- final String resourceIdentifier,
- final String changeRequestAsJson) {
- if (enabled) {
- final String payloadType = PAYLOAD_TYPE_PREFIX + operationType.getOperationName();
- log.info("Policy Executor Enabled");
- log.info("Address : {}", serverAddress);
- log.info("Port : {}", serverPort);
- log.info("Authorization : {}", authorization);
- log.info("Payload Type : {}", payloadType);
- log.info("Target FDN : {}", yangModelCmHandle.getAlternateId());
- log.info("CM Handle Id : {}", yangModelCmHandle.getId());
- log.info("Resource Identifier : {}", resourceIdentifier);
- log.info("Change Request (json) : {}", changeRequestAsJson);
- }
- }
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java
new file mode 100644
index 0000000000..89b48f3755
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/policyexecutor/PolicyExecutor.java
@@ -0,0 +1,174 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.data.policyexecutor;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.data.models.OperationType;
+import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException;
+import org.onap.cps.ncmp.api.exceptions.ServerNcmpException;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class PolicyExecutor {
+
+ @Value("${ncmp.policy-executor.enabled:false}")
+ private boolean enabled;
+
+ @Value("${ncmp.policy-executor.server.address:http://policy-executor}")
+ private String serverAddress;
+
+ @Value("${ncmp.policy-executor.server.port:8080}")
+ private String serverPort;
+
+ @Qualifier("policyExecutorWebClient")
+ private final WebClient policyExecutorWebClient;
+
+ /**
+ * Use the Policy Executor to check permission for a cm write operation.
+ * Wil throw an exception when the operation is not permitted (work in progress)
+ *
+ * @param yangModelCmHandle the cm handle involved
+ * @param operationType the write operation
+ * @param authorization the original rest authorization token (can be used to determine the client)
+ * @param resourceIdentifier the resource identifier (can be blank)
+ * @param changeRequestAsJson the change details from the original rest request in json format
+ */
+ public void checkPermission(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String authorization,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+ log.trace("Policy Executor Enabled: {}", enabled);
+ if (enabled) {
+ final ResponseEntity<JsonNode> responseEntity =
+ getPolicyExecutorResponse(yangModelCmHandle, operationType, authorization, resourceIdentifier,
+ changeRequestAsJson);
+
+ if (responseEntity == null) {
+ log.warn("No valid response from policy, ignored");
+ return;
+ }
+
+ if (responseEntity.getStatusCode().is2xxSuccessful()) {
+ if (responseEntity.getBody() == null) {
+ log.warn("No valid response body from policy, ignored");
+ return;
+ }
+ processResponse(responseEntity.getBody());
+ } else {
+ log.warn("Policy Executor invocation failed with status {}",
+ responseEntity.getStatusCode().value());
+ throw new ServerNcmpException("Policy Executor invocation failed", "HTTP status code: "
+ + responseEntity.getStatusCode().value());
+ }
+ }
+ }
+
+ private Map<String, Object> getSingleRequestAsMap(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+ final Map<String, Object> data = new HashMap<>(4);
+ data.put("cmHandleId", yangModelCmHandle.getId());
+ data.put("resourceIdentifier", resourceIdentifier);
+ data.put("targetIdentifier", yangModelCmHandle.getAlternateId());
+ if (!OperationType.DELETE.equals(operationType)) {
+ data.put("cmChangeRequest", changeRequestAsJson);
+ }
+
+ final Map<String, Object> request = new HashMap<>(2);
+ request.put("schema", getAssociatedPolicyDataSchemaName(operationType));
+ request.put("data", data);
+ return request;
+ }
+
+ private static String getAssociatedPolicyDataSchemaName(final OperationType operationType) {
+ return "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-" + operationType.getOperationName() + "-schema:1.0.0";
+ }
+
+ private Object createBodyAsObject(final List<Object> requests) {
+ final Map<String, Object> bodyAsMap = new HashMap<>(2);
+ bodyAsMap.put("decisionType", "allow");
+ bodyAsMap.put("requests", requests);
+ return bodyAsMap;
+ }
+
+ private ResponseEntity<JsonNode> getPolicyExecutorResponse(final YangModelCmHandle yangModelCmHandle,
+ final OperationType operationType,
+ final String authorization,
+ final String resourceIdentifier,
+ final String changeRequestAsJson) {
+ final String serviceBaseUrl = serverAddress + ":" + serverPort;
+
+ final Map<String, Object> requestAsMap = getSingleRequestAsMap(yangModelCmHandle,
+ operationType,
+ resourceIdentifier,
+ changeRequestAsJson);
+
+ final Object bodyAsObject = createBodyAsObject(Collections.singletonList(requestAsMap));
+
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
+ .fixedPathSegment("execute")
+ .createUrlTemplateParameters(serviceBaseUrl, "");
+
+ return policyExecutorWebClient.post()
+ .uri(urlTemplateParameters.urlTemplate(), urlTemplateParameters.urlVariables())
+ .header(HttpHeaders.AUTHORIZATION, authorization)
+ .body(BodyInserters.fromValue(bodyAsObject))
+ .retrieve()
+ .toEntity(JsonNode.class)
+ .block();
+ }
+
+ private static void processResponse(final JsonNode responseBody) {
+ final String decisionId = responseBody.path("decisionId").asText("unknown id");
+ log.trace("Policy Executor Decision ID: {} ", decisionId);
+ final String decision = responseBody.path("decision").asText("unknown");
+ if ("allow".equals(decision)) {
+ log.trace("Policy Executor allows the operation");
+ } else {
+ log.warn("Policy Executor decision: {}", decision);
+ final String details = responseBody.path("message").asText();
+ log.warn("Policy Executor message: {}", details);
+ final String message = "Policy Executor did not allow request. Decision #"
+ + decisionId + " : " + decision;
+ throw new PolicyExecutorException(message, details);
+ }
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
index 031cedc78b..8934c088a1 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImpl.java
@@ -24,8 +24,8 @@ import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.datajobs.DataJobResultService;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.springframework.stereotype.Service;
@Service
@@ -41,7 +41,7 @@ public class DataJobResultServiceImpl implements DataJobResultService {
final String dataProducerId,
final String dataProducerJobId,
final String destination) {
- final UrlTemplateParameters urlTemplateParameters = DmiServiceUrlTemplateBuilder.newInstance()
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("cmwriteJob")
.fixedPathSegment("dataProducer")
.variablePathSegment("dataProducerId", dataProducerId)
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
index fb17f066ce..1cfb8a9dff 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImpl.java
@@ -24,8 +24,8 @@ import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.datajobs.DataJobStatusService;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.springframework.stereotype.Service;
/**
@@ -54,7 +54,7 @@ public class DataJobStatusServiceImpl implements DataJobStatusService {
private UrlTemplateParameters buildUrlParameters(final String dmiServiceName,
final String dataProducerId,
final String dataProducerJobId) {
- return DmiServiceUrlTemplateBuilder.newInstance()
+ return RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("cmwriteJob")
.fixedPathSegment("dataProducer")
.variablePathSegment("dataProducerId", dataProducerId)
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java
index 0d14dace5e..a118d53e7e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/DmiSubJobRequestHandler.java
@@ -33,9 +33,9 @@ import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteRequest;
import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteResponse;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@@ -88,7 +88,7 @@ public class DmiSubJobRequestHandler {
}
private UrlTemplateParameters getUrlTemplateParameters(final String destination, final ProducerKey producerKey) {
- return DmiServiceUrlTemplateBuilder.newInstance()
+ return RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("cmwriteJob")
.queryParameter("destination", destination)
.createUrlTemplateParameters(producerKey.dmiServiceName(), dmiProperties.getDmiBasePath());
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
index c10132060d..a177272dff 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiRestClient.java
@@ -34,6 +34,7 @@ import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.data.models.OperationType;
import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException;
import org.onap.cps.ncmp.impl.models.RequiredDmiService;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java
new file mode 100644
index 0000000000..4134a56ead
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfiguration.java
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.dmi;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.config.DmiHttpClientConfig;
+import org.onap.cps.ncmp.impl.utils.http.WebClientConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+@RequiredArgsConstructor
+public class DmiWebClientsConfiguration extends WebClientConfiguration {
+
+ private final DmiHttpClientConfig dmiHttpClientConfig;
+
+ /**
+ * Configures and creates a web client bean for DMI data services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for data services.
+ */
+ @Bean
+ public WebClient dataServicesWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getDataServices());
+ }
+
+ /**
+ * Configures and creates a web client bean for DMI model services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for model services.
+ */
+ @Bean
+ public WebClient modelServicesWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getModelServices());
+ }
+
+ /**
+ * Configures and creates a web client bean for DMI health check services.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for health check services.
+ */
+ @Bean
+ public WebClient healthChecksWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, dmiHttpClientConfig.getHealthCheckServices());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
index d6bda3beee..d9f7e38993 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
@@ -37,6 +37,7 @@ import com.hazelcast.map.IMap;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -58,13 +59,11 @@ import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.ncmp.impl.inventory.sync.ModuleOperationsUtils;
import org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventsCmHandleStateHandler;
-import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Slf4j
@@ -79,11 +78,7 @@ public class CmHandleRegistrationService {
private final CpsDataService cpsDataService;
private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
private final IMap<String, Object> moduleSyncStartedOnCmHandles;
-
- @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN)
- private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
private final TrustLevelManager trustLevelManager;
-
private final AlternateIdChecker alternateIdChecker;
/**
@@ -98,7 +93,7 @@ public class CmHandleRegistrationService {
dmiPluginRegistration.validateDmiPluginRegistration();
final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
- setTrustLevelPerDmiPlugin(dmiPluginRegistration);
+ trustLevelManager.registerDmiPlugin(dmiPluginRegistration);
processRemovedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
@@ -153,7 +148,7 @@ public class CmHandleRegistrationService {
final Set<String> notDeletedCmHandles = new HashSet<>();
for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
try {
- batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
+ batchDeleteCmHandlesFromDbAndCaches(tobeRemovedCmHandleBatch);
tobeRemovedCmHandleBatch.forEach(cmHandleId ->
cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
@@ -215,8 +210,7 @@ public class CmHandleRegistrationService {
final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
final List<String> cmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles();
- final String upgradedModuleSetTag =
- StringUtils.trimToEmpty(dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag());
+ final String upgradedModuleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag();
final Map<YangModelCmHandle, CmHandleState> acceptedCmHandleStatePerCmHandle
= new HashMap<>(cmHandleIds.size());
final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(cmHandleIds.size());
@@ -260,7 +254,7 @@ public class CmHandleRegistrationService {
ncmpServiceCmHandle.getRegistrationTrustLevel());
}
}
- trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
+ trustLevelManager.registerCmHandles(initialTrustLevelPerCmHandleId);
}
private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
@@ -281,7 +275,7 @@ public class CmHandleRegistrationService {
private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
try {
- deleteCmHandleFromDbAndModuleSyncMap(cmHandleId);
+ deleteCmHandleFromDbAndCaches(cmHandleId);
return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId);
} catch (final DataNodeNotFoundException dataNodeNotFoundException) {
log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
@@ -304,15 +298,17 @@ public class CmHandleRegistrationService {
lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
}
- private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
+ private void deleteCmHandleFromDbAndCaches(final String cmHandleId) {
inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
+ trustLevelManager.removeCmHandles(Collections.singleton(cmHandleId));
removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
}
- private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
+ private void batchDeleteCmHandlesFromDbAndCaches(final Collection<String> cmHandleIds) {
inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
+ trustLevelManager.removeCmHandles(cmHandleIds);
cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
}
@@ -346,14 +342,6 @@ public class CmHandleRegistrationService {
return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
}
- private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
- if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
- trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
- } else {
- trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
- }
- }
-
private Collection<String> checkAlternateIds(
final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java
index e5848c0dfa..03ec30b73b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryService.java
@@ -22,7 +22,7 @@ package org.onap.cps.ncmp.impl.inventory;
import java.util.Collection;
import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
public interface ParameterizedCmHandleQueryService {
/**
@@ -51,22 +51,14 @@ public interface ParameterizedCmHandleQueryService {
Collection<String> queryCmHandleIdsForInventory(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
/**
- * Query and return cm handle objects that match the given query parameters.
+ * Query and return yang model cm handle objects that match the given query parameters.
* Supported query types:
* public properties
* modules
* cps-path
*
* @param cmHandleQueryServiceParameters the cm handle query parameters
- * @return collection of cm handles
+ * @return collection of yang model cm handles
*/
- Collection<NcmpServiceCmHandle> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
-
- /**
- * Get all cm handle objects.
- * Note: it is similar to all the queries above but simply no conditions and hence not 'parameterized'
- *
- * @return collection of cm handles
- */
- Collection<NcmpServiceCmHandle> getAllCmHandles();
+ Collection<YangModelCmHandle> queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
index 34eeaccf8f..84229e2895 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
@@ -27,7 +27,6 @@ import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HA
import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.HAS_ALL_PROPERTIES;
import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_CPS_PATH;
import static org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions.WITH_TRUST_LEVEL;
-import static org.onap.cps.ncmp.impl.utils.YangDataConverter.toNcmpServiceCmHandle;
import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS;
@@ -40,10 +39,8 @@ import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
import org.onap.cps.cpspath.parser.PathParsingException;
import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters;
-import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
import org.onap.cps.ncmp.impl.inventory.models.PropertyType;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
@@ -54,7 +51,6 @@ import org.onap.cps.spi.model.DataNode;
import org.springframework.stereotype.Service;
@Service
-@Slf4j
@RequiredArgsConstructor
public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHandleQueryService {
@@ -83,22 +79,18 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan
}
@Override
- public Collection<NcmpServiceCmHandle> queryCmHandles(
- final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
-
+ public Collection<YangModelCmHandle> queryCmHandles(
+ final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) {
return getAllCmHandles();
}
-
final Collection<String> cmHandleIds = queryCmHandleIds(cmHandleQueryServiceParameters);
-
- return getNcmpServiceCmHandles(cmHandleIds);
+ return inventoryPersistence.getYangModelCmHandles(cmHandleIds);
}
- @Override
- public Collection<NcmpServiceCmHandle> getAllCmHandles() {
+ private Collection<YangModelCmHandle> getAllCmHandles() {
final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next();
- return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet());
+ return dataNode.getChildDataNodes().stream().map(YangDataConverter::toYangModelCmHandle).toList();
}
private Collection<String> queryCmHandlesByDmiPlugin(
@@ -226,22 +218,6 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan
return collectCmHandleIdsFromDataNodes(dataNode.getChildDataNodes());
}
- private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) {
- final Collection<YangModelCmHandle> yangModelcmHandles
- = inventoryPersistence.getYangModelCmHandles(cmHandleIds);
-
- final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size());
-
- yangModelcmHandles.forEach(yangModelcmHandle ->
- ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle))
- );
- return ncmpServiceCmHandles;
- }
-
- private NcmpServiceCmHandle createNcmpServiceCmHandle(final DataNode dataNode) {
- return toNcmpServiceCmHandle(YangDataConverter.toYangModelCmHandle(dataNode));
- }
-
private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters,
final Function<CmHandleQueryServiceParameters, Collection<String>>...
queryFunctions) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
index 433c67f100..8ba70b3a31 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
@@ -36,10 +36,10 @@ import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.inventory.models.YangResource;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.ncmp.impl.models.DmiRequestBody;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
@@ -107,7 +107,7 @@ public class DmiModelOperations {
final String jsonRequestBody,
final String cmHandle,
final String resourceName) {
- final UrlTemplateParameters urlTemplateParameters = DmiServiceUrlTemplateBuilder.newInstance()
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
.fixedPathSegment("ch")
.variablePathSegment("cmHandleId", cmHandle)
.fixedPathSegment(resourceName)
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
index 617fe7f01d..efcbb78ace 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
@@ -52,7 +52,7 @@ public class DeviceTrustLevelMessageConsumer {
final DeviceTrustLevel deviceTrustLevel =
CloudEventMapper.toTargetEvent(consumerRecord.value(), DeviceTrustLevel.class);
final String trustLevelAsString = deviceTrustLevel.getData().getTrustLevel();
- trustLevelManager.handleUpdateOfDeviceTrustLevel(cmHandleId, TrustLevel.valueOf(trustLevelAsString));
+ trustLevelManager.updateCmHandleTrustLevel(cmHandleId, TrustLevel.valueOf(trustLevelAsString));
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
index c81e9b7840..7581c4af7a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
@@ -26,9 +26,9 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
-import org.onap.cps.ncmp.impl.dmi.DmiServiceUrlTemplateBuilder;
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters;
import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
+import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -67,13 +67,13 @@ public class DmiPluginTrustLevelWatchDog {
} else {
final Collection<String> cmHandleIds =
cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiServiceName);
- trustLevelManager.handleUpdateOfDmiTrustLevel(dmiServiceName, cmHandleIds, newDmiTrustLevel);
+ trustLevelManager.updateDmi(dmiServiceName, cmHandleIds, newDmiTrustLevel);
}
});
}
private String getDmiHealthStatus(final String dmiServiceBaseUrl) {
- final UrlTemplateParameters urlTemplateParameters = DmiServiceUrlTemplateBuilder.newInstance()
+ final UrlTemplateParameters urlTemplateParameters = RestServiceUrlTemplateBuilder.newInstance()
.createUrlTemplateParametersForHealthCheck(dmiServiceBaseUrl);
return dmiRestClient.getDmiHealthStatus(urlTemplateParameters).block();
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
index 44079c0bc9..33310b955e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
@@ -24,6 +24,7 @@ import java.util.Collection;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
@@ -49,11 +50,26 @@ public class TrustLevelManager {
private static final String AVC_NO_OLD_VALUE = null;
/**
+ * Add dmi plugins to the cache.
+ *
+ * @param dmiPluginRegistration a dmi plugin being registered
+ */
+ public void registerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
+ final String dmiServiceName;
+ if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
+ dmiServiceName = dmiPluginRegistration.getDmiPlugin();
+ } else {
+ dmiServiceName = dmiPluginRegistration.getDmiDataPlugin();
+ }
+ trustLevelPerDmiPlugin.put(dmiServiceName, TrustLevel.COMPLETE);
+ }
+
+ /**
* Add cmHandles to the cache and publish notification for initial trust level of cmHandles if it is NONE.
*
* @param cmHandlesToBeCreated a list of cmHandles being created
*/
- public void handleInitialRegistrationOfTrustLevels(final Map<String, TrustLevel> cmHandlesToBeCreated) {
+ public void registerCmHandles(final Map<String, TrustLevel> cmHandlesToBeCreated) {
for (final Map.Entry<String, TrustLevel> entry : cmHandlesToBeCreated.entrySet()) {
final String cmHandleId = entry.getKey();
if (trustLevelPerCmHandle.containsKey(cmHandleId)) {
@@ -82,15 +98,15 @@ public class TrustLevelManager {
* @param affectedCmHandleIds cm handle ids belonging to dmi service name
* @param newDmiTrustLevel new trust level of the dmi plugin
*/
- public void handleUpdateOfDmiTrustLevel(final String dmiServiceName,
- final Collection<String> affectedCmHandleIds,
- final TrustLevel newDmiTrustLevel) {
+ public void updateDmi(final String dmiServiceName,
+ final Collection<String> affectedCmHandleIds,
+ final TrustLevel newDmiTrustLevel) {
final TrustLevel oldDmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
trustLevelPerDmiPlugin.put(dmiServiceName, newDmiTrustLevel);
for (final String affectedCmHandleId : affectedCmHandleIds) {
- final TrustLevel deviceTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
- final TrustLevel oldEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
- final TrustLevel newEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
+ final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
+ final TrustLevel oldEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
+ final TrustLevel newEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
sendAvcNotificationIfRequired(affectedCmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
}
}
@@ -100,23 +116,56 @@ public class TrustLevelManager {
* changed.
*
* @param cmHandleId cm handle id
- * @param newDeviceTrustLevel new trust level of the device
+ * @param newCmHandleTrustLevel new trust level of the device
*/
- public void handleUpdateOfDeviceTrustLevel(final String cmHandleId,
- final TrustLevel newDeviceTrustLevel) {
- final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
- final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ public void updateCmHandleTrustLevel(final String cmHandleId,
+ final TrustLevel newCmHandleTrustLevel) {
+ final String dmiServiceName = getDmiServiceName(cmHandleId);
final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
- final TrustLevel oldDeviceTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+ final TrustLevel oldCmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
- final TrustLevel oldEffectiveTrustLevel = oldDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
- final TrustLevel newEffectiveTrustLevel = newDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+ final TrustLevel oldEffectiveTrustLevel = oldCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+ final TrustLevel newEffectiveTrustLevel = newCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
- trustLevelPerCmHandle.put(cmHandleId, newDeviceTrustLevel);
+ trustLevelPerCmHandle.put(cmHandleId, newCmHandleTrustLevel);
sendAvcNotificationIfRequired(cmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
}
+ /**
+ * Select effective trust level among device and dmi plugin.
+ *
+ * @param cmHandleId cm handle id
+ * @return TrustLevel effective trust level
+ */
+ public TrustLevel getEffectiveTrustLevel(final String dmiServiceName, final String cmHandleId) {
+ final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
+ final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+ return dmiTrustLevel.getEffectiveTrustLevel(cmHandleTrustLevel);
+ }
+
+ /**
+ * Remove cm handle trust level from the cache and publish notification for trust level of cmHandles
+ * if it is COMPLETE.
+ *
+ * @param cmHandleIds cm handle ids to be removed from the cache
+ */
+ public void removeCmHandles(final Collection<String> cmHandleIds) {
+ for (final String cmHandleId : cmHandleIds) {
+ if (trustLevelPerCmHandle.containsKey(cmHandleId)) {
+ final TrustLevel oldTrustLevel = trustLevelPerCmHandle.remove(cmHandleId);
+ sendAvcNotificationIfRequired(cmHandleId, oldTrustLevel, TrustLevel.NONE);
+ } else {
+ log.debug("Removed Cm handle: {} is not in trust level cache", cmHandleId);
+ }
+ }
+ }
+
+ private String getDmiServiceName(final String cmHandleId) {
+ final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+ return yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+ }
+
private void sendAvcNotificationIfRequired(final String notificationCandidateCmHandleId,
final TrustLevel oldEffectiveTrustLevel,
final TrustLevel newEffectiveTrustLevel) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java
new file mode 100644
index 0000000000..333030ccd2
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.policyexecutor;
+
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.config.PolicyExecutorHttpClientConfig;
+import org.onap.cps.ncmp.impl.utils.http.WebClientConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+@RequiredArgsConstructor
+public class PolicyExecutorWebClientConfiguration extends WebClientConfiguration {
+
+ private final PolicyExecutorHttpClientConfig policyExecutorHttpClientConfig;
+
+ /**
+ * Configures and creates a web client bean for Policy Executor.
+ *
+ * @param webClientBuilder The builder instance to create the WebClient.
+ * @return a WebClient instance configured for Policy Executor.
+ */
+ @Bean
+ public WebClient policyExecutorWebClient(final WebClient.Builder webClientBuilder) {
+ return configureWebClient(webClientBuilder, policyExecutorHttpClientConfig.getAllServices());
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java
index c408ff9b13..c526dfb297 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java
@@ -59,7 +59,7 @@ public class AlternateIdMatcher {
/**
* Get cm handle Id from given cmHandleReference.
*
- * @param cmHandleReference alternate ID
+ * @param cmHandleReference cm handle or alternate identifier
* @return cm handle id string
*/
public String getCmHandleId(final String cmHandleReference) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java
index e7dbea83f2..c850ca94a0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilder.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilder.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.impl.dmi;
+package org.onap.cps.ncmp.impl.utils.http;
import java.util.Collections;
import java.util.HashMap;
@@ -30,7 +30,7 @@ import org.apache.logging.log4j.util.Strings;
import org.springframework.web.util.UriComponentsBuilder;
@NoArgsConstructor
-public class DmiServiceUrlTemplateBuilder {
+public class RestServiceUrlTemplateBuilder {
private final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance();
private static final String FIXED_PATH_SEGMENT = null;
@@ -43,8 +43,8 @@ public class DmiServiceUrlTemplateBuilder {
*
* @return a new instance of DmiServiceUrlTemplateBuilder
*/
- public static DmiServiceUrlTemplateBuilder newInstance() {
- return new DmiServiceUrlTemplateBuilder();
+ public static RestServiceUrlTemplateBuilder newInstance() {
+ return new RestServiceUrlTemplateBuilder();
}
/**
@@ -53,7 +53,7 @@ public class DmiServiceUrlTemplateBuilder {
* @param pathSegment the path segment
* @return this builder instance
*/
- public DmiServiceUrlTemplateBuilder fixedPathSegment(final String pathSegment) {
+ public RestServiceUrlTemplateBuilder fixedPathSegment(final String pathSegment) {
pathSegments.put(pathSegment, FIXED_PATH_SEGMENT);
return this;
}
@@ -66,7 +66,7 @@ public class DmiServiceUrlTemplateBuilder {
* @param value the value to be insert in teh URL for the given variable path segment
* @return this builder instance
*/
- public DmiServiceUrlTemplateBuilder variablePathSegment(final String pathSegment, final String value) {
+ public RestServiceUrlTemplateBuilder variablePathSegment(final String pathSegment, final String value) {
pathSegments.put(pathSegment, value);
return this;
}
@@ -80,8 +80,8 @@ public class DmiServiceUrlTemplateBuilder {
*
* @return this builder instance
*/
- public DmiServiceUrlTemplateBuilder queryParameter(final String queryParameterName,
- final String queryParameterValue) {
+ public RestServiceUrlTemplateBuilder queryParameter(final String queryParameterName,
+ final String queryParameterValue) {
if (Strings.isNotBlank(queryParameterValue)) {
queryParameters.put(queryParameterName, queryParameterValue);
}
@@ -91,14 +91,12 @@ public class DmiServiceUrlTemplateBuilder {
/**
* Constructs a URL template with variables based on the accumulated path segments and query parameters.
*
- * @param dmiServiceBaseUrl the base URL of the DMI service, e.g., "http://dmi-service.com".
- * @param dmiBasePath the base path of the DMI service
+ * @param serviceBaseUrl the base URL of the service, e.g., "http://dmi-service.com".
+ * @param basePath the base path of the service
* @return a UrlTemplateParameters instance containing the complete URL template and URL variables
*/
- public UrlTemplateParameters createUrlTemplateParameters(final String dmiServiceBaseUrl, final String dmiBasePath) {
- this.uriComponentsBuilder.pathSegment(dmiBasePath)
- .pathSegment(VERSION_SEGMENT);
-
+ public UrlTemplateParameters createUrlTemplateParameters(final String serviceBaseUrl, final String basePath) {
+ this.uriComponentsBuilder.pathSegment(basePath).pathSegment(VERSION_SEGMENT);
final Map<String, String> urlTemplateVariables = new HashMap<>();
pathSegments.forEach((pathSegmentName, variablePathValue) -> {
@@ -115,22 +113,21 @@ public class DmiServiceUrlTemplateBuilder {
urlTemplateVariables.put(paramName, paramValue);
});
- final String urlTemplate = dmiServiceBaseUrl + this.uriComponentsBuilder.build().toUriString();
+ final String urlTemplate = serviceBaseUrl + this.uriComponentsBuilder.build().toUriString();
return new UrlTemplateParameters(urlTemplate, urlTemplateVariables);
}
/**
- * Constructs a URL for DMI health check based on the given base URL.
+ * Constructs a URL for a spring actuator health check based on the given base URL.
*
- * @param dmiServiceBaseUrl the base URL of the DMI service, e.g., "http://dmi-service.com".
+ * @param serviceBaseUrl the base URL of the service, e.g., "http://dmi-service.com".
* @return a {@link UrlTemplateParameters} instance containing the complete URL template and empty URL variables,
* suitable for DMI health check.
*/
- public UrlTemplateParameters createUrlTemplateParametersForHealthCheck(final String dmiServiceBaseUrl) {
- this.uriComponentsBuilder.pathSegment("actuator")
- .pathSegment("health");
+ public UrlTemplateParameters createUrlTemplateParametersForHealthCheck(final String serviceBaseUrl) {
+ this.uriComponentsBuilder.pathSegment("actuator").pathSegment("health");
- final String urlTemplate = dmiServiceBaseUrl + this.uriComponentsBuilder.build().toUriString();
+ final String urlTemplate = serviceBaseUrl + this.uriComponentsBuilder.build().toUriString();
return new UrlTemplateParameters(urlTemplate, Collections.emptyMap());
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/UrlTemplateParameters.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java
index f51511116a..839af71823 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/UrlTemplateParameters.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/UrlTemplateParameters.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.impl.dmi;
+package org.onap.cps.ncmp.impl.utils.http;
import java.util.Map;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java
index c176e40226..d8e8350345 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfiguration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/http/WebClientConfiguration.java
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.impl.dmi;
+package org.onap.cps.ncmp.impl.utils.http;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.channel.ChannelOption;
@@ -27,10 +27,7 @@ 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.onap.cps.ncmp.config.HttpClientConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.onap.cps.ncmp.config.ServiceConfig;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
@@ -39,58 +36,22 @@ import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
/**
- * Configures and creates WebClient beans for various DMI services including data, model, and health check services.
+ * Configures and creates WebClient beans for various rest services such as DMI and Policy Executor.
* 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
-public class DmiWebClientConfiguration {
+public class WebClientConfiguration {
- private final HttpClientConfiguration httpClientConfiguration;
private static final Duration DEFAULT_RESPONSE_TIMEOUT = Duration.ofSeconds(30);
- /**
- * Configures and creates a web client bean for DMI data services.
- *
- * @param webClientBuilder The builder instance to create the WebClient.
- * @return a WebClient instance configured for data services.
- */
- @Bean
- public WebClient dataServicesWebClient(final WebClient.Builder webClientBuilder) {
- return configureWebClient(webClientBuilder, httpClientConfiguration.getDataServices());
- }
-
- /**
- * Configures and creates a web client bean for DMI model services.
- *
- * @param webClientBuilder The builder instance to create the WebClient.
- * @return a WebClient instance configured for model services.
- */
- @Bean
- public WebClient modelServicesWebClient(final WebClient.Builder webClientBuilder) {
- return configureWebClient(webClientBuilder, httpClientConfiguration.getModelServices());
- }
-
- /**
- * Configures and creates a web client bean for DMI health check services.
- *
- * @param webClientBuilder The builder instance to create the WebClient.
- * @return a WebClient instance configured for health check services.
- */
- @Bean
- public WebClient healthChecksWebClient(final WebClient.Builder webClientBuilder) {
- return configureWebClient(webClientBuilder, httpClientConfiguration.getHealthCheckServices());
- }
-
- private WebClient configureWebClient(final WebClient.Builder webClientBuilder,
- final HttpClientConfiguration.ServiceConfig serviceConfig) {
+ protected WebClient configureWebClient(final WebClient.Builder webClientBuilder,
+ final ServiceConfig serviceConfig) {
final ConnectionProvider connectionProvider = getConnectionProvider(serviceConfig);
final HttpClient httpClient = createHttpClient(serviceConfig, connectionProvider);
return buildAndGetWebClient(webClientBuilder, httpClient, serviceConfig.getMaximumInMemorySizeInMegabytes());
}
- private static HttpClient createHttpClient(final HttpClientConfiguration.ServiceConfig serviceConfig,
+ private static HttpClient createHttpClient(final ServiceConfig serviceConfig,
final ConnectionProvider connectionProvider) {
return HttpClient.create(connectionProvider)
.responseTimeout(DEFAULT_RESPONSE_TIMEOUT)
@@ -103,7 +64,7 @@ public class DmiWebClientConfiguration {
}
@SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE")
- private static ConnectionProvider getConnectionProvider(final HttpClientConfiguration.ServiceConfig serviceConfig) {
+ private static ConnectionProvider getConnectionProvider(final ServiceConfig serviceConfig) {
return ConnectionProvider.builder(serviceConfig.getConnectionProviderName())
.maxConnections(serviceConfig.getMaximumConnectionsTotal())
.pendingAcquireMaxCount(serviceConfig.getPendingAcquireMaxCount())
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy
index 1d3b22fb73..23f5edd890 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/HttpClientConfigurationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/DmiHttpClientConfigSpec.groovy
@@ -28,46 +28,46 @@ import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
@SpringBootTest
-@ContextConfiguration(classes = [HttpClientConfiguration])
-@EnableConfigurationProperties(HttpClientConfiguration)
-class HttpClientConfigurationSpec extends Specification {
+@ContextConfiguration(classes = [DmiHttpClientConfig])
+@EnableConfigurationProperties
+class DmiHttpClientConfigSpec extends Specification {
@Autowired
- HttpClientConfiguration httpClientConfiguration
+ DmiHttpClientConfig dmiHttpClientConfig
def 'Test http client configuration properties of data with custom and default values'() {
- expect: 'properties are populated correctly for data'
- with(httpClientConfiguration.dataServices) {
- assert connectionTimeoutInSeconds == 123
- assert readTimeoutInSeconds == 33
- assert writeTimeoutInSeconds == 30
- assert maximumConnectionsTotal == 100
- assert pendingAcquireMaxCount == 22
- assert maximumInMemorySizeInMegabytes == 7
+ expect: 'properties are populated correctly for data services'
+ with(dmiHttpClientConfig.dataServices) {
+ assert maximumInMemorySizeInMegabytes == 1
+ assert maximumConnectionsTotal == 2
+ assert pendingAcquireMaxCount == 3
+ assert connectionTimeoutInSeconds == 4
+ assert readTimeoutInSeconds == 5
+ assert writeTimeoutInSeconds == 6
}
}
def 'Test http client configuration properties of model with custom and default values'() {
- expect: 'properties are populated correctly for model'
- with(httpClientConfiguration.modelServices) {
- assert connectionTimeoutInSeconds == 456
- assert readTimeoutInSeconds == 30
- assert writeTimeoutInSeconds == 30
- assert maximumConnectionsTotal == 111
- assert pendingAcquireMaxCount == 44
- assert maximumInMemorySizeInMegabytes == 8
+ expect: 'properties are populated correctly for model services'
+ with(dmiHttpClientConfig.modelServices) {
+ assert maximumInMemorySizeInMegabytes == 11
+ assert maximumConnectionsTotal == 12
+ assert pendingAcquireMaxCount == 13
+ assert connectionTimeoutInSeconds == 14
+ assert readTimeoutInSeconds == 15
+ assert writeTimeoutInSeconds == 16
}
}
def 'Test http client configuration properties of health with default values'() {
- expect: 'properties are populated correctly for health'
- with(httpClientConfiguration.healthCheckServices) {
- assert connectionTimeoutInSeconds == 30
- assert readTimeoutInSeconds == 30
- assert writeTimeoutInSeconds == 30
- assert maximumConnectionsTotal == 10
- assert pendingAcquireMaxCount == 5
- assert maximumInMemorySizeInMegabytes == 1
+ expect: 'properties are populated correctly for health check services'
+ with(dmiHttpClientConfig.healthCheckServices) {
+ assert maximumInMemorySizeInMegabytes == 21
+ assert maximumConnectionsTotal == 22
+ assert pendingAcquireMaxCount == 23
+ assert connectionTimeoutInSeconds == 24
+ assert readTimeoutInSeconds == 25
+ assert writeTimeoutInSeconds == 26
}
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy
new file mode 100644
index 0000000000..ca71c345c1
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/config/PolicyExecutorHttpClientConfigSpec.groovy
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.config
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.ContextConfiguration
+import spock.lang.Specification
+
+@SpringBootTest
+@ContextConfiguration(classes = [PolicyExecutorHttpClientConfig])
+@EnableConfigurationProperties
+class PolicyExecutorHttpClientConfigSpec extends Specification {
+
+ @Autowired
+ PolicyExecutorHttpClientConfig policyExecutorHttpClientConfig
+
+ def 'Http client configuration properties for policy executor http client.'() {
+ expect: 'properties are populated correctly for all services'
+ with(policyExecutorHttpClientConfig.allServices) {
+ assert maximumInMemorySizeInMegabytes == 31
+ assert maximumConnectionsTotal == 32
+ assert pendingAcquireMaxCount == 33
+ assert connectionTimeoutInSeconds == 34
+ assert readTimeoutInSeconds == 35
+ assert writeTimeoutInSeconds == 36
+ }
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy
index 8b369bf549..fd76abb581 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy
@@ -28,16 +28,16 @@ import org.onap.cps.ncmp.api.data.models.DataOperationRequest
import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException
import org.onap.cps.ncmp.config.CpsApplicationContext
import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor
import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec
import org.onap.cps.ncmp.impl.dmi.DmiProperties
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters
import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootContextLoader
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
@@ -49,6 +49,8 @@ import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR
import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_OPERATIONAL
import static org.onap.cps.ncmp.api.data.models.DatastoreType.PASSTHROUGH_RUNNING
import static org.onap.cps.ncmp.api.data.models.OperationType.CREATE
+import static org.onap.cps.ncmp.api.data.models.OperationType.DELETE
+import static org.onap.cps.ncmp.api.data.models.OperationType.PATCH
import static org.onap.cps.ncmp.api.data.models.OperationType.READ
import static org.onap.cps.ncmp.api.data.models.OperationType.UPDATE
import static org.onap.cps.ncmp.impl.models.RequiredDmiService.DATA
@@ -161,6 +163,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
def 'Write data for pass-through:running datastore in DMI.'() {
given: 'a cm handle for #cmHandleId'
mockYangModelCmHandleRetrieval([yangModelCmHandleProperty])
+ alternateIdMatcher.getCmHandleId(cmHandleId) >> cmHandleId
and: 'a positive response from DMI service when it is called with the expected parameters'
def expectedUrlTemplateParameters = new UrlTemplateParameters('myServiceName/dmi/v1/ch/{cmHandleId}/data/ds/{datastore}?resourceIdentifier={resourceIdentifier}', ['resourceIdentifier': resourceIdentifier, 'datastore': 'ncmp-datastore:passthrough-running', 'cmHandleId': cmHandleId])
def expectedJson = '{"operation":"' + expectedOperationInUrl + '","dataType":"some data type","data":"requestData","cmHandleProperties":{"prop1":"val1"},"moduleSetTag":""}'
@@ -176,6 +179,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
operation || expectedOperationInUrl
CREATE || 'create'
UPDATE || 'update'
+ DELETE || 'delete'
+ PATCH || 'patch'
}
def 'State Ready validation'() {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy
new file mode 100644
index 0000000000..c086eab810
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorConfigurationSpec.groovy
@@ -0,0 +1,45 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.data
+
+import org.onap.cps.ncmp.config.PolicyExecutorHttpClientConfig
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor
+import org.onap.cps.ncmp.impl.policyexecutor.PolicyExecutorWebClientConfiguration
+import org.onap.cps.ncmp.utils.WebClientBuilderTestConfig
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.ContextConfiguration
+import spock.lang.Specification
+
+@SpringBootTest
+@ContextConfiguration(classes = [PolicyExecutor, PolicyExecutorWebClientConfiguration, PolicyExecutorHttpClientConfig, WebClientBuilderTestConfig ])
+class PolicyExecutorConfigurationSpec extends Specification {
+
+ @Autowired
+ PolicyExecutor objectUnderTest
+
+ def 'Policy executor configuration properties.'() {
+ expect: 'properties used from application.yml'
+ assert objectUnderTest.enabled
+ assert objectUnderTest.serverAddress == 'http://localhost'
+ assert objectUnderTest.serverPort == '8785'
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy
index 654206776b..a5776676dc 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/PolicyExecutorSpec.groovy
@@ -1,68 +1,139 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
package org.onap.cps.ncmp.impl.data
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.JsonNode
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.ncmp.api.exceptions.PolicyExecutorException
+import org.onap.cps.ncmp.api.exceptions.ServerNcmpException
+import org.onap.cps.ncmp.impl.data.policyexecutor.PolicyExecutor
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.test.context.ContextConfiguration
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.web.reactive.function.client.WebClient
+import reactor.core.publisher.Mono
import spock.lang.Specification
+import static org.onap.cps.ncmp.api.data.models.OperationType.CREATE
+import static org.onap.cps.ncmp.api.data.models.OperationType.DELETE
import static org.onap.cps.ncmp.api.data.models.OperationType.PATCH
+import static org.onap.cps.ncmp.api.data.models.OperationType.UPDATE
-@SpringBootTest
-@ContextConfiguration(classes = [PolicyExecutor])
class PolicyExecutorSpec extends Specification {
- @Autowired
- PolicyExecutor objectUnderTest
+ def mockWebClient = Mock(WebClient)
+ def mockRequestBodyUriSpec = Mock(WebClient.RequestBodyUriSpec)
+ def mockResponseSpec = Mock(WebClient.ResponseSpec)
+
+ PolicyExecutor objectUnderTest = new PolicyExecutor(mockWebClient)
def logAppender = Spy(ListAppender<ILoggingEvent>)
+ ObjectMapper objectMapper = new ObjectMapper()
+
def setup() {
setupLogger()
+ objectUnderTest.enabled = true
+ mockWebClient.post() >> mockRequestBodyUriSpec
+ mockRequestBodyUriSpec.uri(*_) >> mockRequestBodyUriSpec
+ mockRequestBodyUriSpec.header(*_) >> mockRequestBodyUriSpec
+ mockRequestBodyUriSpec.body(*_) >> mockRequestBodyUriSpec
+ mockRequestBodyUriSpec.retrieve() >> mockResponseSpec
}
def cleanup() {
((Logger) LoggerFactory.getLogger(PolicyExecutor)).detachAndStopAllAppenders()
}
- def 'Configuration properties.'() {
- expect: 'properties used from application.yml'
- assert objectUnderTest.enabled
- assert objectUnderTest.serverAddress == 'http://localhost'
- assert objectUnderTest.serverPort == '8785'
+ def 'Permission check with allow response.'() {
+ given: 'allow response'
+ mockResponse([decision:'allow'], HttpStatus.OK)
+ when: 'permission is checked for an operation'
+ objectUnderTest.checkPermission(new YangModelCmHandle(), operationType, 'my credentials','my resource','my change')
+ then: 'system logs the operation is allowed'
+ assert getLogEntry(2) == 'Policy Executor allows the operation'
+ and: 'no exception occurs'
+ noExceptionThrown()
+ where: 'all write operations are tested'
+ operationType << [ CREATE, DELETE, PATCH, UPDATE ]
+ }
+
+ def 'Permission check with other response (not allowed).'() {
+ given: 'other response'
+ mockResponse([decision:'other', decisionId:123, message:'I dont like Mondays' ], HttpStatus.OK)
+ when: 'permission is checked for an operation'
+ objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change')
+ then: 'Policy Executor exception is thrown'
+ def thrownException = thrown(PolicyExecutorException)
+ assert thrownException.message == 'Policy Executor did not allow request. Decision #123 : other'
+ assert thrownException.details == 'I dont like Mondays'
+ }
+
+ def 'Permission check with non 2xx response.'() {
+ given: 'other response'
+ mockResponse([], HttpStatus.I_AM_A_TEAPOT)
+ when: 'permission is checked for an operation'
+ objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change')
+ then: 'Server Ncmp exception is thrown'
+ def thrownException = thrown(ServerNcmpException)
+ assert thrownException.message == 'Policy Executor invocation failed'
+ assert thrownException.details == 'HTTP status code: 418'
}
- def 'Permission check logging.'() {
+ def 'Permission check with invalid response from Policy Executor.'() {
+ given: 'invalid response from Policy executor'
+ mockResponseSpec.toEntity(*_) >> invalidResponse
when: 'permission is checked for an operation'
- def yangModelCmHandle = new YangModelCmHandle(id:'ch-1', alternateId:'fdn1')
- objectUnderTest.checkPermission(yangModelCmHandle, PATCH, 'my credentials','my resource','my change')
- then: 'correct details are logged '
- assert getLogEntry(0) == 'Policy Executor Enabled'
- assert getLogEntry(3).contains('my credentials')
- assert getLogEntry(4).contains('cm_patch')
- assert getLogEntry(5).contains('fdn1')
- assert getLogEntry(6).contains('ch-1')
- assert getLogEntry(7).contains('my resource')
- assert getLogEntry(8).contains('my change')
+ objectUnderTest.checkPermission(new YangModelCmHandle(), CREATE, 'my credentials','my resource','my change')
+ then: 'system logs the expected message'
+ assert getLogEntry(1) == expectedMessage
+ where: 'following invalid responses are received'
+ invalidResponse || expectedMessage
+ Mono.empty() || 'No valid response from policy, ignored'
+ Mono.just(new ResponseEntity<>(null, HttpStatus.OK)) || 'No valid response body from policy, ignored'
}
- def 'Permission check with feature disabled.'() {
+ def 'Permission check feature disabled.'() {
given: 'feature is disabled'
objectUnderTest.enabled = false
when: 'permission is checked for an operation'
objectUnderTest.checkPermission(new YangModelCmHandle(), PATCH, 'my credentials','my resource','my change')
- then: 'nothing is logged'
- assert logAppender.list.isEmpty()
+ then: 'system logs that the feature not enabled'
+ assert getLogEntry(0) == 'Policy Executor Enabled: false'
+ }
+
+ def mockResponse(mockResponseAsMap, httpStatus) {
+ JsonNode jsonNode = objectMapper.readTree(objectMapper.writeValueAsString(mockResponseAsMap))
+ def mono = Mono.just(new ResponseEntity<>(jsonNode, httpStatus))
+ mockResponseSpec.toEntity(*_) >> mono
}
def setupLogger() {
def logger = LoggerFactory.getLogger(PolicyExecutor)
- logger.setLevel(Level.DEBUG)
+ logger.setLevel(Level.TRACE)
logger.addAppender(logAppender)
logAppender.start()
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy
index 3af474040e..74bd0484df 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobResultServiceImplSpec.groovy
@@ -22,7 +22,7 @@ package org.onap.cps.ncmp.impl.datajobs
import org.onap.cps.ncmp.impl.dmi.DmiProperties
import org.onap.cps.ncmp.impl.dmi.DmiRestClient
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import reactor.core.publisher.Mono
import spock.lang.Specification
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy
index d231dfa755..be46d885e0 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/DataJobStatusServiceImplSpec.groovy
@@ -22,7 +22,7 @@ package org.onap.cps.ncmp.impl.datajobs
import org.onap.cps.ncmp.impl.dmi.DmiProperties
import org.onap.cps.ncmp.impl.dmi.DmiRestClient
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import reactor.core.publisher.Mono
import spock.lang.Specification
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy
index affbf2aa4f..65fda8718c 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy
@@ -46,6 +46,7 @@ abstract class DmiOperationsBaseSpec extends Specification {
def yangModelCmHandle = new YangModelCmHandle()
def static dmiServiceName = 'myServiceName'
def static cmHandleId = 'some-cm-handle'
+ def static alternateId = 'alt-id-' + cmHandleId
def static resourceIdentifier = 'parent/child'
def mockYangModelCmHandleRetrieval(dmiProperties) {
@@ -68,6 +69,7 @@ abstract class DmiOperationsBaseSpec extends Specification {
yangModelCmHandle.dmiServiceName = dmiServiceName
yangModelCmHandle.dmiProperties = dmiProperties
yangModelCmHandle.id = cmHandleId
+ yangModelCmHandle.alternateId = alternateId
yangModelCmHandle.compositeState = new CompositeState()
yangModelCmHandle.compositeState.cmHandleState = CmHandleState.READY
yangModelCmHandle.moduleSetTag = moduleSetTag
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy
index d92e69a136..4d47ef14a0 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiRestClientSpec.groovy
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import org.onap.cps.ncmp.api.exceptions.DmiClientRequestException
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import org.onap.cps.ncmp.utils.TestUtils
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.http.HttpHeaders
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy
deleted file mode 100644
index fca47d8c24..0000000000
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientConfigurationSpec.groovy
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.impl.dmi
-
-
-import org.onap.cps.ncmp.config.HttpClientConfiguration
-import org.springframework.boot.context.properties.EnableConfigurationProperties
-import org.springframework.boot.test.context.SpringBootTest
-import org.springframework.test.context.ContextConfiguration
-import org.springframework.test.context.TestPropertySource
-import org.springframework.web.reactive.function.client.WebClient
-import spock.lang.Specification
-
-@SpringBootTest
-@ContextConfiguration(classes = [HttpClientConfiguration])
-@TestPropertySource(properties = ['ncmp.dmi.httpclient.data-services.connectionTimeoutInSeconds=1', 'ncmp.dmi.httpclient.model-services.maximumInMemorySizeInMegabytes=1'])
-@EnableConfigurationProperties
-class DmiWebClientConfigurationSpec extends Specification {
-
- def webClientBuilder = Mock(WebClient.Builder) {
- defaultHeaders(_) >> it
- clientConnector(_) >> it
- codecs(_) >> it
- build() >> Mock(WebClient)
- }
-
- def httpClientConfiguration = Spy(HttpClientConfiguration.class)
-
- def objectUnderTest = new DmiWebClientConfiguration(httpClientConfiguration)
-
- def 'Web Client Configuration construction.'() {
- expect: 'the system can create an instance'
- new DmiWebClientConfiguration(httpClientConfiguration) != null
- }
-
- def 'Creating a web client instance data service.'() {
- given: 'Web client configuration is invoked'
- def dataServicesWebClient = objectUnderTest.dataServicesWebClient(webClientBuilder)
- expect: 'the system can create an instance for data service'
- assert dataServicesWebClient != null
- assert dataServicesWebClient instanceof WebClient
- }
-
- def 'Creating a web client instance model service.'() {
- given: 'Web client configuration invoked'
- def modelServicesWebClient = objectUnderTest.modelServicesWebClient(webClientBuilder)
- expect: 'the system can create an instance for model service'
- assert modelServicesWebClient != null
- assert modelServicesWebClient instanceof WebClient
- }
-
- def 'Creating a web client instance health service.'() {
- given: 'Web client configuration invoked'
- def healthChecksWebClient = objectUnderTest.healthChecksWebClient(webClientBuilder)
- expect: 'the system can create an instance for health service'
- assert healthChecksWebClient != null
- assert healthChecksWebClient instanceof WebClient
- }
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfigurationSpec.groovy
new file mode 100644
index 0000000000..cb209beef0
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiWebClientsConfigurationSpec.groovy
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.dmi
+
+
+import org.onap.cps.ncmp.config.DmiHttpClientConfig
+import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.web.reactive.function.client.WebClient
+import spock.lang.Specification
+
+@SpringBootTest
+@ContextConfiguration(classes = [DmiHttpClientConfig])
+@EnableConfigurationProperties
+class DmiWebClientsConfigurationSpec extends Specification {
+
+ def webClientBuilder = Mock(WebClient.Builder) {
+ defaultHeaders(_) >> it
+ clientConnector(_) >> it
+ codecs(_) >> it
+ build() >> Mock(WebClient)
+ }
+
+ def dmiHttpClientConfiguration = Spy(DmiHttpClientConfig.class)
+
+ def objectUnderTest = new DmiWebClientsConfiguration(dmiHttpClientConfiguration)
+
+ def 'Web client for data services.'() {
+ when: 'creating a web client for dmi data services'
+ def result = objectUnderTest.dataServicesWebClient(webClientBuilder)
+ then: 'a web client is created successfully'
+ assert result != null
+ assert result instanceof WebClient
+ }
+
+ def 'Web client model services.'() {
+ when: 'creating a web client for dmi model services'
+ def result = objectUnderTest.modelServicesWebClient(webClientBuilder)
+ then: 'a web client is created successfully'
+ assert result != null
+ assert result instanceof WebClient
+ }
+
+ def 'Web client health check services.'() {
+ when: 'creating a web client for dmi health check services'
+ def result = objectUnderTest.healthChecksWebClient(webClientBuilder)
+ then: 'a web client is created successfully'
+ assert result != null
+ assert result instanceof WebClient
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
index 0c702abea6..dcff2e9b89 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
@@ -59,13 +59,12 @@ class CmHandleRegistrationServiceSpec extends Specification {
def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
def mockCpsDataService = Mock(CpsDataService)
def mockModuleSyncStartedOnCmHandles = Mock(IMap<String, Object>)
- def trustLevelPerDmiPlugin = [:]
def mockTrustLevelManager = Mock(TrustLevelManager)
def mockAlternateIdChecker = Mock(AlternateIdChecker)
def objectUnderTest = Spy(new CmHandleRegistrationService(
mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCpsDataService, mockLcmEventsCmHandleStateHandler,
- mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin , mockTrustLevelManager, mockAlternateIdChecker))
+ mockModuleSyncStartedOnCmHandles, mockTrustLevelManager, mockAlternateIdChecker))
def setup() {
// always accept all cm handles
@@ -143,9 +142,6 @@ class CmHandleRegistrationServiceSpec extends Specification {
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'create cm handles registration and sync modules is called with the correct plugin information'
1 * objectUnderTest.processCreatedCmHandles(dmiPluginRegistration, _)
- and: 'dmi is added to the dmi trustLevel map'
- assert trustLevelPerDmiPlugin.size() == 1
- assert trustLevelPerDmiPlugin.containsKey(expectedDmiPluginRegisteredName)
where:
scenario | dmiPlugin | dmiModelPlugin | dmiDataPlugin || expectedDmiPluginRegisteredName
'combined DMI plugin' | 'service1' | '' | '' || 'service1'
@@ -212,7 +208,7 @@ class CmHandleRegistrationServiceSpec extends Specification {
when: 'registration is updated'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'trustLevel is set for the created cm-handle'
- 1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(expectedMapping)
+ 1 * mockTrustLevelManager.registerCmHandles(expectedMapping)
where:
scenario | registrationTrustLevel || expectedMapping
'with trusted cm handle' | TrustLevel.COMPLETE || [ 'ch-1' : TrustLevel.COMPLETE ]
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
index 716efd8fdb..b243a74cd9 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
@@ -35,6 +35,8 @@ import org.onap.cps.ncmp.api.inventory.models.TrustLevel
import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager
+import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher
import org.onap.cps.spi.model.ConditionProperties
import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Specification
@@ -46,10 +48,11 @@ class NetworkCmProxyInventoryFacadeSpec extends Specification {
def mockParameterizedCmHandleQueryService = Mock(ParameterizedCmHandleQueryService)
def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
def mockInventoryPersistence = Mock(InventoryPersistence)
+ def mockTrustLevelManager = Mock(TrustLevelManager)
+ def mockAlternateIdMatcher = Mock(AlternateIdMatcher)
+ def objectUnderTest = new NetworkCmProxyInventoryFacade(mockCmHandleRegistrationService, mockCmHandleQueryService, mockParameterizedCmHandleQueryService, mockInventoryPersistence, spiedJsonObjectMapper, mockTrustLevelManager, mockAlternateIdMatcher)
def trustLevelPerCmHandle = [:]
- def objectUnderTest = new NetworkCmProxyInventoryFacade(mockCmHandleRegistrationService, mockCmHandleQueryService, mockParameterizedCmHandleQueryService, mockInventoryPersistence, spiedJsonObjectMapper, trustLevelPerCmHandle)
-
def 'Update DMI Registration'() {
given: 'an (updated) dmi plugin registration'
def dmiPluginRegistration = Mock(DmiPluginRegistration)
@@ -110,7 +113,7 @@ class NetworkCmProxyInventoryFacadeSpec extends Specification {
publicProperties: publicProperties, compositeState: compositeState, moduleSetTag: moduleSetTag, alternateId: alternateId)
1 * mockInventoryPersistence.getYangModelCmHandle('ch-1') >> yangModelCmHandle
and: 'a trust level for the cm handle in the cache'
- trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+ mockTrustLevelManager.getEffectiveTrustLevel(*_) >> TrustLevel.COMPLETE
when: 'getting cm handle details for a given cm handle id from ncmp service'
def result = objectUnderTest.getNcmpServiceCmHandle('ch-1')
then: 'the result is a ncmpServiceCmHandle'
@@ -144,7 +147,7 @@ class NetworkCmProxyInventoryFacadeSpec extends Specification {
assert result == [ 'public prop' : 'some public prop' ]
}
- def 'Get cm handle composite state'() {
+ def 'Get cm handle composite state using #scenario'() {
given: 'a yang modelled cm handle'
def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED,
lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.MODULE_SYNC_FAILED).details("lock details").build(),
@@ -153,13 +156,21 @@ class NetworkCmProxyInventoryFacadeSpec extends Specification {
dataStores: dataStores())
def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')]
def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')]
- def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState)
+ def cmHandleId = 'some-cm-handle'
+ def alternateId = 'some-alternate-id'
+ def yangModelCmHandle = new YangModelCmHandle(id:cmHandleId, alternateId: alternateId, dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState)
+ and: 'we have corresponding cm handle for the cm handle reference'
+ 1 * mockAlternateIdMatcher.getCmHandleId(cmHandleRef) >> cmHandleId
and: 'the system returns this yang modelled cm handle'
- 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle
+ 1 * mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle
when: 'getting cm handle composite state for a given cm handle id from ncmp service'
- def result = objectUnderTest.getCmHandleCompositeState('some-cm-handle')
+ def result = objectUnderTest.getCmHandleCompositeState(cmHandleRef)
then: 'the result returns the correct data'
assert result == compositeState
+ where: 'following cm handle reference is used'
+ scenario | cmHandleRef
+ 'Cm Handle Reference as cm handle-id' | 'some-cm-handle'
+ 'Cm Handle Reference as alternate-id' | 'some-alternate-id'
}
def 'Execute cm handle id search'() {
@@ -203,17 +214,18 @@ class NetworkCmProxyInventoryFacadeSpec extends Specification {
and: 'query cm handle method returns two cm handles'
mockParameterizedCmHandleQueryService.queryCmHandles(
spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class))
- >> [new NcmpServiceCmHandle(cmHandleId: 'ch-0'), new NcmpServiceCmHandle(cmHandleId: 'ch-1')]
- and: ' a trust level for ch-1'
- trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+ >> [new YangModelCmHandle(id: 'ch-0', dmiProperties: [], publicProperties: []),
+ new YangModelCmHandle(id: 'ch-1', dmiProperties: [], publicProperties: [])]
+ and: 'a trust level for cm handles'
+ mockTrustLevelManager.getEffectiveTrustLevel(*_) >> TrustLevel.COMPLETE
when: 'execute cm handle search is called'
def result = objectUnderTest.executeCmHandleSearch(cmHandleQueryApiParameters)
then: 'result consists of the two cm handles returned by the CPS Data Service'
assert result.size() == 2
assert result[0].cmHandleId == 'ch-0'
assert result[1].cmHandleId == 'ch-1'
- and: 'only ch-1 has a trust level'
- assert result[0].currentTrustLevel == null
+ and: 'cm handles have trust level'
+ assert result[0].currentTrustLevel == TrustLevel.COMPLETE
assert result[1].currentTrustLevel == TrustLevel.COMPLETE
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy
index 013bace04d..08644202c6 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022-2023 Nordix Foundation
+ * Copyright (C) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ package org.onap.cps.ncmp.impl.inventory
import org.onap.cps.cpspath.parser.PathParsingException
import org.onap.cps.ncmp.api.inventory.models.CmHandleQueryServiceParameters
-import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.DataInUseException
@@ -139,10 +138,10 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification {
and: 'the inventory service is called with teh correct if and returns a yang model cm handle'
1 * mockInventoryPersistence.getYangModelCmHandles(['ch1']) >>
[new YangModelCmHandle(id: 'abc', dmiProperties: [new YangModelCmHandle.Property('name','value')], publicProperties: [])]
- and: 'the expected cm handle(s) are returned as NCMP Service cm handles'
- assert result[0] instanceof NcmpServiceCmHandle
+ and: 'the expected cm handle(s) are returned as Yang Model cm handles'
+ assert result[0] instanceof YangModelCmHandle
assert result.size() == 1
- assert result[0].dmiProperties == [name:'value']
+ assert result[0].dmiProperties.size() == 1
}
def 'Query cm handle ids when the query is empty.'() {
@@ -165,7 +164,7 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification {
def result = objectUnderTest.queryCmHandles(cmHandleQueryParameters)
then: 'the correct cm handles are returned'
assert result.size() == 4
- assert result.cmHandleId.containsAll('PNFDemo1', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4')
+ assert result.id.containsAll('PNFDemo1', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4')
}
def 'Query CMHandleId with #scenario.' () {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
index 196a1cd360..c80aa7b242 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperationsSpec.groovy
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec
import org.onap.cps.ncmp.impl.dmi.DmiProperties
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import org.onap.cps.spi.model.ModuleReference
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
index 6db304acd1..c7d0616bb2 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
@@ -49,7 +49,7 @@ class DeviceTrustLevelMessageConsumerSpec extends Specification {
when: 'the event is consumed'
objectUnderTest.deviceTrustLevelListener(consumerRecord)
then: 'cm handles are stored with correct trust level'
- 1 * mockTrustLevelManager.handleUpdateOfDeviceTrustLevel('"ch-1"', TrustLevel.COMPLETE)
+ 1 * mockTrustLevelManager.updateCmHandleTrustLevel('"ch-1"', TrustLevel.COMPLETE)
}
def createTrustLevelEvent(eventPayload) {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
index 0a34d267c5..32f4503005 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
@@ -22,8 +22,8 @@ package org.onap.cps.ncmp.impl.inventory.trustlevel
import org.onap.cps.ncmp.api.inventory.models.TrustLevel
import org.onap.cps.ncmp.impl.dmi.DmiRestClient
-import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters
import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService
+import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
import reactor.core.publisher.Mono
import spock.lang.Specification
@@ -46,7 +46,7 @@ class DmiPluginTrustLevelWatchDogSpec extends Specification {
when: 'dmi watch dog method runs'
objectUnderTest.checkDmiAvailability()
then: 'the update delegated to manager'
- numberOfCalls * mockTrustLevelManager.handleUpdateOfDmiTrustLevel('dmi-1', _, newDmiTrustLevel)
+ numberOfCalls * mockTrustLevelManager.updateDmi('dmi-1', _, newDmiTrustLevel)
where: 'the following parameters are used'
dmiHealhStatus | dmiOldTrustLevel | newDmiTrustLevel || numberOfCalls
'UP' | TrustLevel.COMPLETE | TrustLevel.COMPLETE || 0
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
index b5bfbc165c..84d93e0b7f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
@@ -20,6 +20,7 @@
package org.onap.cps.ncmp.impl.inventory.trustlevel
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration
import org.onap.cps.ncmp.api.inventory.models.TrustLevel
import org.onap.cps.ncmp.impl.inventory.InventoryPersistence
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
@@ -35,11 +36,20 @@ class TrustLevelManagerSpec extends Specification {
def mockAttributeValueChangeEventPublisher = Mock(CmAvcEventPublisher)
def objectUnderTest = new TrustLevelManager(trustLevelPerCmHandle, trustLevelPerDmiPlugin, mockInventoryPersistence, mockAttributeValueChangeEventPublisher)
+ def 'Initial dmi registration'() {
+ given: 'a dmi plugin'
+ def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'dmi-1')
+ when: 'method to register to the cache is called'
+ objectUnderTest.registerDmiPlugin(dmiPluginRegistration)
+ then: 'dmi plugin in the cache and trusted'
+ assert trustLevelPerDmiPlugin.get('dmi-1') == TrustLevel.COMPLETE
+ }
+
def 'Initial cm handle registration'() {
given: 'two cm handles: one with no trust level and one trusted'
def cmHandleModelsToBeCreated = ['ch-1': null, 'ch-2': TrustLevel.COMPLETE]
- when: 'the initial registration handled'
- objectUnderTest.handleInitialRegistrationOfTrustLevels(cmHandleModelsToBeCreated)
+ when: 'method to register to the cache is called'
+ objectUnderTest.registerCmHandles(cmHandleModelsToBeCreated)
then: 'no notification sent'
0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
and: 'both cm handles are in the cache and are trusted'
@@ -50,8 +60,8 @@ class TrustLevelManagerSpec extends Specification {
def 'Initial cm handle registration with a cm handle that is not trusted'() {
given: 'a not trusted cm handle'
def cmHandleModelsToBeCreated = ['ch-2': TrustLevel.NONE]
- when: 'the initial registration handled'
- objectUnderTest.handleInitialRegistrationOfTrustLevels(cmHandleModelsToBeCreated)
+ when: 'method to register to the cache is called'
+ objectUnderTest.registerCmHandles(cmHandleModelsToBeCreated)
then: 'notification is sent'
1 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
}
@@ -62,7 +72,7 @@ class TrustLevelManagerSpec extends Specification {
and: 'a trusted cm handle'
trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
when: 'the update is handled'
- objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.NONE)
+ objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.NONE)
then: 'notification is sent'
1 * mockAttributeValueChangeEventPublisher.publishAvcEvent('ch-1', 'trustLevel', 'COMPLETE', 'NONE')
and: 'the dmi in the cache is not trusted'
@@ -75,54 +85,87 @@ class TrustLevelManagerSpec extends Specification {
and: 'a trusted cm handle'
trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
when: 'the update is handled'
- objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
+ objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
then: 'no notification is sent'
0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
and: 'the dmi in the cache is trusted'
assert trustLevelPerDmiPlugin.get('my-dmi') == TrustLevel.COMPLETE
}
- def 'Device trust level updated'() {
+ def 'CmHandle trust level updated'() {
given: 'a non trusted cm handle'
trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
and: 'a trusted dmi plugin'
trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.COMPLETE)
and: 'inventory persistence service returns yang model cm handle'
mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(id: 'ch-1', dmiDataServiceName: 'my-dmi')
- when: 'update of device to COMPLETE trust level handled'
- objectUnderTest.handleUpdateOfDeviceTrustLevel('ch-1', TrustLevel.COMPLETE)
+ when: 'update of CmHandle to COMPLETE trust level handled'
+ objectUnderTest.updateCmHandleTrustLevel('ch-1', TrustLevel.COMPLETE)
then: 'the cm handle in the cache is trusted'
assert trustLevelPerCmHandle.get('ch-1', TrustLevel.COMPLETE)
and: 'notification is sent'
1 * mockAttributeValueChangeEventPublisher.publishAvcEvent('ch-1', 'trustLevel', 'NONE', 'COMPLETE')
}
- def 'Device trust level updated with same value'() {
+ def 'CmHandle trust level updated with same value'() {
given: 'a non trusted cm handle'
trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
and: 'a trusted dmi plugin'
trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.COMPLETE)
and: 'inventory persistence service returns yang model cm handle'
mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(id: 'ch-1', dmiDataServiceName: 'my-dmi')
- when: 'update of device trust to the same level (NONE)'
- objectUnderTest.handleUpdateOfDeviceTrustLevel('ch-1', TrustLevel.NONE)
+ when: 'update of CmHandle trust to the same level (NONE)'
+ objectUnderTest.updateCmHandleTrustLevel('ch-1', TrustLevel.NONE)
then: 'the cm handle in the cache is not trusted'
assert trustLevelPerCmHandle.get('ch-1', TrustLevel.NONE)
and: 'no notification is sent'
0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
}
- def 'Dmi trust level restored to complete with non trusted device'() {
+ def 'Dmi trust level restored to complete with non trusted CmHandle'() {
given: 'a non trusted dmi'
trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.NONE)
- and: 'a non trusted device'
+ and: 'a non trusted CmHandle'
trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
when: 'restore the dmi trust level to COMPLETE'
- objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
+ objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
then: 'the cm handle in the cache is still NONE'
assert trustLevelPerCmHandle.get('ch-1') == TrustLevel.NONE
and: 'no notification is sent'
0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
}
+ def 'Select effective trust level among CmHandle and dmi plugin'() {
+ given: 'a non trusted dmi'
+ trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.NONE)
+ and: 'a trusted CmHandle'
+ trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+ when: 'effective trust level selected'
+ def effectiveTrustLevel = objectUnderTest.getEffectiveTrustLevel('my-dmi', 'ch-1')
+ then: 'effective trust level is trusted'
+ assert effectiveTrustLevel == TrustLevel.NONE
+ }
+
+ def 'CmHandle trust level (COMPLETE) removed'() {
+ given: 'a trusted cm handle'
+ trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+ when: 'the remove is handled'
+ objectUnderTest.removeCmHandles(['ch-1'])
+ then: 'cm handle removed from the cache'
+ assert trustLevelPerCmHandle.get('ch-1') == null
+ and: 'notification is sent'
+ 1 * mockAttributeValueChangeEventPublisher.publishAvcEvent(_,'trustLevel','COMPLETE','NONE')
+ }
+
+ def 'CmHandle trust level (NONE) removed'() {
+ given: 'a non-trusted cm handle'
+ trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
+ when: 'the remove is handled'
+ objectUnderTest.removeCmHandles(['ch-1'])
+ then: 'cm handle removed from the cache'
+ assert trustLevelPerCmHandle.get('ch-1') == null
+ and: 'no notification is sent'
+ 0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
+ }
+
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfigurationSpec.groovy
new file mode 100644
index 0000000000..cf5e1a383c
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/policyexecutor/PolicyExecutorWebClientConfigurationSpec.groovy
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.impl.policyexecutor
+
+import org.onap.cps.ncmp.config.PolicyExecutorHttpClientConfig
+import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.web.reactive.function.client.WebClient
+import spock.lang.Specification
+
+@SpringBootTest
+@ContextConfiguration(classes = [PolicyExecutorHttpClientConfig])
+@EnableConfigurationProperties
+class PolicyExecutorWebClientConfigurationSpec extends Specification {
+
+ def webClientBuilder = Mock(WebClient.Builder) {
+ defaultHeaders(_) >> it
+ clientConnector(_) >> it
+ codecs(_) >> it
+ build() >> Mock(WebClient)
+ }
+
+ def httpClientConfiguration = Spy(PolicyExecutorHttpClientConfig.class)
+
+ def objectUnderTest = new PolicyExecutorWebClientConfiguration(httpClientConfiguration)
+
+ def 'Web client policy executor.'() {
+ when: 'create a web client for policy executor'
+ def result = objectUnderTest.policyExecutorWebClient(webClientBuilder)
+ then: 'a web client is created successfully'
+ assert result != null
+ assert result instanceof WebClient
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy
index 9e1b37023b..9e051156f7 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiServiceUrlTemplateBuilderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/http/RestServiceUrlTemplateBuilderSpec.groovy
@@ -18,14 +18,13 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.impl.dmi
-
+package org.onap.cps.ncmp.impl.utils.http
import spock.lang.Specification
-class DmiServiceUrlTemplateBuilderSpec extends Specification {
+class RestServiceUrlTemplateBuilderSpec extends Specification {
- def objectUnderTest = new DmiServiceUrlTemplateBuilder()
+ def objectUnderTest = new RestServiceUrlTemplateBuilder()
def 'Build URL template parameters with (variable) path segments and query parameters.'() {
given: 'the URL details are given to the builder'
@@ -35,9 +34,9 @@ class DmiServiceUrlTemplateBuilderSpec extends Specification {
objectUnderTest.queryParameter('param1', 'abc')
objectUnderTest.queryParameter('param2', 'value?with#special:characters')
when: 'the URL template parameters are created'
- def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath')
+ def result = objectUnderTest.createUrlTemplateParameters('myServer', 'myBasePath')
then: 'the URL template contains variable names instead of value and un-encoded fixed segment'
- assert result.urlTemplate == 'myDmiServer/myBasePath/v1/segment/{myVariableSegment}/segment?with:special&characters?param1={param1}&param2={param2}'
+ assert result.urlTemplate == 'myServer/myBasePath/v1/segment/{myVariableSegment}/segment?with:special&characters?param1={param1}&param2={param2}'
and: 'URL variables contains name and un-encoded value pairs'
assert result.urlVariables == ['myVariableSegment': 'someValue', 'param1': 'abc', 'param2': 'value?with#special:characters']
}
@@ -46,7 +45,7 @@ class DmiServiceUrlTemplateBuilderSpec extends Specification {
given: 'the query parameter is given to the builder'
objectUnderTest.queryParameter('my&param', 'special&characters=are?not\\encoded')
when: 'the URL template parameters are created'
- def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath')
+ def result = objectUnderTest.createUrlTemplateParameters('myServer', 'myBasePath')
then: 'Special characters are not encoded'
assert result.urlVariables == ['my&param': 'special&characters=are?not\\encoded']
}
@@ -55,7 +54,7 @@ class DmiServiceUrlTemplateBuilderSpec extends Specification {
when: 'the query parameter is given to the builder'
objectUnderTest.queryParameter('param', value)
and: 'the URL template parameters are create'
- def result = objectUnderTest.createUrlTemplateParameters('myDmiServer', 'myBasePath')
+ def result = objectUnderTest.createUrlTemplateParameters('myServer', 'myBasePath')
then: 'no parameter gets added'
assert result.urlVariables.isEmpty()
where: 'the following parameter values are used'
diff --git a/cps-ncmp-service/src/test/java/org/onap/cps/ncmp/utils/WebClientBuilderTestConfig.java b/cps-ncmp-service/src/test/java/org/onap/cps/ncmp/utils/WebClientBuilderTestConfig.java
new file mode 100644
index 0000000000..2f6b270076
--- /dev/null
+++ b/cps-ncmp-service/src/test/java/org/onap/cps/ncmp/utils/WebClientBuilderTestConfig.java
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.utils;
+
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@TestConfiguration
+public class WebClientBuilderTestConfig {
+
+ /**
+ * Configures and creates a web client builder bean to make it accessible for the Spring Boot Test Context.
+ *
+ * @return a WebClient Builder instance.
+ */
+ @Bean
+ public WebClient.Builder webClientBuilder() {
+ return WebClient.builder();
+ }
+
+}
diff --git a/cps-ncmp-service/src/test/resources/application.yml b/cps-ncmp-service/src/test/resources/application.yml
index 759de834ab..c76831da74 100644
--- a/cps-ncmp-service/src/test/resources/application.yml
+++ b/cps-ncmp-service/src/test/resources/application.yml
@@ -47,15 +47,26 @@ ncmp:
dmi:
httpclient:
data-services:
- pendingAcquireMaxCount: 22
- connectionTimeoutInSeconds: 123
- maximumInMemorySizeInMegabytes: 7
- readTimeoutInSeconds: 33
+ maximumInMemorySizeInMegabytes: 1
+ maximumConnectionsTotal: 2
+ pendingAcquireMaxCount: 3
+ connectionTimeoutInSeconds: 4
+ readTimeoutInSeconds: 5
+ writeTimeoutInSeconds: 6
model-services:
- pendingAcquireMaxCount: 44
- connectionTimeoutInSeconds: 456
- maximumInMemorySizeInMegabytes: 8
- maximumConnectionsTotal: 111
+ maximumInMemorySizeInMegabytes: 11
+ maximumConnectionsTotal: 12
+ pendingAcquireMaxCount: 13
+ connectionTimeoutInSeconds: 14
+ readTimeoutInSeconds: 15
+ writeTimeoutInSeconds: 16
+ healthCheckServices:
+ maximumInMemorySizeInMegabytes: 21
+ maximumConnectionsTotal: 22
+ pendingAcquireMaxCount: 23
+ connectionTimeoutInSeconds: 24
+ readTimeoutInSeconds: 25
+ writeTimeoutInSeconds: 26
auth:
username: some-user
password: some-password
@@ -73,8 +84,16 @@ ncmp:
policy-executor:
enabled: true
server:
- address: "http://localhost"
- port: "8785"
+ address: http://localhost
+ port: 8785
+ httpclient:
+ all-services:
+ maximumInMemorySizeInMegabytes: 31
+ maximumConnectionsTotal: 32
+ pendingAcquireMaxCount: 33
+ connectionTimeoutInSeconds: 34
+ readTimeoutInSeconds: 35
+ writeTimeoutInSeconds: 36
# Custom Hazelcast Config.
hazelcast:
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index a4aeb5b5a5..430f4b5cd8 100644
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -410,30 +410,6 @@
<artifactId>sonar-maven-plugin</artifactId>
<version>3.9.1.2184</version>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.6.0</version>
- <executions>
- <execution>
- <id>generate-csv</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <executable>${script.executor}</executable>
- <workingDirectory>${parent.directory}/cps-ri/src/main/resources/</workingDirectory>
- <arguments>
- <argument>yangResourceCsvGenerator.py</argument>
- <argument>dmi-registry@2021-12-13</argument>
- <argument>dmi-registry@2022-02-10</argument>
- <argument>dmi-registry@2022-05-10</argument>
- </arguments>
- </configuration>
- </plugin>
</plugins>
</build>
</project>
diff --git a/cps-ri/src/main/resources/changelog/db/changes/data/dmi/generated-csv/README.md b/cps-ri/src/main/resources/changelog/db/changes/data/dmi/generated-csv/README.md
deleted file mode 100644
index 212acb9006..0000000000
--- a/cps-ri/src/main/resources/changelog/db/changes/data/dmi/generated-csv/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- ============LICENSE_START=======================================================
- Copyright (C) 2022 Nordix Foundation.
- ================================================================================
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- SPDX-License-Identifier: Apache-2.0
- ============LICENSE_END=========================================================
--->
-
-##Placeholder folder for generated CSV files as part of yang models.
-
-Do not remove this folder \ No newline at end of file
diff --git a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2021-12-13.yang b/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2021-12-13.yang
deleted file mode 100644
index ed3559bf61..0000000000
--- a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2021-12-13.yang
+++ /dev/null
@@ -1,63 +0,0 @@
-module dmi-registry {
-
- yang-version 1.1;
-
- namespace "org:onap:cps:ncmp";
-
- prefix dmi-reg;
-
- contact "dylan.byrne@est.tech";
-
- revision "2021-05-20" {
- description
- "Initial Version";
- }
-
- revision "2021-10-20" {
- description
- "Added dmi-data-service-name & dmi-model-service-name to allow separate DMI instances for each responsibility";
- }
-
- revision "2021-12-13" {
- description
- "Added new list of public additonal properties for a Cm-Handle which are exposed to clients of the NCMP interface";
- }
-
- container dmi-registry {
- list cm-handles {
- key "id";
- leaf id {
- type string;
- }
- leaf dmi-service-name {
- type string;
- }
- leaf dmi-data-service-name {
- type string;
- }
- leaf dmi-model-service-name {
- type string;
- }
-
- list additional-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
-
- list public-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-02-10.yang b/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-02-10.yang
deleted file mode 100644
index 3c6d990c5d..0000000000
--- a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-02-10.yang
+++ /dev/null
@@ -1,81 +0,0 @@
-module dmi-registry {
-
- yang-version 1.1;
-
- namespace "org:onap:cps:ncmp";
-
- prefix dmi-reg;
-
- contact "toine.siebelink@est.tech";
-
- revision "2022-02-10" {
- description
- "Added State, LockReason, LockReasonDetails to aid with cmHandle sync and timestamp to aid with retry/timeout scenarios";
- }
-
- revision "2021-12-13" {
- description
- "Added new list of public additional properties for a Cm-Handle which are exposed to clients of the NCMP interface";
- }
-
- revision "2021-10-20" {
- description
- "Added dmi-data-service-name & dmi-model-service-name to allow separate DMI instances for each responsibility";
- }
-
- revision "2021-05-20" {
- description
- "Initial Version";
- }
-
- container dmi-registry {
- list cm-handles {
- key "id";
- leaf id {
- type string;
- }
- leaf dmi-service-name {
- type string;
- }
- leaf dmi-data-service-name {
- type string;
- }
- leaf dmi-model-service-name {
- type string;
- }
-
- list additional-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
-
- list public-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
-
- leaf state {
- type string;
- }
- leaf lock-reason {
- type string;
- }
- leaf lock-reason-details {
- type string;
- }
- leaf last-update-time {
- type string;
- }
- }
- }
-}
diff --git a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-05-10.yang b/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-05-10.yang
deleted file mode 100644
index 77517968c6..0000000000
--- a/cps-ri/src/main/resources/changelog/db/changes/data/yang-models/dmi-registry@2022-05-10.yang
+++ /dev/null
@@ -1,123 +0,0 @@
-module dmi-registry {
-
- yang-version 1.1;
-
- namespace "org:onap:cps:ncmp";
-
- prefix dmi-reg;
-
- contact "toine.siebelink@est.tech";
-
- revision "2022-05-10" {
- description
- "Added DataSyncEnabled, SyncState with State, LastSyncTime, DataStoreSyncState with Operational and Running syncstate";
- }
-
- revision "2022-02-10" {
- description
- "Added State, LockReason, LockReasonDetails to aid with cmHandle sync and timestamp to aid with retry/timeout scenarios";
- }
-
- revision "2021-12-13" {
- description
- "Added new list of public additional properties for a Cm-Handle which are exposed to clients of the NCMP interface";
- }
-
- revision "2021-10-20" {
- description
- "Added dmi-data-service-name & dmi-model-service-name to allow separate DMI instances for each responsibility";
- }
-
- revision "2021-05-20" {
- description
- "Initial Version";
- }
-
- grouping LockReason {
- leaf reason {
- type string;
- }
- leaf details {
- type string;
- }
- }
-
- grouping SyncState {
- leaf sync-state {
- type string;
- }
- leaf last-sync-time {
- type string;
- }
- }
-
- grouping Datastores {
- container operational {
- uses SyncState;
- }
- container running {
- uses SyncState;
- }
- }
-
- container dmi-registry {
- list cm-handles {
- key "id";
- leaf id {
- type string;
- }
- leaf dmi-service-name {
- type string;
- }
- leaf dmi-data-service-name {
- type string;
- }
- leaf dmi-model-service-name {
- type string;
- }
-
- list additional-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
-
- list public-properties {
- key "name";
- leaf name {
- type string;
- }
- leaf value {
- type string;
- }
- }
-
- container state {
- leaf cm-handle-state {
- type string;
- }
-
- container lock-reason {
- uses LockReason;
- }
-
- leaf last-update-time {
- type string;
- }
-
- leaf data-sync-enabled {
- type boolean;
- default "false";
- }
-
- container datastores {
- uses Datastores;
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/cps-ri/src/main/resources/yangResourceCsvGenerator.py b/cps-ri/src/main/resources/yangResourceCsvGenerator.py
deleted file mode 100644
index 3a076d4378..0000000000
--- a/cps-ri/src/main/resources/yangResourceCsvGenerator.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (C) 2022 Nordix Foundation
-# ================================================================================
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# SPDX-License-Identifier: Apache-2.0
-# ============LICENSE_END=========================================================
-
-
-import csv
-import datetime
-import hashlib
-import sys
-import re
-
-yang_source = ''
-checksum = ''
-regexForModuleName = '(?<=module)(.*)(?={)'
-regexForRevision = '(?<=revision)(.*)(?={)'
-
-def main():
- for yang_source in sys.argv[1:]:
- checksum = hashlib.sha256(str(yang_source).encode()).hexdigest()
-
- with open('changelog/db/changes/data/yang-models/' + yang_source + '.yang', 'r') as content:
- dmiRegistry = content.read()
-
- try:
- latestRevision = re.search(regexForRevision, dmiRegistry).group(0).replace('\"','').strip()
- except:
- print("ERROR IN in yangResourceCsvGenerator.py: Unable to find revision for " + yang_source + '.yang')
-
- try:
- module_name = re.search(regexForModuleName, dmiRegistry).group(0).strip()
- except:
- print("ERROR IN in yangResourceCsvGenerator.py: Unable to find module name for " + yang_source + '.yang')
-
- #If true, file was created after module_name and revision columns were added to yang-resources table
- writeWithModuleNameAndRevision = yang_source != 'dmi-registry@2021-12-13'
-
- try:
- # open the file in the write mode
- with open('changelog/db/changes/data/dmi/generated-csv/generated_yang_resource_' + yang_source + '.csv', 'w', newline='') \
- as file:
- writer = csv.writer(file, delimiter='|')
- if(writeWithModuleNameAndRevision):
- writer.writerow(["name", "content", "checksum", "module_name", "revision"])
- writer.writerow([yang_source + '.yang', dmiRegistry, checksum, module_name, latestRevision])
- else:
- writer.writerow(["name", "content", "checksum"])
- writer.writerow([yang_source + '.yang', dmiRegistry, checksum])
- except:
- print("ERROR IN in yangResourceCsvGenerator.py: Unable to write to changelog/db/changes/data/dmi/generated-csv/generated_yang_resource_" + yang_source + ".csv")
-
-
-main() \ No newline at end of file
diff --git a/csit/install-deps.sh b/csit/install-deps.sh
new file mode 100755
index 0000000000..ef0b96a799
--- /dev/null
+++ b/csit/install-deps.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Copyright 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.
+#
+
+echo "---> install-deps.sh"
+echo "Installing dependencies"
+
+# Create directory for downloaded binaries.
+mkdir -p bin
+touch bin/.gitignore
+
+# Add it to the PATH, so downloaded versions will be used.
+export PATH="$(pwd)/bin:$PATH"
+
+# Download docker-compose.
+if [ ! -x bin/docker-compose ]; then
+ echo " Downloading docker-compose"
+ curl -s -L https://github.com/docker/compose/releases/download/v2.29.2/docker-compose-linux-x86_64 > bin/docker-compose
+ chmod +x bin/docker-compose
+else
+ echo " docker-compose already installed"
+fi
+docker-compose version
diff --git a/csit/plans/cps/setup.sh b/csit/plans/cps/setup.sh
index 80829eba14..036f14b82f 100755
--- a/csit/plans/cps/setup.sh
+++ b/csit/plans/cps/setup.sh
@@ -1,7 +1,6 @@
#!/bin/bash
#
# Copyright 2016-2017 Huawei Technologies Co., Ltd.
-# Modifications Copyright (C) 2022 Nordix Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,7 +18,7 @@
# Modifications copyright (c) 2020-2021 Samsung Electronics Co., Ltd.
# Modifications Copyright (C) 2021 Pantheon.tech
# Modifications Copyright (C) 2021 Bell Canada.
-# Modifications Copyright (C) 2021 Nordix Foundation.
+# Modifications Copyright (C) 2021-2024 Nordix Foundation.
#
# Branched from ccsdk/distribution to this repository Feb 23, 2021
#
@@ -59,10 +58,6 @@ export $(cut -d= -f1 $WORKSPACE/plans/cps/test.properties)
###################### setup cps-ncmp ############################
cd $CPS_HOME/docker-compose
-curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > docker-compose
-chmod +x docker-compose
-docker-compose version
-
# start CPS/NCMP, DMI Plugin, and PostgreSQL containers with docker compose
docker-compose --profile dmi-service up -d
@@ -82,4 +77,4 @@ check_health $DMI_HOST:$DMI_PORT 'dmi-plugin'
###################### ROBOT Configurations ##########################
# Pass variables required for Robot test suites in ROBOT_VARIABLES
-ROBOT_VARIABLES="-v CPS_CORE_HOST:$CPS_CORE_HOST -v CPS_CORE_PORT:$CPS_CORE_PORT -v DMI_HOST:$LOCAL_IP -v DMI_PORT:$DMI_PORT -v DMI_CSIT_STUB_HOST:$LOCAL_IP -v DMI_CSIT_STUB_PORT:$DMI_DEMO_STUB_PORT -v DMI_AUTH_ENABLED:$DMI_AUTH_ENABLED -v DATADIR_CPS_CORE:$WORKSPACE/data/cps-core -v DATADIR_NCMP:$WORKSPACE/data/ncmp -v DATADIR_SUBS_NOTIFICATION:$WORKSPACE/data/subscription-notification --exitonfailure" \ No newline at end of file
+ROBOT_VARIABLES="-v CPS_CORE_HOST:$CPS_CORE_HOST -v CPS_CORE_PORT:$CPS_CORE_PORT -v DMI_HOST:$LOCAL_IP -v DMI_PORT:$DMI_PORT -v DMI_CSIT_STUB_HOST:$LOCAL_IP -v DMI_CSIT_STUB_PORT:$DMI_DEMO_STUB_PORT -v DMI_AUTH_ENABLED:$DMI_AUTH_ENABLED -v DATADIR_CPS_CORE:$WORKSPACE/data/cps-core -v DATADIR_NCMP:$WORKSPACE/data/ncmp -v DATADIR_SUBS_NOTIFICATION:$WORKSPACE/data/subscription-notification --exitonfailure"
diff --git a/csit/run-project-csit.sh b/csit/run-project-csit.sh
index fcb3c925c1..f362cc7130 100755
--- a/csit/run-project-csit.sh
+++ b/csit/run-project-csit.sh
@@ -2,6 +2,7 @@
#
# Copyright 2020-2021 © Samsung Electronics Co., Ltd.
# Modifications Copyright (C) 2021 Pantheon.tech
+# Modifications 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.
@@ -28,6 +29,8 @@ rm -rf ${WORKSPACE}/archives
mkdir -p ${WORKSPACE}/archives
cd ${WORKSPACE}
+source install-deps.sh
+
# Execute all test-suites defined under plans subdirectory
for dir in plans/*/
do
diff --git a/csit/tests/cps-trust-level/cps-trust-level.robot b/csit/tests/cps-trust-level/cps-trust-level.robot
index e4deeff32b..4db0115871 100644
--- a/csit/tests/cps-trust-level/cps-trust-level.robot
+++ b/csit/tests/cps-trust-level/cps-trust-level.robot
@@ -36,7 +36,7 @@ ${ncmpBasePath} /ncmp/v1
${dmiUrl} http://${DMI_HOST}:${DMI_PORT}
${jsonCreateCmHandles} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"trustLevel":"COMPLETE","cmHandle":"CH-1"},{"trustLevel":"COMPLETE","cmHandle":"CH-2"},{"cmHandle":"CH-3"},{"trustLevel":"NONE","cmHandle":"CH-4"}]}
${jsonTrustLevelPropertyQueryParameters} {"cmHandleQueryParameters": [{"conditionName": "cmHandleWithTrustLevel", "conditionParameters": [ {"trustLevel": "COMPLETE"} ] }]}
-${jsonTrustLevelQueryResponse} {"data":{"attributeValueChange":[{"attributeName":"trustLevel","newAttributeValue":"NONE"}]}}
+${jsonTrustLevelEventPayload} {"data":{"attributeValueChange":[{"attributeName":"trustLevel","oldAttributeValue":"COMPLETE","newAttributeValue":"NONE"}]}}
*** Test Cases ***
Register data node
@@ -55,9 +55,9 @@ Verify notification
Compare Header Values ${header_key_value_pair[0]} ${header_key_value_pair[1]} "ce_specversion" "1.0"
Compare Header Values ${header_key_value_pair[0]} ${header_key_value_pair[1]} "ce_source" "NCMP"
Compare Header Values ${header_key_value_pair[0]} ${header_key_value_pair[1]} "ce_type" "org.onap.cps.ncmp.events.avc.ncmp_to_client.AvcEvent"
- Compare Header Values ${header_key_value_pair[0]} ${header_key_value_pair[1]} "ce_correlationid" "CH-4"
+ Compare Header Values ${header_key_value_pair[0]} ${header_key_value_pair[1]} "ce_correlationid" "CmHandleForDelete"
END
- Should Be Equal As Strings ${payload} ${jsonTrustLevelQueryResponse}
+ Should Be Equal As Strings ${payload} ${jsonTrustLevelEventPayload}
[Teardown] Basic Teardown ${group_id}
Retrieve CM Handle ids where query parameters Match (trust level query)
diff --git a/docs/schemas/policy-executor/ncmp-create-schema-1.0.0.json b/docs/schemas/policy-executor/ncmp-create-schema-1.0.0.json
index 2ec9daf949..4d98bc8632 100644
--- a/docs/schemas/policy-executor/ncmp-create-schema-1.0.0.json
+++ b/docs/schemas/policy-executor/ncmp-create-schema-1.0.0.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
- "$id": "urn:cps:org.onap.cps.ncmp.policy-executor:ncmp-create-schema:1.0.0",
+ "$id": "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-create-schema:1.0.0",
"$ref": "#/definitions/NcmpCreate",
"definitions": {
"NcmpCreate": {
diff --git a/docs/schemas/policy-executor/ncmp-delete-schema-1.0.0.json b/docs/schemas/policy-executor/ncmp-delete-schema-1.0.0.json
index 5df0325e39..1246d9d815 100644
--- a/docs/schemas/policy-executor/ncmp-delete-schema-1.0.0.json
+++ b/docs/schemas/policy-executor/ncmp-delete-schema-1.0.0.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
- "$id": "urn:cps:org.onap.cps.ncmp.policy-executor:ncmp-delete-schema:1.0.0",
+ "$id": "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-delete-schema:1.0.0",
"$ref": "#/definitions/NcmpDelete",
"definitions": {
"NcmpDelete": {
diff --git a/docs/schemas/policy-executor/ncmp-patch-schema-1.0.0.json b/docs/schemas/policy-executor/ncmp-patch-schema-1.0.0.json
index e26c244c94..4917aea146 100644
--- a/docs/schemas/policy-executor/ncmp-patch-schema-1.0.0.json
+++ b/docs/schemas/policy-executor/ncmp-patch-schema-1.0.0.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
- "$id": "urn:cps:org.onap.cps.ncmp.policy-executor:ncmp-patch-schema:1.0.0",
+ "$id": "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-patch-schema:1.0.0",
"$ref": "#/definitions/NcmpPatch",
"definitions": {
"NcmpPatch": {
diff --git a/docs/schemas/policy-executor/ncmp-update-schema-1.0.0.json b/docs/schemas/policy-executor/ncmp-update-schema-1.0.0.json
index 0a497e38c5..831526cd52 100644
--- a/docs/schemas/policy-executor/ncmp-update-schema-1.0.0.json
+++ b/docs/schemas/policy-executor/ncmp-update-schema-1.0.0.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
- "$id": "urn:cps:org.onap.cps.ncmp.policy-executor:ncmp-update-schema:1.0.0",
+ "$id": "urn:cps:org.onap.cps.ncmp.policy-executor.ncmp-update-schema:1.0.0",
"$ref": "#/definitions/NcmpUpdate",
"definitions": {
"NcmpUpdate": {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
index 5e46e95a0c..bd53c4ea13 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
@@ -46,6 +46,7 @@ import org.onap.cps.spi.utils.SessionManager
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
@@ -125,12 +126,19 @@ abstract class CpsIntegrationSpecBase extends Specification {
@Autowired
AlternateIdMatcher alternateIdMatcher
+
+ @Value('${ncmp.policy-executor.server.port:8080}')
+ private String policyServerPort;
+
MockWebServer mockDmiServer1 = new MockWebServer()
MockWebServer mockDmiServer2 = new MockWebServer()
+ MockWebServer mockPolicyServer = new MockWebServer()
DmiDispatcher dmiDispatcher1 = new DmiDispatcher()
DmiDispatcher dmiDispatcher2 = new DmiDispatcher()
+ PolicyDispatcher policyDispatcher = new PolicyDispatcher();
+
def DMI1_URL = null
def DMI2_URL = null
@@ -155,13 +163,18 @@ abstract class CpsIntegrationSpecBase extends Specification {
mockDmiServer2.setDispatcher(dmiDispatcher2)
mockDmiServer2.start()
+ mockPolicyServer.setDispatcher(policyDispatcher)
+ mockPolicyServer.start(Integer.valueOf(policyServerPort))
+
DMI1_URL = String.format("http://%s:%s", mockDmiServer1.getHostName(), mockDmiServer1.getPort())
DMI2_URL = String.format("http://%s:%s", mockDmiServer2.getHostName(), mockDmiServer2.getPort())
+
}
def cleanup() {
mockDmiServer1.shutdown()
mockDmiServer2.shutdown()
+ mockPolicyServer.shutdown()
}
def static readResourceDataFile(filename) {
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
index fcc23db782..35a7b6a7c2 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/DmiDispatcher.groovy
@@ -20,18 +20,18 @@
package org.onap.cps.integration.base
-import static org.onap.cps.integration.base.CpsIntegrationSpecBase.readResourceDataFile
-
import groovy.json.JsonSlurper
-import java.util.regex.Matcher
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
-import org.onap.cps.ncmp.api.datajobs.models.SubJobWriteRequest
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
+import java.util.regex.Matcher
+
+import static org.onap.cps.integration.base.CpsIntegrationSpecBase.readResourceDataFile
+
/**
* This class simulates responses from the DMI server in NCMP integration tests.
*
@@ -117,32 +117,32 @@ class DmiDispatcher extends Dispatcher {
return mockResponseWithBody(HttpStatus.OK, response)
}
- private getModuleReferencesResponse(cmHandleId) {
+ def getModuleReferencesResponse(cmHandleId) {
def moduleReferences = '{"schemas":[' + getModuleNamesForCmHandle(cmHandleId).collect {
MODULE_REFERENCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
}.join(',') + ']}'
return mockResponseWithBody(HttpStatus.OK, moduleReferences)
}
- private getModuleResourcesResponse(cmHandleId) {
+ def getModuleResourcesResponse(cmHandleId) {
def moduleResources = '[' + getModuleNamesForCmHandle(cmHandleId).collect {
MODULE_RESOURCES_RESPONSE_TEMPLATE.replaceAll("<MODULE_NAME>", it)
}.join(',') + ']'
return mockResponseWithBody(HttpStatus.OK, moduleResources)
}
- private getModuleNamesForCmHandle(cmHandleId) {
+ def getModuleNamesForCmHandle(cmHandleId) {
if (!moduleNamesPerCmHandleId.containsKey(cmHandleId)) {
throw new IllegalArgumentException('Mock DMI has no modules configured for ' + cmHandleId)
}
return moduleNamesPerCmHandleId.get(cmHandleId)
}
- private static mockResponse(status) {
+ def static mockResponse(status) {
return new MockResponse().setResponseCode(status.value())
}
- private static mockResponseWithBody(status, responseBody) {
+ def static mockResponseWithBody(status, responseBody) {
return new MockResponse()
.setResponseCode(status.value())
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/base/PolicyDispatcher.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/base/PolicyDispatcher.groovy
new file mode 100644
index 0000000000..27e7563e61
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/base/PolicyDispatcher.groovy
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration.base
+
+
+import okhttp3.mockwebserver.Dispatcher
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.RecordedRequest
+import org.springframework.http.HttpHeaders
+import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
+import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper
+
+/**
+ * This class simulates responses from the Policy Execution server in NCMP integration tests.
+ */
+class PolicyDispatcher extends Dispatcher {
+
+ def objectMapper = new ObjectMapper()
+ def expectedAuthorizationToken = 'ABC'
+ def allowAll = true; // Prevents legacy test being affected
+
+ @Override
+ MockResponse dispatch(RecordedRequest recordedRequest) {
+
+ if (!allowAll && !recordedRequest.getHeader('Authorization').contains(expectedAuthorizationToken)) {
+ return new MockResponse().setResponseCode(401)
+ }
+
+ if (recordedRequest.path != '/v1/execute') {
+ return new MockResponse().setResponseCode(400)
+ }
+
+ def body = objectMapper.readValue(recordedRequest.getBody().readUtf8(), Map.class)
+ def targetIdentifier = body.get('requests').get(0).get('data').get('targetIdentifier')
+ def responseAsMap = [:]
+ responseAsMap.put('decisionId',1)
+ if (allowAll || targetIdentifier == 'fdn1') {
+ responseAsMap.put('decision','allow')
+ responseAsMap.put('message','')
+ } else {
+ responseAsMap.put('decision','deny')
+ responseAsMap.put('message','I only like fdn1')
+ }
+ def responseAsString = objectMapper.writeValueAsString(responseAsMap)
+
+ return mockResponseWithBody(HttpStatus.OK, responseAsString)
+ }
+
+ static mockResponseWithBody(status, responseBody) {
+ return new MockResponse()
+ .setResponseCode(status.value())
+ .addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+ .setBody(responseBody)
+ }
+}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobResultServiceSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobResultServiceSpec.groovy
index 241d31a642..4d04eeeb81 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobResultServiceSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/DataJobResultServiceSpec.groovy
@@ -39,7 +39,6 @@ class DataJobResultServiceSpec extends CpsIntegrationSpecBase {
when: 'the data job status checked'
def result = dataJobResultService.getDataJobResult(authorization, dmiServiceName, dataProducerId, dataProducerJobId, destination)
then: 'the status is that defined in the mock service.'
- assert result != null
assert result == '{ "result": "some result"}'
}
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/PolicyExecutorIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/PolicyExecutorIntegrationSpec.groovy
new file mode 100644
index 0000000000..99f245ae8c
--- /dev/null
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/PolicyExecutorIntegrationSpec.groovy
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.integration.functional.ncmp
+
+import org.onap.cps.integration.base.CpsIntegrationSpecBase
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+
+import static org.springframework.http.HttpMethod.POST
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request
+
+class PolicyExecutorIntegrationSpec extends CpsIntegrationSpecBase {
+
+ def setup() {
+ // Enable mocked policy executor logic
+ policyDispatcher.allowAll = false;
+ //minimum setup for 2 cm handles with alternate ids
+ dmiDispatcher1.moduleNamesPerCmHandleId = ['ch-1': [], 'ch-2': []]
+ registerCmHandle(DMI1_URL, 'ch-1', NO_MODULE_SET_TAG, 'fdn1')
+ registerCmHandle(DMI1_URL, 'ch-2', NO_MODULE_SET_TAG, 'fdn2')
+ }
+
+ def cleanup() {
+ deregisterCmHandle(DMI1_URL, 'ch-1')
+ deregisterCmHandle(DMI1_URL, 'ch-2')
+ }
+
+ def 'Policy Executor create request with #scenario.'() {
+ when: 'a pass-through write request is sent to NCMP'
+ def response = mvc.perform(request(POST, "/ncmp/v1/ch/$cmHandle/data/ds/ncmp-datastore:passthrough-running")
+ .queryParam('resourceIdentifier', 'my-resource-id')
+ .contentType(MediaType.APPLICATION_JSON)
+ .content('{ "some-json": "data" }')
+ .header(HttpHeaders.AUTHORIZATION, authorization))
+ .andReturn().response
+ then: 'the expected status code is returned'
+ response.getStatus() == execpectedStatusCode
+ where: 'following parameters are used'
+ scenario | cmHandle | authorization || execpectedStatusCode
+ 'accepted cm handle' | 'ch-1' | 'mock expects "ABC"' || 201
+ 'un-accepted cm handle' | 'ch-2' | 'mock expects "ABC"' || 409
+ 'invalid authorization' | 'ch-1' | 'something else' || 500
+ }
+
+}
diff --git a/integration-test/src/test/resources/application.yml b/integration-test/src/test/resources/application.yml
index fefae345e6..760dad01af 100644
--- a/integration-test/src/test/resources/application.yml
+++ b/integration-test/src/test/resources/application.yml
@@ -213,6 +213,20 @@ ncmp:
init:
mode: ALWAYS
+ policy-executor:
+ enabled: true
+ server:
+ address: http://localhost
+ port: 8790
+ httpclient:
+ all-services:
+ maximumInMemorySizeInMegabytes: 1
+ maximumConnectionsTotal: 10
+ pendingAcquireMaxCount: 10
+ connectionTimeoutInSeconds: 30
+ readTimeoutInSeconds: 30
+ writeTimeoutInSeconds: 30
+
hazelcast:
cluster-name: cps-and-ncmp-test-caches
mode:
diff --git a/k6-tests/install-deps.sh b/k6-tests/install-deps.sh
new file mode 100755
index 0000000000..bb5deb93dd
--- /dev/null
+++ b/k6-tests/install-deps.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Copyright 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.
+#
+
+echo "---> install-deps.sh"
+echo "Installing dependencies"
+
+# Create directory for downloaded binaries.
+mkdir -p bin
+touch bin/.gitignore
+
+# Add it to the PATH, so downloaded versions will be used.
+export PATH="$(pwd)/bin:$PATH"
+
+# Download docker-compose.
+if [ ! -x bin/docker-compose ]; then
+ echo " Downloading docker-compose"
+ curl -s -L https://github.com/docker/compose/releases/download/v2.29.2/docker-compose-linux-x86_64 > bin/docker-compose
+ chmod +x bin/docker-compose
+else
+ echo " docker-compose already installed"
+fi
+docker-compose version
+
+# Download k6 with kafka extension.
+if [ ! -x bin/k6 ]; then
+ echo " Downloading k6 with kafka extension"
+ curl -s -L https://github.com/mostafa/xk6-kafka/releases/download/v0.26.0/xk6-kafka_v0.26.0_linux_amd64.tar.gz | tar -xz
+ mv dist/xk6-kafka_v0.26.0_linux_amd64 bin/k6 && rmdir dist
+ chmod +x bin/k6
+else
+ echo " k6 already installed"
+fi
+k6 --version
diff --git a/k6-tests/ncmp/common/cmhandle-crud.js b/k6-tests/ncmp/common/cmhandle-crud.js
index 88ecdb45b8..8f53c9b9be 100644
--- a/k6-tests/ncmp/common/cmhandle-crud.js
+++ b/k6-tests/ncmp/common/cmhandle-crud.js
@@ -19,28 +19,14 @@
*/
import http from 'k6/http';
-import { check, sleep } from 'k6';
-import { NCMP_BASE_URL, DMI_PLUGIN_URL, TOTAL_CM_HANDLES, MODULE_SET_TAGS, REGISTRATION_BATCH_SIZE, CONTENT_TYPE_JSON_PARAM, makeBatchOfCmHandleIds } from './utils.js';
+import { sleep } from 'k6';
+import {
+ NCMP_BASE_URL, DMI_PLUGIN_URL, TOTAL_CM_HANDLES,
+ MODULE_SET_TAGS, CONTENT_TYPE_JSON_PARAM
+} from './utils.js';
import { executeCmHandleIdSearch } from './search-base.js';
-export function registerAllCmHandles() {
- forEachBatchOfCmHandles(createCmHandles);
- waitForAllCmHandlesToBeReady();
-}
-
-export function deregisterAllCmHandles() {
- forEachBatchOfCmHandles(deleteCmHandles);
-}
-
-function forEachBatchOfCmHandles(functionToExecute) {
- const TOTAL_BATCHES = Math.ceil(TOTAL_CM_HANDLES / REGISTRATION_BATCH_SIZE);
- for (let batchNumber = 0; batchNumber < TOTAL_BATCHES; batchNumber++) {
- const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(REGISTRATION_BATCH_SIZE, batchNumber);
- functionToExecute(nextBatchOfCmHandleIds);
- }
-}
-
-function createCmHandles(cmHandleIds) {
+export function createCmHandles(cmHandleIds) {
const url = `${NCMP_BASE_URL}/ncmpInventory/v1/ch`;
const payload = {
"dmiPlugin": DMI_PLUGIN_URL,
@@ -57,22 +43,20 @@ function createCmHandles(cmHandleIds) {
})),
};
const response = http.post(url, JSON.stringify(payload), CONTENT_TYPE_JSON_PARAM);
- check(response, { 'create CM-handles status equals 200': (r) => r.status === 200 });
return response;
}
-function deleteCmHandles(cmHandleIds) {
+export function deleteCmHandles(cmHandleIds) {
const url = `${NCMP_BASE_URL}/ncmpInventory/v1/ch`;
const payload = {
"dmiPlugin": DMI_PLUGIN_URL,
"removedCmHandles": cmHandleIds,
};
const response = http.post(url, JSON.stringify(payload), CONTENT_TYPE_JSON_PARAM);
- check(response, { 'delete CM-handles status equals 200': (r) => r.status === 200 });
return response;
}
-function waitForAllCmHandlesToBeReady() {
+export function waitForAllCmHandlesToBeReady() {
const POLLING_INTERVAL_SECONDS = 5;
let cmHandlesReady = 0;
do {
@@ -86,4 +70,4 @@ function getNumberOfReadyCmHandles() {
const response = executeCmHandleIdSearch('readyCmHandles');
const arrayOfCmHandleIds = JSON.parse(response.body);
return arrayOfCmHandleIds.length;
-}
+} \ No newline at end of file
diff --git a/k6-tests/ncmp/common/search-base.js b/k6-tests/ncmp/common/search-base.js
index bc964856af..a7d0c925c4 100644
--- a/k6-tests/ncmp/common/search-base.js
+++ b/k6-tests/ncmp/common/search-base.js
@@ -26,7 +26,7 @@ const SEARCH_PARAMETERS_PER_SCENARIO = {
'cmHandleQueryParameters': [
{
'conditionName': 'hasAllModules',
- 'conditionParameters': [{'moduleName': 'ietf-yang-types-1'}]
+ 'conditionParameters': [{'moduleName': 'ietf-yang-types'}]
}
]
},
diff --git a/k6-tests/ncmp/common/utils.js b/k6-tests/ncmp/common/utils.js
index 294789f940..43036b1789 100644
--- a/k6-tests/ncmp/common/utils.js
+++ b/k6-tests/ncmp/common/utils.js
@@ -30,13 +30,6 @@ export const TOPIC_DATA_OPERATIONS_BATCH_READ = 'topic-data-operations-batch-rea
export const KAFKA_BOOTSTRAP_SERVERS = ['localhost:9092'];
export const MODULE_SET_TAGS = ['tagA','tagB','tagC',' tagD']
-export function recordTimeInSeconds(functionToExecute) {
- const startTimeInMillis = Date.now();
- functionToExecute();
- const endTimeInMillis = Date.now();
- const totalTimeInSeconds = (endTimeInMillis - startTimeInMillis) / 1000.0;
- return totalTimeInSeconds;
-}
/**
* Generates a batch of CM-handle IDs based on batch size and number.
@@ -63,12 +56,20 @@ export function makeCustomSummaryReport(data, options) {
'#,Test Name,Unit,Limit,Actual',
makeSummaryCsvLine('1', 'Registration of CM-handles', 'CM-handles/second', 'cmhandles_created_per_second', data, options),
makeSummaryCsvLine('2', 'De-registration of CM-handles', 'CM-handles/second', 'cmhandles_deleted_per_second', data, options),
- makeSummaryCsvLine('3', 'CM-handle ID search with Module filter', 'milliseconds', 'http_req_duration{scenario:id_search_module}', data, options),
- makeSummaryCsvLine('4', 'CM-handle search with Module filter', 'milliseconds', 'http_req_duration{scenario:cm_search_module}', data, options),
+ makeSummaryCsvLine('3', 'CM-handle ID search with Module filter', 'milliseconds', 'id_search_duration', data, options),
+ makeSummaryCsvLine('4', 'CM-handle search with Module filter', 'milliseconds', 'cm_search_duration', data, options),
makeSummaryCsvLine('5a', 'NCMP overhead for Synchronous single CM-handle pass-through read', 'milliseconds', 'ncmp_overhead_passthrough_read', data, options),
makeSummaryCsvLine('5b', 'NCMP overhead for Synchronous single CM-handle pass-through read with alternate id', 'milliseconds', 'ncmp_overhead_passthrough_read_alt_id', data, options),
makeSummaryCsvLine('6', 'NCMP overhead for Synchronous single CM-handle pass-through write', 'milliseconds', 'ncmp_overhead_passthrough_write', data, options),
makeSummaryCsvLine('7', 'Data operations batch read', 'events/second', 'data_operations_batch_read_cmhandles_per_second', data, options),
+ makeSummaryCsvLine('1x', 'Failures of Registration of CM-handles', 'number of failed requests', 'http_req_failed{group:::setup}', data, options),
+ makeSummaryCsvLine('2x', 'Failures of De-registration of CM-handles', 'number of failed requests', 'http_req_failed{group:::teardown}', data, options),
+ makeSummaryCsvLine('3x', 'Failures of CM-handle ID search with Module filter', 'number of failed requests', 'http_req_failed{scenario:id_search_module}', data, options),
+ makeSummaryCsvLine('4x', 'Failures of CM-handle search with Module filter', 'number of failed requests', 'http_req_failed{scenario:cm_search_module}', data, options),
+ makeSummaryCsvLine('5x', 'Failures of Synchronous single CM-handle pass-through read', 'number of failed requests', 'http_req_failed{scenario:passthrough_read}', data, options),
+ makeSummaryCsvLine('6x', 'Failures of Synchronous single CM-handle pass-through write', 'number of failed requests', 'http_req_failed{scenario:passthrough_write}', data, options),
+ makeSummaryCsvLine('7ax', 'Failures of Data operations batch read', 'number of failed requests', 'http_req_failed{scenario:data_operation_send_async_http_request}', data, options),
+ makeSummaryCsvLine('7bx', 'Failures of Data operations batch read consume kafka responses', 'number of failed requests', 'kafka_reader_error_count{scenario:data_operation_consume_kafka_responses}', data, options),
];
return summaryCsvLines.join('\n') + '\n';
}
diff --git a/k6-tests/ncmp/ncmp-kpi.js b/k6-tests/ncmp/ncmp-kpi.js
index f4a44dba68..16c6f7d2b1 100644
--- a/k6-tests/ncmp/ncmp-kpi.js
+++ b/k6-tests/ncmp/ncmp-kpi.js
@@ -19,23 +19,29 @@
*/
import { check } from 'k6';
-import { Gauge, Trend } from 'k6/metrics';
+import { Trend } from 'k6/metrics';
import { Reader } from 'k6/x/kafka';
import {
TOTAL_CM_HANDLES, READ_DATA_FOR_CM_HANDLE_DELAY_MS, WRITE_DATA_FOR_CM_HANDLE_DELAY_MS,
- makeCustomSummaryReport, recordTimeInSeconds, makeBatchOfCmHandleIds, DATA_OPERATION_READ_BATCH_SIZE,
- TOPIC_DATA_OPERATIONS_BATCH_READ, KAFKA_BOOTSTRAP_SERVERS
+ makeCustomSummaryReport, makeBatchOfCmHandleIds, DATA_OPERATION_READ_BATCH_SIZE,
+ TOPIC_DATA_OPERATIONS_BATCH_READ, KAFKA_BOOTSTRAP_SERVERS, REGISTRATION_BATCH_SIZE
} from './common/utils.js';
-import { registerAllCmHandles, deregisterAllCmHandles } from './common/cmhandle-crud.js';
+import {
+ createCmHandles,
+ deleteCmHandles,
+ waitForAllCmHandlesToBeReady
+} from './common/cmhandle-crud.js';
import { executeCmHandleSearch, executeCmHandleIdSearch } from './common/search-base.js';
import { passthroughRead, passthroughReadWithAltId, passthroughWrite, batchRead } from './common/passthrough-crud.js';
-let cmHandlesCreatedPerSecondGauge = new Gauge('cmhandles_created_per_second');
-let cmHandlesDeletedPerSecondGauge = new Gauge('cmhandles_deleted_per_second');
+let cmHandlesCreatedPerSecondTrend = new Trend('cmhandles_created_per_second', false);
+let cmHandlesDeletedPerSecondTrend = new Trend('cmhandles_deleted_per_second', false);
let passthroughReadNcmpOverheadTrend = new Trend('ncmp_overhead_passthrough_read', true);
let passthroughReadNcmpOverheadTrendWithAlternateId = new Trend('ncmp_overhead_passthrough_read_alt_id', true);
let passthroughWriteNcmpOverheadTrend = new Trend('ncmp_overhead_passthrough_write', true);
-let dataOperationsBatchReadCmHandlePerSecondTrend = new Trend('data_operations_batch_read_cmhandles_per_second');
+let idSearchDurationTrend = new Trend('id_search_duration', true);
+let cmSearchDurationTrend = new Trend('cm_search_duration', true);
+let dataOperationsBatchReadCmHandlePerSecondTrend = new Trend('data_operations_batch_read_cmhandles_per_second', false);
const reader = new Reader({
brokers: KAFKA_BOOTSTRAP_SERVERS,
@@ -45,7 +51,7 @@ const reader = new Reader({
const DURATION = '15m';
export const options = {
- setupTimeout: '6m',
+ setupTimeout: '8m',
teardownTimeout: '6m',
scenarios: {
passthrough_read: {
@@ -96,69 +102,102 @@ export const options = {
}
},
thresholds: {
- 'cmhandles_created_per_second': ['value >= 22'],
- 'cmhandles_deleted_per_second': ['value >= 22'],
+ 'cmhandles_created_per_second': ['avg >= 22'],
+ 'cmhandles_deleted_per_second': ['avg >= 22'],
'ncmp_overhead_passthrough_read': ['avg <= 100'],
'ncmp_overhead_passthrough_read_alt_id': ['avg <= 100'],
'ncmp_overhead_passthrough_write': ['avg <= 100'],
- 'http_req_duration{scenario:id_search_module}': ['avg <= 625'],
- 'http_req_duration{scenario:cm_search_module}': ['avg <= 13000'],
+ 'id_search_duration': ['avg <= 625'],
+ 'cm_search_duration': ['avg <= 13000'],
+ 'data_operations_batch_read_cmhandles_per_second': ['avg >= 150'],
'http_req_failed{scenario:id_search_module}': ['rate == 0'],
'http_req_failed{scenario:cm_search_module}': ['rate == 0'],
'http_req_failed{scenario:passthrough_read}': ['rate == 0'],
'http_req_failed{scenario:passthrough_write}': ['rate == 0'],
+ 'http_req_failed{group:::setup}':['rate == 0'],
+ 'http_req_failed{group:::teardown}':['rate == 0'],
'http_req_failed{scenario:data_operation_send_async_http_request}': ['rate == 0'],
'kafka_reader_error_count{scenario:data_operation_consume_kafka_responses}': ['count == 0'],
- 'data_operations_batch_read_cmhandles_per_second': ['avg >= 150'],
},
};
export function setup() {
- const totalRegistrationTimeInSeconds = recordTimeInSeconds(registerAllCmHandles);
- cmHandlesCreatedPerSecondGauge.add(TOTAL_CM_HANDLES / totalRegistrationTimeInSeconds);
+ const startTimeInMillis = Date.now();
+
+ const TOTAL_BATCHES = Math.ceil(TOTAL_CM_HANDLES / REGISTRATION_BATCH_SIZE);
+ for (let batchNumber = 0; batchNumber < TOTAL_BATCHES; batchNumber++) {
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(REGISTRATION_BATCH_SIZE, batchNumber);
+ const response = createCmHandles(nextBatchOfCmHandleIds);
+ check(response, { 'create CM-handles status equals 200': (r) => r.status === 200 });
+ }
+
+ waitForAllCmHandlesToBeReady();
+
+ const endTimeInMillis = Date.now();
+ const totalRegistrationTimeInSeconds = (endTimeInMillis - startTimeInMillis) / 1000.0;
+
+ cmHandlesCreatedPerSecondTrend.add(TOTAL_CM_HANDLES / totalRegistrationTimeInSeconds);
}
export function teardown() {
- const totalDeregistrationTimeInSeconds = recordTimeInSeconds(deregisterAllCmHandles);
- cmHandlesDeletedPerSecondGauge.add(TOTAL_CM_HANDLES / totalDeregistrationTimeInSeconds);
+ const startTimeInMillis = Date.now();
+
+ const TOTAL_BATCHES = Math.ceil(TOTAL_CM_HANDLES / REGISTRATION_BATCH_SIZE);
+ for (let batchNumber = 0; batchNumber < TOTAL_BATCHES; batchNumber++) {
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(REGISTRATION_BATCH_SIZE, batchNumber);
+ const response = deleteCmHandles(nextBatchOfCmHandleIds);
+ check(response, { 'delete CM-handles status equals 200': (r) => r.status === 200 });
+ }
+
+ const endTimeInMillis = Date.now();
+ const totalDeregistrationTimeInSeconds = (endTimeInMillis - startTimeInMillis) / 1000.0;
+
+ cmHandlesDeletedPerSecondTrend.add(TOTAL_CM_HANDLES / totalDeregistrationTimeInSeconds);
}
export function passthrough_read() {
const response = passthroughRead();
- check(response, { 'passthrough read status equals 200': (r) => r.status === 200 });
- const overhead = response.timings.duration - READ_DATA_FOR_CM_HANDLE_DELAY_MS;
- passthroughReadNcmpOverheadTrend.add(overhead);
+ if (check(response, { 'passthrough read status equals 200': (r) => r.status === 200 })) {
+ const overhead = response.timings.duration - READ_DATA_FOR_CM_HANDLE_DELAY_MS;
+ passthroughReadNcmpOverheadTrend.add(overhead);
+ }
}
export function passthrough_read_alt_id() {
const response = passthroughReadWithAltId();
- check(response, { 'passthrough read with alternate Id status equals 200': (r) => r.status === 200 });
- const overhead = response.timings.duration - READ_DATA_FOR_CM_HANDLE_DELAY_MS;
- passthroughReadNcmpOverheadTrendWithAlternateId.add(overhead);
+ if (check(response, { 'passthrough read with alternate Id status equals 200': (r) => r.status === 200 })) {
+ const overhead = response.timings.duration - READ_DATA_FOR_CM_HANDLE_DELAY_MS;
+ passthroughReadNcmpOverheadTrendWithAlternateId.add(overhead);
+ }
}
export function passthrough_write() {
const response = passthroughWrite();
- check(response, { 'passthrough write status equals 201': (r) => r.status === 201 });
- const overhead = response.timings.duration - WRITE_DATA_FOR_CM_HANDLE_DELAY_MS;
- passthroughWriteNcmpOverheadTrend.add(overhead);
+ if (check(response, { 'passthrough write status equals 201': (r) => r.status === 201 })) {
+ const overhead = response.timings.duration - WRITE_DATA_FOR_CM_HANDLE_DELAY_MS;
+ passthroughWriteNcmpOverheadTrend.add(overhead);
+ }
}
export function id_search_module() {
const response = executeCmHandleIdSearch('module');
- check(response, { 'module ID search status equals 200': (r) => r.status === 200 });
- check(JSON.parse(response.body), { 'module ID search returned expected CM-handles': (arr) => arr.length === TOTAL_CM_HANDLES });
+ if (check(response, { 'CM handle ID search status equals 200': (r) => r.status === 200 })
+ && check(response, { 'CM handle ID search returned expected CM-handles': (r) => r.json('#') === TOTAL_CM_HANDLES })) {
+ idSearchDurationTrend.add(response.timings.duration);
+ }
}
export function cm_search_module() {
const response = executeCmHandleSearch('module');
- check(response, { 'module search status equals 200': (r) => r.status === 200 });
- check(JSON.parse(response.body), { 'module search returned expected CM-handles': (arr) => arr.length === TOTAL_CM_HANDLES });
+ if (check(response, { 'CM handle search status equals 200': (r) => r.status === 200 })
+ && check(response, { 'CM handle search returned expected CM-handles': (r) => r.json('#') === TOTAL_CM_HANDLES })) {
+ cmSearchDurationTrend.add(response.timings.duration);
+ }
}
export function data_operation_send_async_http_request() {
- const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(DATA_OPERATION_READ_BATCH_SIZE,1);
- const response = batchRead(nextBatchOfCmHandleIds)
+ const nextBatchOfCmHandleIds = makeBatchOfCmHandleIds(DATA_OPERATION_READ_BATCH_SIZE, 0);
+ const response = batchRead(nextBatchOfCmHandleIds);
check(response, { 'data operation batch read status equals 200': (r) => r.status === 200 });
}
diff --git a/k6-tests/run-k6-tests.sh b/k6-tests/run-k6-tests.sh
index 9b8747b1ff..b1ad38911a 100755
--- a/k6-tests/run-k6-tests.sh
+++ b/k6-tests/run-k6-tests.sh
@@ -31,6 +31,10 @@ trap on_exit EXIT
pushd "$(dirname "$0")" || exit 1
+# Install needed dependencies.
+source install-deps.sh
+
+# Run k6 test suite.
./setup.sh
./ncmp/run-all-tests.sh
NCMP_RESULT=$?
diff --git a/k6-tests/teardown.sh b/k6-tests/teardown.sh
index 1b4d721a23..7693dc03a4 100755
--- a/k6-tests/teardown.sh
+++ b/k6-tests/teardown.sh
@@ -19,4 +19,10 @@ echo '================================== docker info =========================='
docker ps -a
echo 'Stopping, Removing containers and volumes...'
-docker-compose -f ../docker-compose/docker-compose.yml --profile dmi-stub down --volumes
+docker_compose_cmd="docker-compose -f ../docker-compose/docker-compose.yml --profile dmi-stub down --volumes"
+# Set an environment variable CLEAN_DOCKER_IMAGES=1 to also remove docker images when done (used on jenkins job)
+if [ "${CLEAN_DOCKER_IMAGES:-0}" -eq 1 ]; then
+ $docker_compose_cmd --rmi all
+else
+ $docker_compose_cmd
+fi
diff --git a/spotbugs/src/main/resources/spotbugs-exclude.xml b/spotbugs/src/main/resources/spotbugs-exclude.xml
index 78f61d290e..23e62cdbc7 100644
--- a/spotbugs/src/main/resources/spotbugs-exclude.xml
+++ b/spotbugs/src/main/resources/spotbugs-exclude.xml
@@ -36,6 +36,7 @@
<Bug pattern="NP_NULL_PARAM_DEREF" />
<Bug pattern="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" />
<Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" />
+ <Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" />
<!-- https://stackoverflow.com/a/34674776. Doesn't detect Lombok All Args Constructor variables being used with map get key and value, which can lead to spotbugs being detected
on used fields -->