aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checkstyle/pom.xml2
-rwxr-xr-xcps-application/pom.xml2
-rw-r--r--cps-bom/pom.xml2
-rwxr-xr-xcps-dependencies/pom.xml13
-rw-r--r--cps-events/pom.xml2
-rw-r--r--cps-ncmp-rest/docs/openapi/components.yaml26
-rwxr-xr-xcps-ncmp-rest/docs/openapi/ncmp-inventory.yml4
-rwxr-xr-xcps-ncmp-rest/docs/openapi/ncmp.yml27
-rwxr-xr-xcps-ncmp-rest/docs/openapi/openapi.yml5
-rw-r--r--cps-ncmp-rest/pom.xml10
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java27
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java34
-rw-r--r--cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java43
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java18
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy25
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy65
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy64
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy73
-rw-r--r--cps-ncmp-rest/src/test/resources/dmi-registration.json14
-rw-r--r--cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json43
-rw-r--r--cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json8
-rw-r--r--cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json12
-rw-r--r--cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json10
-rw-r--r--cps-ncmp-service/pom.xml2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java25
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java161
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java21
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java38
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java41
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java10
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetriever.java)33
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandle.java)47
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandlesList.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandlesList.java)46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java13
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandle.java)9
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy48
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy55
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy22
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy10
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy14
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy54
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy20
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy63
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy72
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy (renamed from cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/PersistenceCmHandleSpec.groovy)19
-rwxr-xr-xcps-parent/pom.xml2
-rw-r--r--cps-path-parser/pom.xml2
-rw-r--r--cps-rest/docs/openapi/components.yml16
-rw-r--r--cps-rest/docs/openapi/cpsData.yml26
-rw-r--r--cps-rest/docs/openapi/cpsQuery.yml6
-rwxr-xr-xcps-rest/pom.xml2
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java15
-rw-r--r--cps-ri/pom.xml2
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java49
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java44
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java34
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java36
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java107
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java2
-rwxr-xr-xcps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy5
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy34
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy11
-rwxr-xr-xcps-ri/src/test/resources/data/fragment.sql7
-rw-r--r--cps-service/pom.xml2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java27
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java16
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java17
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy32
-rw-r--r--csit/tests/cps-model-sync/cps-model-sync.robot41
-rw-r--r--docs/api/swagger/ncmp/openapi-inventory.yaml33
-rw-r--r--docs/api/swagger/ncmp/openapi.yaml983
-rwxr-xr-xdocs/release-notes.rst20
-rw-r--r--jacoco-report/pom.xml2
-rw-r--r--pom.xml2
-rw-r--r--spotbugs/pom.xml2
-rwxr-xr-xversion.properties5
77 files changed, 2141 insertions, 795 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml
index ef7c09fe1..07e6cf966 100644
--- a/checkstyle/pom.xml
+++ b/checkstyle/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>checkstyle</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<properties>
<nexusproxy>https://nexus.onap.org</nexusproxy>
diff --git a/cps-application/pom.xml b/cps-application/pom.xml
index 24e41c0cd..50b06b2e6 100755
--- a/cps-application/pom.xml
+++ b/cps-application/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml
index 7da4abf36..3e5f70d77 100644
--- a/cps-bom/pom.xml
+++ b/cps-bom/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-bom</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>This artifact contains dependencyManagement declarations of all published CPS components.</description>
diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml
index 3d15f0e9a..5c2ff565e 100755
--- a/cps-dependencies/pom.xml
+++ b/cps-dependencies/pom.xml
@@ -23,7 +23,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>cps-dependencies</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
@@ -44,6 +44,7 @@
<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
<sonar.skip>true</sonar.skip>
<testcontainers.version>1.15.1</testcontainers.version>
+ <mapstruct.version>1.4.2.Final</mapstruct.version>
</properties>
<distributionManagement>
@@ -183,6 +184,16 @@
<artifactId>log4j-to-slf4j</artifactId>
<version>2.17.1</version>
</dependency>
+ <dependency>
+ <groupId>org.mapstruct</groupId>
+ <artifactId>mapstruct</artifactId>
+ <version>${mapstruct.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mapstruct</groupId>
+ <artifactId>mapstruct-processor</artifactId>
+ <version>${mapstruct.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
</project>
diff --git a/cps-events/pom.xml b/cps-events/pom.xml
index 4327a3aa9..b9b399c95 100644
--- a/cps-events/pom.xml
+++ b/cps-events/pom.xml
@@ -24,7 +24,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index cda6ca3ac..d82813b87 100644
--- a/cps-ncmp-rest/docs/openapi/components.yaml
+++ b/cps-ncmp-rest/docs/openapi/components.yaml
@@ -38,16 +38,19 @@ components:
dmiPlugin:
type: string
example: my-dmi-plugin
+ default: ""
dmiDataPlugin:
type: string
example: my-dmi-data-plugin
+ default: ""
dmiModelPlugin:
type: string
example: my-dmi-model-plugin
+ default: ""
createdCmHandles:
type: array
items:
- $ref: '#/components/schemas/RestCmHandle'
+ $ref: '#/components/schemas/RestInputCmHandle'
updatedCmHandles:
type: array
example:
@@ -61,14 +64,14 @@ components:
update-my-property: updated-property
delete-my-property: '~'
items:
- $ref: '#/components/schemas/RestCmHandle'
+ $ref: '#/components/schemas/RestInputCmHandle'
removedCmHandles:
type: array
items:
type: string
example: [my-cm-handle1, my-cm-handle2, my-cm-handle3]
- RestCmHandle:
+ RestInputCmHandle:
required:
- cmHandle
type: object
@@ -143,6 +146,23 @@ components:
type: string
example: my-module-revision
+ RestOutputCmHandle:
+ type: object
+ title: CM handle Details
+ properties:
+ cmHandle:
+ type: string
+ example: my-cm-handle1
+ publicCmHandleProperties:
+ $ref: '#/components/schemas/CmHandlePublicProperties'
+ CmHandlePublicProperties:
+ type: array
+ items:
+ type: object
+ additionalProperties:
+ type: string
+ example: Book Type
+
examples:
dataSampleRequest:
summary: Sample request
diff --git a/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml b/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
index f3f84fed9..3cd8e8baf 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp-inventory.yml
@@ -31,8 +31,8 @@ updateDmiRegistration:
schema:
$ref: 'components.yaml#/components/schemas/RestDmiPluginRegistration'
responses:
- 201:
- $ref: 'components.yaml#/components/responses/Created'
+ 204:
+ $ref: 'components.yaml#/components/responses/NoContent'
400:
$ref: 'components.yaml#/components/responses/BadRequest'
401:
diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml
index 3a71aba80..a267fb491 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp.yml
@@ -262,3 +262,30 @@ executeCmHandleSearch:
$ref: 'components.yaml#/components/responses/Forbidden'
500:
$ref: 'components.yaml#/components/responses/InternalServerError'
+
+retrieveCmHandleDetailsById:
+ get:
+ description: Retrieve CM handle details and properties by cm handle id
+ tags:
+ - network-cm-proxy
+ summary: Retrieve CM handle details
+ operationId: retrieveCmHandleDetailsById
+ parameters:
+ - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
+ responses:
+ 200:
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: 'components.yaml#/components/schemas/RestOutputCmHandle'
+ 400:
+ $ref: 'components.yaml#/components/responses/BadRequest'
+ 401:
+ $ref: 'components.yaml#/components/responses/Unauthorized'
+ 403:
+ $ref: 'components.yaml#/components/responses/Forbidden'
+ 404:
+ $ref: 'components.yaml#/components/responses/NotFound'
+ 500:
+ $ref: 'components.yaml#/components/responses/InternalServerError' \ No newline at end of file
diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml
index 838a0d08e..12a8318ef 100755
--- a/cps-ncmp-rest/docs/openapi/openapi.yml
+++ b/cps-ncmp-rest/docs/openapi/openapi.yml
@@ -36,4 +36,7 @@ paths:
$ref: 'ncmp.yml#/fetchModuleReferencesByCmHandle'
/v1/ch/searches:
- $ref: 'ncmp.yml#/executeCmHandleSearch' \ No newline at end of file
+ $ref: 'ncmp.yml#/executeCmHandleSearch'
+
+ /v1/ch/{cm-handle}:
+ $ref: 'ncmp.yml#/retrieveCmHandleDetailsById' \ No newline at end of file
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index 26b83bef8..97305cfe9 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
@@ -61,6 +61,14 @@
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.mapstruct</groupId>
+ <artifactId>mapstruct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mapstruct</groupId>
+ <artifactId>mapstruct-processor</artifactId>
+ </dependency>
<!-- T E S T D E P E N D E N C I E S -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
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 419f6e926..86f4460ea 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
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Pantheon.tech
- * Modifications (C) 2021-2022 Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 Nordix Foundation
* Modification Copyright (C) 2021 highstreet technologies GmbH
* Modifications (C) 2021 Bell Canada
* ================================================================================
@@ -10,6 +10,7 @@
* 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.
@@ -38,15 +39,18 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
import org.onap.cps.ncmp.rest.model.CmHandleProperties;
import org.onap.cps.ncmp.rest.model.CmHandleProperty;
+import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
import org.onap.cps.ncmp.rest.model.CmHandles;
import org.onap.cps.ncmp.rest.model.ConditionProperties;
import org.onap.cps.ncmp.rest.model.Conditions;
import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
import org.onap.cps.ncmp.rest.model.ModuleReference;
+import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -186,6 +190,18 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
}
/**
+ * Search for Cm Handle and Properties by Name.
+ * @param cmHandleId cm-handle identifier
+ * @return cm handle and its properties
+ */
+ @Override
+ public ResponseEntity<RestOutputCmHandle> retrieveCmHandleDetailsById(final String cmHandleId) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId);
+ final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle);
+ return ResponseEntity.ok(restOutputCmHandle);
+ }
+
+ /**
* Return module references for a cm handle.
*
* @param cmHandle the cm handle
@@ -233,4 +249,13 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
}
return cmHandleProperties;
}
+
+ private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle();
+ final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
+ restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleID());
+ cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties());
+ restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties);
+ return restOutputCmHandle;
+ }
}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
index 3b72cec38..36991952c 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryController.java
@@ -1,12 +1,14 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Bell Canada
+ * 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.
* 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.
@@ -19,11 +21,9 @@
package org.onap.cps.ncmp.rest.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
import org.onap.cps.ncmp.rest.api.NetworkCmProxyInventoryApi;
import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
import org.springframework.http.HttpStatus;
@@ -33,21 +33,11 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("${rest.api.ncmp-inventory-base-path}")
+@RequiredArgsConstructor
public class NetworkCmProxyInventoryController implements NetworkCmProxyInventoryApi {
private final NetworkCmProxyDataService networkCmProxyDataService;
- private final ObjectMapper objectMapper;
-
- /**
- * Constructor Injection for Dependencies.
- * @param networkCmProxyDataService Data Service Interface
- * @param objectMapper Object Mapper
- */
- public NetworkCmProxyInventoryController(final NetworkCmProxyDataService networkCmProxyDataService,
- final ObjectMapper objectMapper) {
- this.networkCmProxyDataService = networkCmProxyDataService;
- this.objectMapper = objectMapper;
- }
+ private final RestInputMapper restInputMapper;
/**
* Update DMI Plugin Registration (used for first registration also).
@@ -56,15 +46,11 @@ public class NetworkCmProxyInventoryController implements NetworkCmProxyInventor
@Override
public ResponseEntity<Void> updateDmiPluginRegistration(
final @Valid RestDmiPluginRegistration restDmiPluginRegistration) {
- final DmiPluginRegistration dmiPluginRegistration =
- convertRestObjectToJavaApiObject(restDmiPluginRegistration);
- networkCmProxyDataService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
- return new ResponseEntity<>(HttpStatus.CREATED);
- }
-
- private DmiPluginRegistration convertRestObjectToJavaApiObject(
- final RestDmiPluginRegistration restDmiPluginRegistration) {
- return objectMapper.convertValue(restDmiPluginRegistration, DmiPluginRegistration.class);
+ networkCmProxyDataService.updateDmiRegistrationAndSyncModule(
+ restInputMapper.toDmiPluginRegistration(restDmiPluginRegistration));
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
+
+
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java
new file mode 100644
index 000000000..a1d046ece
--- /dev/null
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java
@@ -0,0 +1,43 @@
+/*
+ * ============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=========================================================
+ */
+
+package org.onap.cps.ncmp.rest.controller;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.NullValueMappingStrategy;
+import org.mapstruct.NullValuePropertyMappingStrategy;
+import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration;
+import org.onap.cps.ncmp.rest.model.RestInputCmHandle;
+
+@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT,
+ nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
+public interface RestInputMapper {
+
+ DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration);
+
+ @Mapping(source = "cmHandle", target = "cmHandleID")
+ @Mapping(source = "cmHandleProperties", target = "dmiProperties")
+ @Mapping(source = "publicCmHandleProperties", target = "publicProperties")
+ NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle);
+
+}
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
index d3450e596..5aaf1c31f 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java
@@ -27,10 +27,13 @@ import org.onap.cps.ncmp.api.impl.exception.DmiRequestException;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController;
+import org.onap.cps.ncmp.rest.controller.NetworkCmProxyInventoryController;
import org.onap.cps.ncmp.rest.model.ErrorMessage;
import org.onap.cps.spi.exceptions.CpsException;
+import org.onap.cps.spi.exceptions.DataValidationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -38,7 +41,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
* Exception handler with error message return.
*/
@Slf4j
-@RestControllerAdvice(assignableTypes = {NetworkCmProxyController.class})
+@RestControllerAdvice(assignableTypes = {NetworkCmProxyController.class, NetworkCmProxyInventoryController.class})
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public class NetworkCmProxyRestExceptionHandler {
@@ -56,18 +59,13 @@ public class NetworkCmProxyRestExceptionHandler {
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
- @ExceptionHandler({CpsException.class})
- public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final CpsException exception) {
+ @ExceptionHandler({CpsException.class, ServerNcmpException.class})
+ public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final Exception exception) {
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
- @ExceptionHandler({ServerNcmpException.class})
- public static ResponseEntity<Object> handleServerNcmpExceptions(final ServerNcmpException exception) {
- return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
- }
-
- @ExceptionHandler({DmiRequestException.class})
- public static ResponseEntity<Object> handleDmiRequestExceptions(final DmiRequestException exception) {
+ @ExceptionHandler({DmiRequestException.class, DataValidationException.class, HttpMessageNotReadableException.class})
+ public static ResponseEntity<Object> handleDmiRequestExceptions(final Exception exception) {
return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
}
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 0c8b2227d..c99771443 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
@@ -22,6 +22,9 @@
package org.onap.cps.ncmp.rest.controller
+
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
@@ -180,6 +183,28 @@ class NetworkCmProxyControllerSpec extends Specification {
response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}'
}
+ def 'Get Cm Handle details by Cm Handle id.' () {
+ given: 'an endpoint and a cm handle'
+ def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/Some-Cm-Handle"
+ and: 'an existing ncmp service cm handle'
+ def cmHandleId = 'Some-Cm-Handle'
+ def dmiProperties = [ prop:'some DMI property' ]
+ def publicProperties = [ "public prop":'some public property' ]
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleID: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties)
+ and: 'the service method is invoked with the cm handle id'
+ 1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('Some-Cm-Handle') >> ncmpServiceCmHandle
+ when: 'the cm handle details api is invoked'
+ def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response
+ then: 'the correct response is returned'
+ response.status == HttpStatus.OK.value()
+ and: 'the response returns public properties and the correct properties'
+ response.contentAsString.contains('publicCmHandleProperties')
+ response.contentAsString.contains('public prop')
+ response.contentAsString.contains('some public property')
+ and: 'the content does not contain dmi properties'
+ !response.contentAsString.contains("some DMI property")
+ }
+
def 'Call execute cm handle searches with unrecognized condition name.'() {
given: 'an endpoint and json data'
def searchesEndpoint = "$ncmpBasePathV1/ch/searches"
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
index 8d434e775..079554a22 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyInventoryControllerSpec.groovy
@@ -8,6 +8,7 @@
* 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.
@@ -23,8 +24,9 @@ package org.onap.cps.ncmp.rest.controller
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.TestUtils
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.onap.cps.ncmp.api.models.CmHandle
import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -46,46 +48,51 @@ class NetworkCmProxyInventoryControllerSpec extends Specification {
@SpringBean
NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
+ @SpringBean
+ RestInputMapper restInputMapper = Mock()
+
+ DmiPluginRegistration mockDmiPluginRegistration = Mock()
+
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
@Value('${rest.api.ncmp-inventory-base-path}/v1')
def ncmpBasePathV1
- def 'Register CM Handle Event' () {
- given: 'jsonData'
- def jsonData = TestUtils.getResourceFileContent('dmi-registration.json')
- when: 'post request is performed'
+ def 'Dmi plugin registration #scenario' () {
+ given: 'a dmi plugin registration with #scenario'
+ def jsonData = TestUtils.getResourceFileContent(dmiRegistrationJson)
+ and: 'the expected rest input as an object'
+ def expectedRestDmiPluginRegistration = jsonObjectMapper.convertJsonString(jsonData, RestDmiPluginRegistration)
+ and: 'the converter returns a dmi registration (only for the expected input object)'
+ restInputMapper.toDmiPluginRegistration(expectedRestDmiPluginRegistration) >> mockDmiPluginRegistration
+ when: 'post request is performed & registration is called with correct DMI plugin information'
def response = mvc.perform(
post("$ncmpBasePathV1/ch")
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonData)
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(jsonData)
).andReturn().response
- then: 'the cm handles are registered with the service'
- 1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(_)
- and: 'response status is created'
- response.status == HttpStatus.CREATED.value()
+ then: 'the converted object is forwarded to the registration service'
+ 1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(mockDmiPluginRegistration)
+ and: 'response status is no content'
+ response.status == HttpStatus.NO_CONTENT.value()
+ where: 'the following registration json is used'
+ scenario | dmiRegistrationJson
+ 'multiple services, added, updated and removed cm handles and many properties' | 'dmi_registration_all_singing_and_dancing.json'
+ 'updated cm handle with updated/new and removed properties' | 'dmi_registration_updates_only.json'
+ 'without any properties' | 'dmi_registration_without_properties.json'
}
- def 'Dmi plugin registration with #scenario' () {
- given: 'jsonData, cmHandle, & DmiPluginRegistration'
- def jsonData = TestUtils.getResourceFileContent('dmi_registration_combined_valid.json' )
- def cmHandle = new CmHandle(cmHandleID : 'example-name')
- def expectedDmiPluginRegistration = new DmiPluginRegistration(
- dmiPlugin: 'service1',
- dmiDataPlugin: '',
- dmiModelPlugin: '',
- createdCmHandles: [cmHandle])
+ def 'Dmi plugin registration with invalid json' () {
+ given: 'a dmi plugin registration with #scenario'
+ def jsonDataWithUndefinedDataLabel = '{"notAdmiPlugin":""}'
when: 'post request is performed & registration is called with correct DMI plugin information'
def response = mvc.perform(
post("$ncmpBasePathV1/ch")
.contentType(MediaType.APPLICATION_JSON)
- .content(jsonData)
+ .content(jsonDataWithUndefinedDataLabel)
).andReturn().response
- then: 'no NcmpException is thrown & updateDmiRegistrationAndSyncModule is called with correct parameters'
- 1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule({
- it.getDmiPlugin() == expectedDmiPluginRegistration.getDmiPlugin()
- it.getDmiDataPlugin() == expectedDmiPluginRegistration.getDmiDataPlugin()
- it.getDmiModelPlugin() == expectedDmiPluginRegistration.getDmiModelPlugin()
- it.getCreatedCmHandles().get(0).getCmHandleID() == expectedDmiPluginRegistration.getCreatedCmHandles().get(0).getCmHandleID()
- })
+ then: 'response status is bad request'
+ response.status == HttpStatus.BAD_REQUEST.value()
}
-}
+}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy
new file mode 100644
index 000000000..ed938810c
--- /dev/null
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy
@@ -0,0 +1,64 @@
+/*
+ * ============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=========================================================
+ */
+
+package org.onap.cps.ncmp.rest.controller
+
+import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration
+import org.onap.cps.ncmp.rest.model.RestInputCmHandle
+import spock.lang.Specification
+
+class RestInputMapperSpec extends Specification {
+
+ def objectUnderTest = Mappers.getMapper(RestInputMapper.class)
+
+ def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() {
+ given: 'a rest cm handle input'
+ def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties,
+ publicCmHandleProperties: publicProperties)
+ def restDmiPluginRegistration = new RestDmiPluginRegistration(
+ createdCmHandles: [inputRestCmHandle])
+ when: 'to plugin dmi registration is called'
+ def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration)
+ then: 'the result returns the correct number of cm handles'
+ result.createdCmHandles.size() == 1
+ and: 'the converted cm handle has the same id'
+ result.createdCmHandles[0].cmHandleID == 'example-id'
+ and: '(empty) properties are converted correctly'
+ result.createdCmHandles[0].dmiProperties == expectedDmiProperties
+ result.createdCmHandles[0].publicProperties == expectedPublicProperties
+ where: 'the following parameters are used'
+ scenario | dmiProperties | publicProperties || expectedDmiProperties | expectedPublicProperties
+ 'dmi and public properties' | ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property'] || ['Property-Example': 'example property'] | ['Public-Property-Example': 'public example property']
+ 'no properties' | null | null || [:] | [:]
+ }
+
+ def 'Handling empty dmi registration'() {
+ given: 'a rest cm handle input without any cm handles'
+ def restDmiPluginRegistration = new RestDmiPluginRegistration()
+ when: 'to plugin dmi registration is called'
+ def result = objectUnderTest.toDmiPluginRegistration(restDmiPluginRegistration)
+ then: 'unspecified lists remain as empty lists'
+ assert result.createdCmHandles == []
+ assert result.updatedCmHandles == []
+ assert result.removedCmHandles == []
+ }
+
+}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
index 1b72b8c08..8004328bc 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -8,6 +8,7 @@
* 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.
@@ -22,22 +23,30 @@ package org.onap.cps.ncmp.rest.exceptions
import groovy.json.JsonSlurper
import org.modelmapper.ModelMapper
+import org.onap.cps.TestUtils
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException
+import org.onap.cps.ncmp.rest.controller.RestInputMapper
import org.onap.cps.spi.exceptions.CpsException
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException
+import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
+import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import spock.lang.Shared
import spock.lang.Specification
+import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP
+import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY
import static org.springframework.http.HttpStatus.BAD_REQUEST
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
@WebMvcTest
class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@@ -54,41 +63,68 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@SpringBean
JsonObjectMapper jsonObjectMapper = Stub()
+ @SpringBean
+ RestInputMapper restInputMapper = Mock()
+
@Value('${rest.api.ncmp-base-path}')
- def basePath
+ def basePathNcmp
- def dataNodeBaseEndpoint
+ @Value('${rest.api.ncmp-inventory-base-path}')
+ def basePathNcmpInventory
+
+ def dataNodeBaseEndpointNcmp
+ def dataNodeBaseEndpointNcmpInventory
@Shared
def errorMessage = 'some error message'
@Shared
def errorDetails = 'some error details'
+ @Shared
+ def dataNodeNotFoundErrorMessage = 'DataNode not found'
def setup() {
- dataNodeBaseEndpoint = "$basePath/v1"
+ dataNodeBaseEndpointNcmp = "$basePathNcmp/v1"
+ dataNodeBaseEndpointNcmpInventory = "$basePathNcmpInventory/v1"
}
def 'Get request with generic #scenario exception returns correct HTTP Status.'() {
when: 'an exception is thrown by the service'
- setupTestException(exception)
- def response = performTestRequest()
+ setupTestException(exception, NCMP)
+ def response = performTestRequest(NCMP)
then: 'an HTTP response is returned with correct message and details'
- assertTestResponse(response, expectedErrorCode, errorMessage, expectedErrorDetails)
+ assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails)
where:
- scenario | exception || expectedErrorDetails | expectedErrorCode
- 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails | INTERNAL_SERVER_ERROR
- 'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null | INTERNAL_SERVER_ERROR
- 'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null | BAD_REQUEST
- 'other' | new IllegalStateException(errorMessage) || null | INTERNAL_SERVER_ERROR
+ scenario | exception || expectedErrorDetails | expectedErrorMessage | expectedErrorCode
+ 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails | errorMessage | INTERNAL_SERVER_ERROR
+ 'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null | errorMessage | INTERNAL_SERVER_ERROR
+ 'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null | errorMessage | BAD_REQUEST
+ 'DataNode Validation' | new DataNodeNotFoundException(dataNodeNotFoundErrorMessage, errorDetails) || null | dataNodeNotFoundErrorMessage | BAD_REQUEST
+ 'other' | new IllegalStateException(errorMessage) || null | errorMessage | INTERNAL_SERVER_ERROR
}
- def setupTestException(exception){
- mockNetworkCmProxyDataService.getYangResourcesModuleReferences('testCmHandle')>>
- { throw exception}
+ def 'Post request with exception returns correct HTTP Status.'() {
+ given: 'the service throws data validation exception'
+ def exception = new DataValidationException(errorMessage, errorDetails)
+ setupTestException(exception, NCMPINVENTORY)
+ when: 'the HTTP request is made'
+ def response = performTestRequest(NCMPINVENTORY)
+ then: 'an HTTP response is returned with correct message and details'
+ assertTestResponse(response, BAD_REQUEST, errorMessage, errorDetails)
+ }
+
+ def setupTestException(exception, apiType) {
+ if (NCMP == apiType) {
+ mockNetworkCmProxyDataService.getYangResourcesModuleReferences(*_) >> { throw exception }
+ }
+ mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(*_) >> { throw exception }
}
- def performTestRequest(){
- return mvc.perform(get("$dataNodeBaseEndpoint/ch/testCmHandle/modules")).andReturn().response
+ def performTestRequest(apiType) {
+ if (NCMP == apiType) {
+ return mvc.perform(get("$dataNodeBaseEndpointNcmp/ch/testCmHandle/modules")).andReturn().response
+ }
+ def jsonData = TestUtils.getResourceFileContent('dmi_registration_all_singing_and_dancing.json')
+ return mvc.perform(post("$dataNodeBaseEndpointNcmpInventory/ch").contentType(MediaType.APPLICATION_JSON).content(jsonData)).andReturn().response
}
static void assertTestResponse(response, expectedStatus , expectedErrorMessage , expectedErrorDetails) {
@@ -98,4 +134,9 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
assert content['message'] == expectedErrorMessage
assert expectedErrorDetails == null || content['details'] == expectedErrorDetails
}
+
+ enum ApiType {
+ NCMP,
+ NCMPINVENTORY;
+ }
}
diff --git a/cps-ncmp-rest/src/test/resources/dmi-registration.json b/cps-ncmp-rest/src/test/resources/dmi-registration.json
deleted file mode 100644
index 4f27e1184..000000000
--- a/cps-ncmp-rest/src/test/resources/dmi-registration.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "dmiPlugin": "onap-dmi-plugin",
- "createdCmHandles": [
- {
- "cmHandle": "example-name",
- "cmHandleProperties": {
- "subSystemId" : "system-001"
- },
- "publicCmHandleProperties": {
- "area" : "south"
- }
- }
- ]
-} \ No newline at end of file
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json b/cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json
new file mode 100644
index 000000000..fd8b56b02
--- /dev/null
+++ b/cps-ncmp-rest/src/test/resources/dmi_registration_all_singing_and_dancing.json
@@ -0,0 +1,43 @@
+{
+ "dmiDataPlugin":"service2",
+ "dmiModelPlugin":"service3",
+ "createdCmHandles":[
+ {
+ "cmHandle":"ch1(new)",
+ "cmHandleProperties":{
+ "dmiProp1":"ch1-dmi1",
+ "dmiProp2":"ch1-dmi2"
+ },
+ "publicCmHandleProperties":{
+ "pubProp1":"ch1-pub1",
+ "pubProp2":"ch1-pub2"
+ }
+ },
+ {
+ "cmHandle":"ch2(new)",
+ "cmHandleProperties":{
+ "dmiProp1":"ch2-dmi1",
+ "dmiProp2":"ch2-dmi2"
+ },
+ "publicCmHandleProperties":{
+ "pubProp1":"ch2-pub1",
+ "pubProp2":"ch2-pub2"
+ }
+ }
+ ],
+ "updatedCmHandles":[
+ {
+ "cmHandle":"ch3(upd)",
+ "cmHandleProperties":{
+ "dmiProp1":"ch3-dmi1"
+ },
+ "publicCmHandleProperties":{
+ "pubProp2":"ch3-pub1"
+ }
+ }
+ ],
+ "removedCmHandles":[
+ "ch4",
+ "ch5"
+ ]
+}
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json b/cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json
deleted file mode 100644
index bded4f215..000000000
--- a/cps-ncmp-rest/src/test/resources/dmi_registration_combined_valid.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "dmiPlugin": "service1",
- "dmiDataPlugin": "",
- "dmiModelPlugin": "",
- "createdCmHandles": [{
- "cmHandle": "example-name"
- }]
-} \ No newline at end of file
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json b/cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json
new file mode 100644
index 000000000..58a1a9836
--- /dev/null
+++ b/cps-ncmp-rest/src/test/resources/dmi_registration_updates_only.json
@@ -0,0 +1,12 @@
+{
+ "dmiPlugin": "service1",
+ "updatedCmHandles":[
+ {
+ "cmHandle":"ch3(upd)",
+ "cmHandleProperties":{
+ "dmiProp1":"ch3-dmi1",
+ "dmiProp2":null
+ }
+ }
+ ]
+}
diff --git a/cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json b/cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json
new file mode 100644
index 000000000..395c098d2
--- /dev/null
+++ b/cps-ncmp-rest/src/test/resources/dmi_registration_without_properties.json
@@ -0,0 +1,10 @@
+{
+ "dmiPlugin":"",
+ "dmiDataPlugin":"service2",
+ "dmiModelPlugin":"service3",
+ "createdCmHandles":[
+ {
+ "cmHandle": "ch1(new)"
+ }
+ ]
+}
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index 871bd14c5..5145a12ce 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
index 5d2ab5339..471e97e08 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
@@ -26,6 +26,7 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import java.util.Collection;
import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.spi.model.ModuleReference;
/*
@@ -44,13 +45,13 @@ public interface NetworkCmProxyDataService {
* Get resource data for data store pass-through operational
* using dmi.
*
- * @param cmHandle cm handle
+ * @param cmHandleId cm handle identifier
* @param resourceIdentifier resource identifier
* @param acceptParamInHeader accept param
* @param optionsParamInQuery options query
* @return {@code Object} resource data
*/
- Object getResourceDataOperationalForCmHandle(String cmHandle,
+ Object getResourceDataOperationalForCmHandle(String cmHandleId,
String resourceIdentifier,
String acceptParamInHeader,
String optionsParamInQuery);
@@ -59,13 +60,13 @@ public interface NetworkCmProxyDataService {
* Get resource data for data store pass-through running
* using dmi.
*
- * @param cmHandle cm handle
+ * @param cmHandleId cm handle identifier
* @param resourceIdentifier resource identifier
* @param acceptParamInHeader accept param
* @param optionsParamInQuery options query
* @return {@code Object} resource data
*/
- Object getResourceDataPassThroughRunningForCmHandle(String cmHandle,
+ Object getResourceDataPassThroughRunningForCmHandle(String cmHandleId,
String resourceIdentifier,
String acceptParamInHeader,
String optionsParamInQuery);
@@ -73,14 +74,14 @@ public interface NetworkCmProxyDataService {
/**
* Write resource data for data store pass-through running
* using dmi for given cm-handle.
- * @param cmHandle cm handle
+ * @param cmHandleId cm handle identifier
* @param resourceIdentifier resource identifier
* @param operation required operation
* @param requestBody request body to create resource
* @param contentType content type in body
* @return {@code Object} return data
*/
- Object writeResourceDataPassThroughRunningForCmHandle(String cmHandle,
+ Object writeResourceDataPassThroughRunningForCmHandle(String cmHandleId,
String resourceIdentifier,
OperationEnum operation,
String requestBody,
@@ -89,10 +90,10 @@ public interface NetworkCmProxyDataService {
/**
* Retrieve module references for the given cm handle.
*
- * @param cmHandle cm handle
+ * @param cmHandleId cm handle identifier
* @return a collection of modules names and revisions
*/
- Collection<ModuleReference> getYangResourcesModuleReferences(String cmHandle);
+ Collection<ModuleReference> getYangResourcesModuleReferences(String cmHandleId);
/**
* Query cm handle identifiers for the given collection of module names.
@@ -103,4 +104,12 @@ public interface NetworkCmProxyDataService {
*/
Collection<String> executeCmHandleHasAllModulesSearch(Collection<String> moduleNames);
+ /**
+ * Query cm handle details by cm handle's name.
+ *
+ * @param cmHandleId cm handle identifier
+ * @return a collection of cm handle details.
+ */
+ NcmpServiceCmHandle getNcmpServiceCmHandle(String cmHandleId);
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 38f8e1707..1762e4628 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -32,11 +32,12 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
import com.fasterxml.jackson.core.JsonProcessingException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsAdminService;
@@ -47,10 +48,11 @@ import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
-import org.onap.cps.ncmp.api.models.CmHandle;
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandlesList;
import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandlesList;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.ModuleReference;
@@ -77,34 +79,34 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
+ private final YangModelCmHandleRetriever yangModelCmHandleRetriever;
+
@Override
public void updateDmiRegistrationAndSyncModule(final DmiPluginRegistration dmiPluginRegistration) {
dmiPluginRegistration.validateDmiPluginRegistration();
try {
- if (dmiPluginRegistration.getCreatedCmHandles() != null) {
+ if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) {
parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration);
}
- if (dmiPluginRegistration.getUpdatedCmHandles() != null) {
+ if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) {
parseAndUpdateCmHandlesInDmiRegistration(dmiPluginRegistration);
}
- if (dmiPluginRegistration.getRemovedCmHandles() != null) {
- parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration);
- }
+ parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration);
} catch (final JsonProcessingException | DataNodeNotFoundException e) {
final String errorMessage = String.format(
- "Error occurred while processing the CM-handle registration request [%s] ,caused by : [%s]",
- dmiPluginRegistration, e.getMessage());
+ "Error occurred while processing the CM-handle registration request, caused by : [%s]",
+ e.getMessage());
throw new DataValidationException(errorMessage, e.getMessage(), e);
}
}
@Override
- public Object getResourceDataOperationalForCmHandle(final String cmHandle,
+ public Object getResourceDataOperationalForCmHandle(final String cmHandleId,
final String resourceIdentifier,
final String acceptParamInHeader,
final String optionsParamInQuery) {
return handleResponse(dmiDataOperations.getResourceDataFromDmi(
- cmHandle,
+ cmHandleId,
resourceIdentifier,
optionsParamInQuery,
acceptParamInHeader,
@@ -112,12 +114,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
@Override
- public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandle,
+ public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
final String resourceIdentifier,
final String acceptParamInHeader,
final String optionsParamInQuery) {
return handleResponse(dmiDataOperations.getResourceDataFromDmi(
- cmHandle,
+ cmHandleId,
resourceIdentifier,
optionsParamInQuery,
acceptParamInHeader,
@@ -125,21 +127,21 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
@Override
- public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandle,
+ public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
final String resourceIdentifier,
final OperationEnum operation,
final String requestData,
final String dataType) {
return handleResponse(
dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(
- cmHandle, resourceIdentifier, operation, requestData, dataType),
+ cmHandleId, resourceIdentifier, operation, requestData, dataType),
"Not able to " + operation + " resource data.");
}
@Override
- public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandle) {
- return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle);
+ public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
+ return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
}
/**
@@ -154,16 +156,56 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
/**
- * THis method registers a cm handle and intiates modules sync.
+ * Retrieve cm handle details for a given cm handle.
+ * @param cmHandleId cm handle identifier
+ * @return cm handle details
+ */
+ @Override
+ public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
+ final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
+ final YangModelCmHandle yangModelCmHandle =
+ yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
+ final List<YangModelCmHandle.Property> dmiProperties = yangModelCmHandle.getDmiProperties();
+ final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties();
+ ncmpServiceCmHandle.setCmHandleID(yangModelCmHandle.getId());
+ setDmiProperties(dmiProperties, ncmpServiceCmHandle);
+ setPublicProperties(publicProperties, ncmpServiceCmHandle);
+ return ncmpServiceCmHandle;
+ }
+
+ private void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size());
+ asPropertiesMap(dmiProperties, dmiPropertiesMap);
+ ncmpServiceCmHandle.setDmiProperties(dmiPropertiesMap);
+ }
+
+ private void setPublicProperties(final List<YangModelCmHandle.Property> publicProperties,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final Map<String, String> publicPropertiesMap = new LinkedHashMap<>();
+ asPropertiesMap(publicProperties, publicPropertiesMap);
+ ncmpServiceCmHandle.setPublicProperties(publicPropertiesMap);
+ }
+
+ private void asPropertiesMap(final List<YangModelCmHandle.Property> properties,
+ final Map<String, String> propertiesMap) {
+ for (final YangModelCmHandle.Property property: properties) {
+ propertiesMap.put(property.getName(), property.getValue());
+ }
+ }
+
+ /**
+ * THis method registers a cm handle and initiates modules sync.
*
* @param dmiPluginRegistration dmi plugin registration information.
* @throws JsonProcessingException thrown if json is malformed or missing.
*/
public void parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(
final DmiPluginRegistration dmiPluginRegistration) throws JsonProcessingException {
- final PersistenceCmHandlesList createdPersistenceCmHandlesList =
- getUpdatedPersistenceCmHandlesList(dmiPluginRegistration, dmiPluginRegistration.getCreatedCmHandles());
- registerAndSyncNewCmHandles(createdPersistenceCmHandlesList);
+ final YangModelCmHandlesList createdYangModelCmHandlesList =
+ getUpdatedYangModelCmHandlesList(dmiPluginRegistration,
+ dmiPluginRegistration.getCreatedCmHandles());
+ registerAndSyncNewCmHandles(createdYangModelCmHandlesList);
}
private static Object handleResponse(final ResponseEntity<?> responseEntity,
@@ -181,29 +223,29 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
networkCmProxyDataServicePropertyHandler.updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles());
}
- private PersistenceCmHandlesList getUpdatedPersistenceCmHandlesList(
+ private YangModelCmHandlesList getUpdatedYangModelCmHandlesList(
final DmiPluginRegistration dmiPluginRegistration,
- final List<CmHandle> updatedCmHandles) {
- return PersistenceCmHandlesList.toPersistenceCmHandlesList(
+ final List<NcmpServiceCmHandle> updatedCmHandles) {
+ return YangModelCmHandlesList.toYangModelCmHandlesList(
dmiPluginRegistration.getDmiPlugin(),
dmiPluginRegistration.getDmiDataPlugin(),
dmiPluginRegistration.getDmiModelPlugin(),
updatedCmHandles);
}
- private void registerAndSyncNewCmHandles(final PersistenceCmHandlesList persistenceCmHandlesList) {
- final String cmHandleJsonData = jsonObjectMapper.asJsonString(persistenceCmHandlesList);
+ private void registerAndSyncNewCmHandles(final YangModelCmHandlesList yangModelCmHandlesList) {
+ final String cmHandleJsonData = jsonObjectMapper.asJsonString(yangModelCmHandlesList);
cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
cmHandleJsonData, NO_TIMESTAMP);
- for (final PersistenceCmHandle persistenceCmHandle : persistenceCmHandlesList.getPersistenceCmHandles()) {
- syncModulesAndCreateAnchor(persistenceCmHandle);
+ for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandlesList.getYangModelCmHandles()) {
+ syncModulesAndCreateAnchor(yangModelCmHandle);
}
}
- protected void syncModulesAndCreateAnchor(final PersistenceCmHandle persistenceCmHandle) {
- syncAndCreateSchemaSet(persistenceCmHandle);
- createAnchor(persistenceCmHandle);
+ protected void syncModulesAndCreateAnchor(final YangModelCmHandle yangModelCmHandle) {
+ syncAndCreateSchemaSet(yangModelCmHandle);
+ createAnchor(yangModelCmHandle);
}
private void parseAndRemoveCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) {
@@ -227,43 +269,32 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
}
- private void syncAndCreateSchemaSet(final PersistenceCmHandle persistenceCmHandle) {
- final List<ModuleReference> moduleReferencesFromCmHandle =
- dmiModelOperations.getModuleReferences(persistenceCmHandle);
- final List<ModuleReference> existingModuleReferences = new ArrayList<>();
- final List<ModuleReference> unknownModuleReferences = new ArrayList<>();
- prepareModuleSubsets(moduleReferencesFromCmHandle, existingModuleReferences, unknownModuleReferences);
+ private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
+ final Collection<ModuleReference> moduleReferencesFromCmHandle =
+ dmiModelOperations.getModuleReferences(yangModelCmHandle);
- final Map<String, String> newYangResourcesModuleNameToContentMap;
- if (unknownModuleReferences.isEmpty()) {
- newYangResourcesModuleNameToContentMap = new HashMap<>();
- } else {
- newYangResourcesModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(persistenceCmHandle,
- unknownModuleReferences);
- }
- cpsModuleService
- .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, persistenceCmHandle.getId(),
- newYangResourcesModuleNameToContentMap, existingModuleReferences);
- }
-
- private void prepareModuleSubsets(final List<ModuleReference> moduleReferencesFromCmHandle,
- final List<ModuleReference> existingModuleReferences,
- final List<ModuleReference> unknownModuleReferences) {
+ final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
+ .identifyNewModuleReferences(moduleReferencesFromCmHandle);
- final Collection<ModuleReference> knownModuleReferencesInCps =
- cpsModuleService.getYangResourceModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME);
+ final Collection<ModuleReference> existingModuleReferencesFromCmHandle =
+ moduleReferencesFromCmHandle.stream().filter(moduleReferenceFromCmHandle ->
+ !identifiedNewModuleReferencesFromCmHandle.contains(moduleReferenceFromCmHandle)
+ ).collect(Collectors.toList());
- for (final ModuleReference moduleReferenceFromDmiForCmHandle : moduleReferencesFromCmHandle) {
- if (knownModuleReferencesInCps.contains(moduleReferenceFromDmiForCmHandle)) {
- existingModuleReferences.add(moduleReferenceFromDmiForCmHandle);
- } else {
- unknownModuleReferences.add(moduleReferenceFromDmiForCmHandle);
- }
+ final Map<String, String> newModuleNameToContentMap;
+ if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
+ newModuleNameToContentMap = new HashMap<>();
+ } else {
+ newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
+ identifiedNewModuleReferencesFromCmHandle);
}
+ cpsModuleService
+ .createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
+ newModuleNameToContentMap, existingModuleReferencesFromCmHandle);
}
- private void createAnchor(final PersistenceCmHandle persistenceCmHandle) {
- cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, persistenceCmHandle.getId(),
- persistenceCmHandle.getId());
+ private void createAnchor(final YangModelCmHandle yangModelCmHandle) {
+ cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, yangModelCmHandle.getId(),
+ yangModelCmHandle.getId());
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
index 359921349..ca2f578f4 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java
@@ -37,7 +37,7 @@ import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.models.CmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.model.DataNode;
@@ -56,28 +56,31 @@ public class NetworkCmProxyDataServicePropertyHandler {
private final CpsDataService cpsDataService;
/**
- * Iterates over incoming cmHandles and update the dataNodes based on the updated attributes.
+ * Iterates over incoming ncmpServiceCmHandles and update the dataNodes based on the updated attributes.
* The attributes which are not passed will remain as is.
*
- * @param cmHandles collection of cmHandles
+ * @param ncmpServiceCmHandles collection of ncmpServiceCmHandles
*/
- public void updateCmHandleProperties(final Collection<CmHandle> cmHandles) throws DataNodeNotFoundException {
- for (final CmHandle cmHandle : cmHandles) {
+ public void updateCmHandleProperties(final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles)
+ throws DataNodeNotFoundException {
+ for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
try {
- final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE, cmHandle.getCmHandleID());
+ final String cmHandleXpath = String.format(CM_HANDLE_XPATH_TEMPLATE,
+ ncmpServiceCmHandle.getCmHandleID());
final DataNode existingCmHandleDataNode =
cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandleXpath,
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
- processUpdates(existingCmHandleDataNode, cmHandle);
+ processUpdates(existingCmHandleDataNode, ncmpServiceCmHandle);
} catch (final DataNodeNotFoundException e) {
- log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", cmHandle.getCmHandleID(),
+ log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
+ ncmpServiceCmHandle.getCmHandleID(),
e.getMessage());
throw e;
}
}
}
- private void processUpdates(final DataNode existingCmHandleDataNode, final CmHandle incomingCmHandle) {
+ private void processUpdates(final DataNode existingCmHandleDataNode, final NcmpServiceCmHandle incomingCmHandle) {
if (!incomingCmHandle.getPublicProperties().isEmpty()) {
updateProperties(existingCmHandleDataNode, PUBLIC_PROPERTY, incomingCmHandle.getPublicProperties());
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
index bce3ac384..229d4fc91 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
@@ -27,7 +27,7 @@ import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
@@ -44,7 +44,7 @@ public class DmiDataOperations extends DmiOperations {
*
* @param dmiRestClient {@code DmiRestClient}
*/
- public DmiDataOperations(final PersistenceCmHandleRetriever cmHandlePropertiesRetriever,
+ public DmiDataOperations(final YangModelCmHandleRetriever cmHandlePropertiesRetriever,
final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient) {
@@ -55,28 +55,28 @@ public class DmiDataOperations extends DmiOperations {
* This method fetches the resource data from operational data store for given cm handle
* identifier on given resource using dmi client.
*
- * @param cmHandle network resource identifier
+ * @param cmHandleId network resource identifier
* @param resourceId resource identifier
* @param optionsParamInQuery options query
* @param acceptParamInHeader accept parameter
* @param dataStore data store enum
* @return {@code ResponseEntity} response entity
*/
- public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandle,
+ public ResponseEntity<Object> getResourceDataFromDmi(final String cmHandleId,
final String resourceId,
final String optionsParamInQuery,
final String acceptParamInHeader,
final DataStoreEnum dataStore) {
- final PersistenceCmHandle persistenceCmHandle =
- cmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandle);
+ final YangModelCmHandle yangModelCmHandle =
+ yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.operation(READ)
.build();
- dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+ dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
final var dmiResourceDataUrl = getDmiDatastoreUrlWithOptions(
- persistenceCmHandle.resolveDmiServiceName(DATA), cmHandle, resourceId,
+ yangModelCmHandle.resolveDmiServiceName(DATA), cmHandleId, resourceId,
optionsParamInQuery, dataStore);
final var httpHeaders = prepareHeader(acceptParamInHeader);
return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody, httpHeaders);
@@ -86,38 +86,38 @@ public class DmiDataOperations extends DmiOperations {
* This method creates the resource data from pass-through running data store for given cm handle
* identifier on given resource using dmi client.
*
- * @param cmHandle network resource identifier
+ * @param cmHandleId network resource identifier
* @param resourceId resource identifier
* @param operation operation enum
* @param requestData the request data
* @param dataType data type
* @return {@code ResponseEntity} response entity
*/
- public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandle,
+ public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleId,
final String resourceId,
final OperationEnum operation,
final String requestData,
final String dataType) {
- final PersistenceCmHandle persistenceCmHandle =
- cmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandle);
+ final YangModelCmHandle yangModelCmHandle =
+ yangModelCmHandleRetriever.getDmiServiceNamesAndProperties(cmHandleId);
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.operation(operation)
.data(requestData)
.dataType(dataType)
.build();
- dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+ dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
final String dmiUrl =
- getResourceInDataStoreUrl(persistenceCmHandle.resolveDmiServiceName(DATA),
- cmHandle, resourceId, PASSTHROUGH_RUNNING);
+ getResourceInDataStoreUrl(yangModelCmHandle.resolveDmiServiceName(DATA),
+ cmHandleId, resourceId, PASSTHROUGH_RUNNING);
return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody, new HttpHeaders());
}
private String getResourceInDataStoreUrl(final String dmiServiceName,
- final String cmHandle,
+ final String cmHandleId,
final String resourceId,
final DataStoreEnum dataStoreEnum) {
- return getCmHandleUrl(dmiServiceName, cmHandle)
+ return getCmHandleUrl(dmiServiceName, cmHandleId)
+ "data"
+ URL_SEPARATOR
+ "ds"
@@ -128,12 +128,12 @@ public class DmiDataOperations extends DmiOperations {
}
private String getDmiDatastoreUrlWithOptions(final String dmiServiceName,
- final String cmHandle,
+ final String cmHandleId,
final String resourceId,
final String optionsParamInQuery,
final DataStoreEnum dataStoreEnum) {
final String resourceInDataStoreUrl = getResourceInDataStoreUrl(dmiServiceName,
- cmHandle, resourceId, dataStoreEnum);
+ cmHandleId, resourceId, dataStoreEnum);
return appendOptionsQuery(resourceInDataStoreUrl, optionsParamInQuery);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
index 657b0b474..bfe934dfd 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
@@ -25,12 +25,13 @@ import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.models.YangResource;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.JsonObjectMapper;
@@ -49,7 +50,7 @@ public class DmiModelOperations extends DmiOperations {
*
* @param dmiRestClient {@code DmiRestClient}
*/
- public DmiModelOperations(final PersistenceCmHandleRetriever dmiPropertiesRetriever,
+ public DmiModelOperations(final YangModelCmHandleRetriever dmiPropertiesRetriever,
final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient) {
@@ -59,34 +60,34 @@ public class DmiModelOperations extends DmiOperations {
/**
* Retrieves module references.
*
- * @param persistenceCmHandle the persistence cm handle
+ * @param yangModelCmHandle the yang model cm handle
* @return module references
*/
- public List<ModuleReference> getModuleReferences(final PersistenceCmHandle persistenceCmHandle) {
+ public List<ModuleReference> getModuleReferences(final YangModelCmHandle yangModelCmHandle) {
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.build();
- dmiRequestBody.asDmiProperties(persistenceCmHandle.getDmiProperties());
+ dmiRequestBody.asDmiProperties(yangModelCmHandle.getDmiProperties());
final ResponseEntity<Object> dmiFetchModulesResponseEntity = getResourceFromDmiWithJsonData(
- persistenceCmHandle.resolveDmiServiceName(MODEL),
- jsonObjectMapper.asJsonString(dmiRequestBody), persistenceCmHandle.getId(), "modules");
+ yangModelCmHandle.resolveDmiServiceName(MODEL),
+ jsonObjectMapper.asJsonString(dmiRequestBody), yangModelCmHandle.getId(), "modules");
return toModuleReferences((Map) dmiFetchModulesResponseEntity.getBody());
}
/**
* Retrieve yang resources from dmi for any modules that CPS-NCMP hasn't cached before.
*
- * @param persistenceCmHandle the persistenceCmHandle
- * @param unknownModuleReferences the unknown module references
+ * @param yangModelCmHandle the yangModelCmHandle
+ * @param newModuleReferences the unknown module references
* @return yang resources as map of module name to yang(re)source
*/
- public Map<String, String> getNewYangResourcesFromDmi(final PersistenceCmHandle persistenceCmHandle,
- final List<ModuleReference> unknownModuleReferences) {
+ public Map<String, String> getNewYangResourcesFromDmi(final YangModelCmHandle yangModelCmHandle,
+ final Collection<ModuleReference> newModuleReferences) {
final String jsonWithDataAndDmiProperties = getRequestBodyToFetchYangResources(
- unknownModuleReferences, persistenceCmHandle.getDmiProperties());
+ newModuleReferences, yangModelCmHandle.getDmiProperties());
final ResponseEntity<Object> responseEntity = getResourceFromDmiWithJsonData(
- persistenceCmHandle.resolveDmiServiceName(MODEL),
+ yangModelCmHandle.resolveDmiServiceName(MODEL),
jsonWithDataAndDmiProperties,
- persistenceCmHandle.getId(),
+ yangModelCmHandle.getId(),
"moduleResources");
return asModuleNameToYangResourceMap(responseEntity);
}
@@ -108,9 +109,9 @@ public class DmiModelOperations extends DmiOperations {
return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonData, new HttpHeaders());
}
- private static String getRequestBodyToFetchYangResources(final List<ModuleReference> unknownModuleReferences,
- final List<PersistenceCmHandle.Property> dmiProperties) {
- final JsonArray moduleReferencesAsJson = getModuleReferencesAsJson(unknownModuleReferences);
+ private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
+ final List<YangModelCmHandle.Property> dmiProperties) {
+ final JsonArray moduleReferencesAsJson = getModuleReferencesAsJson(newModuleReferences);
final JsonObject data = new JsonObject();
data.add("modules", moduleReferencesAsJson);
final JsonObject jsonRequestObject = new JsonObject();
@@ -119,7 +120,7 @@ public class DmiModelOperations extends DmiOperations {
return jsonRequestObject.toString();
}
- private static JsonArray getModuleReferencesAsJson(final List<ModuleReference> unknownModuleReferences) {
+ private static JsonArray getModuleReferencesAsJson(final Collection<ModuleReference> unknownModuleReferences) {
final JsonArray moduleReferences = new JsonArray();
for (final ModuleReference moduleReference : unknownModuleReferences) {
@@ -131,10 +132,10 @@ public class DmiModelOperations extends DmiOperations {
return moduleReferences;
}
- private static JsonObject toJsonObject(final List<PersistenceCmHandle.Property>
+ private static JsonObject toJsonObject(final List<YangModelCmHandle.Property>
dmiProperties) {
final JsonObject asJsonObject = new JsonObject();
- for (final PersistenceCmHandle.Property additionalProperty : dmiProperties) {
+ for (final YangModelCmHandle.Property additionalProperty : dmiProperties) {
asJsonObject.addProperty(additionalProperty.getName(), additionalProperty.getValue());
}
return asJsonObject;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
index 2f7376e87..645d9799f 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
@@ -46,7 +46,7 @@ public class DmiOperations {
}
}
- protected final PersistenceCmHandleRetriever cmHandlePropertiesRetriever;
+ protected final YangModelCmHandleRetriever yangModelCmHandleRetriever;
protected final JsonObjectMapper jsonObjectMapper;
protected final NcmpConfiguration.DmiProperties dmiProperties;
protected final DmiRestClient dmiRestClient;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
index 1066eacf7..d97e90cbb 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiRequestBody.java
@@ -28,7 +28,7 @@ import java.util.List;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@@ -60,14 +60,14 @@ public class DmiRequestBody {
private Map<String, String> dmiProperties;
/**
- * Set DMI Properties by converting a list of PersistenceCmHandle.Property objects.
+ * Set DMI Properties by converting a list of YangModelCmHandle.Property objects.
*
- * @param dmiPropertiesAsList list of cm handle dmi properties
+ * @param yangModelCmHandleProperties list of cm handle dmi properties
*/
public void asDmiProperties(
- final List<PersistenceCmHandle.Property> dmiPropertiesAsList) {
+ final List<YangModelCmHandle.Property> yangModelCmHandleProperties) {
dmiProperties = new LinkedHashMap<>();
- for (final PersistenceCmHandle.Property dmiProperty : dmiPropertiesAsList) {
+ for (final YangModelCmHandle.Property dmiProperty : yangModelCmHandleProperties) {
dmiProperties.put(dmiProperty.getName(), dmiProperty.getValue());
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetriever.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java
index c489eef8e..6b6bdf5be 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetriever.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java
@@ -24,39 +24,39 @@ import java.util.LinkedHashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.models.CmHandle;
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
import org.springframework.stereotype.Component;
/**
- * Retrieves PersistenceCmHandles & properties.
+ * Retrieves YangModelCmHandles & properties.
*/
@Component
@AllArgsConstructor
-public class PersistenceCmHandleRetriever {
+public class YangModelCmHandleRetriever {
private static final String NCMP_DATASPACE_NAME = "NCMP-Admin";
private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry";
- private final CpsDataService cpsDataService;
+ private CpsDataService cpsDataService;
/**
* This method retrieves DMI service name and DMI properties for a given cm handle.
* @param cmHandleId the id of the cm handle
- * @return persistence cm handle
+ * @return yang model cm handle
*/
- public PersistenceCmHandle retrieveCmHandleDmiServiceNameAndDmiProperties(final String cmHandleId) {
+ public YangModelCmHandle getDmiServiceNamesAndProperties(final String cmHandleId) {
final DataNode cmHandleDataNode = getCmHandleDataNode(cmHandleId);
- final CmHandle cmHandle = new CmHandle();
- cmHandle.setCmHandleID(cmHandleId);
- populateCmHandleDmiProperties(cmHandleDataNode, cmHandle);
- return PersistenceCmHandle.toPersistenceCmHandle(
+ final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
+ ncmpServiceCmHandle.setCmHandleID(cmHandleId);
+ populateCmHandleProperties(cmHandleDataNode, ncmpServiceCmHandle);
+ return YangModelCmHandle.toYangModelCmHandle(
String.valueOf(cmHandleDataNode.getLeaves().get("dmi-service-name")),
String.valueOf(cmHandleDataNode.getLeaves().get("dmi-data-service-name")),
String.valueOf(cmHandleDataNode.getLeaves().get("dmi-model-service-name")),
- cmHandle
+ ncmpServiceCmHandle
);
}
@@ -68,14 +68,19 @@ public class PersistenceCmHandleRetriever {
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
}
- private static void populateCmHandleDmiProperties(final DataNode cmHandleDataNode, final CmHandle cmHandle) {
+ private static void populateCmHandleProperties(final DataNode cmHandleDataNode,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
final Map<String, String> dmiProperties = new LinkedHashMap<>();
+ final Map<String, String> publicProperties = new LinkedHashMap<>();
for (final DataNode childDataNode: cmHandleDataNode.getChildDataNodes()) {
if (childDataNode.getXpath().contains("/additional-properties[@name=")) {
addProperty(childDataNode, dmiProperties);
+ } else if (childDataNode.getXpath().contains("/public-properties[@name=")) {
+ addProperty(childDataNode, publicProperties);
}
}
- cmHandle.setDmiProperties(dmiProperties);
+ ncmpServiceCmHandle.setDmiProperties(dmiProperties);
+ ncmpServiceCmHandle.setPublicProperties(publicProperties);
}
private static void addProperty(final DataNode propertyDataNode, final Map<String, String> propertiesAsMap) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
index cc32bb75c..47062b354 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
@@ -19,7 +19,7 @@
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.impl.yangmodels;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
@@ -32,14 +32,16 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
/**
- * DmiRegistry.
+ * Cm Handle which follows the Yang resource dmi registry model when persisting data to DMI or the DB.
+ * Yang model CmHandle
*/
@Getter
@Setter
@NoArgsConstructor
-public class PersistenceCmHandle {
+public class YangModelCmHandle {
private String id;
@@ -59,25 +61,26 @@ public class PersistenceCmHandle {
private List<Property> publicProperties;
/**
- * Create a persistenceCmHandle.
+ * Create a yangModelCmHandle.
* @param dmiServiceName dmi service name
* @param dmiDataServiceName dmi data service name
* @param dmiModelServiceName dmi model service name
- * @param cmHandle the cm handle
- * @return instance of persistenceCmHandle
+ * @param ncmpServiceCmHandle the cm handle
+ * @return instance of yangModelCmHandle
*/
- public static PersistenceCmHandle toPersistenceCmHandle(final String dmiServiceName,
- final String dmiDataServiceName,
- final String dmiModelServiceName,
- final CmHandle cmHandle) {
- final PersistenceCmHandle persistenceCmHandle = new PersistenceCmHandle();
- persistenceCmHandle.setId(cmHandle.getCmHandleID());
- persistenceCmHandle.setDmiServiceName(dmiServiceName);
- persistenceCmHandle.setDmiDataServiceName(dmiDataServiceName);
- persistenceCmHandle.setDmiModelServiceName(dmiModelServiceName);
- persistenceCmHandle.setDmiProperties(asPersistenceCmHandleProperties(cmHandle.getDmiProperties()));
- persistenceCmHandle.setPublicProperties(asPersistenceCmHandleProperties(cmHandle.getPublicProperties()));
- return persistenceCmHandle;
+ public static YangModelCmHandle toYangModelCmHandle(final String dmiServiceName,
+ final String dmiDataServiceName,
+ final String dmiModelServiceName,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle();
+ yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleID());
+ yangModelCmHandle.setDmiServiceName(dmiServiceName);
+ yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName);
+ yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName);
+ yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
+ yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
+ ncmpServiceCmHandle.getPublicProperties()));
+ return yangModelCmHandle;
}
/**
@@ -95,12 +98,12 @@ public class PersistenceCmHandle {
return dmiServiceName;
}
- private static List<Property> asPersistenceCmHandleProperties(final Map<String, String> propertiesAsMap) {
- final List<Property> persistenceCmHandleProperties = new ArrayList<>(propertiesAsMap.size());
+ private static List<Property> asYangModelCmHandleProperties(final Map<String, String> propertiesAsMap) {
+ final List<Property> yangModelCmHandleProperties = new ArrayList<>(propertiesAsMap.size());
for (final Map.Entry<String, String> entry : propertiesAsMap.entrySet()) {
- persistenceCmHandleProperties.add(new PersistenceCmHandle.Property(entry.getKey(), entry.getValue()));
+ yangModelCmHandleProperties.add(new YangModelCmHandle.Property(entry.getKey(), entry.getValue()));
}
- return persistenceCmHandleProperties;
+ return yangModelCmHandleProperties;
}
private static boolean isNullEmptyOrBlank(final String serviceName) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandlesList.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandlesList.java
index d4f6e952d..261a0181c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/PersistenceCmHandlesList.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandlesList.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,51 +18,53 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.models;
+package org.onap.cps.ncmp.api.impl.yangmodels;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import lombok.Getter;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
@Getter
-public class PersistenceCmHandlesList {
+public class YangModelCmHandlesList {
@JsonProperty("cm-handles")
- private List<PersistenceCmHandle> persistenceCmHandles = new ArrayList<>();
+ private final List<YangModelCmHandle> yangModelCmHandles = new ArrayList<>();
/**
- * Create a PersistenceCmHandleList given all service names and a collection of cmHandles.
+ * Create a YangModelCmHandleList given all service names and a collection of cmHandles.
* @param dmiServiceName the dmi service name
* @param dmiDataServiceName the dmi data service name
* @param dmiModelServiceName the dmi model service name
- * @param cmHandles cm handles
- * @return instance of PersistenceCmHandleList
+ * @param ncmpServiceCmHandles cm handles rest model
+ * @return instance of YangModelCmHandleList
*/
- public static PersistenceCmHandlesList toPersistenceCmHandlesList(final String dmiServiceName,
- final String dmiDataServiceName,
- final String dmiModelServiceName,
- final Collection<CmHandle> cmHandles) {
- final PersistenceCmHandlesList persistenceCmHandlesList = new PersistenceCmHandlesList();
- for (final CmHandle cmHandle : cmHandles) {
- final PersistenceCmHandle persistenceCmHandle =
- PersistenceCmHandle.toPersistenceCmHandle(
+ public static YangModelCmHandlesList toYangModelCmHandlesList(final String dmiServiceName,
+ final String dmiDataServiceName,
+ final String dmiModelServiceName,
+ final Collection<NcmpServiceCmHandle>
+ ncmpServiceCmHandles) {
+ final YangModelCmHandlesList yangModelCmHandlesList = new YangModelCmHandlesList();
+ for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) {
+ final YangModelCmHandle yangModelCmHandle =
+ YangModelCmHandle.toYangModelCmHandle(
dmiServiceName,
dmiDataServiceName,
dmiModelServiceName,
- cmHandle);
- persistenceCmHandlesList.add(persistenceCmHandle);
+ ncmpServiceCmHandle);
+ yangModelCmHandlesList.add(yangModelCmHandle);
}
- return persistenceCmHandlesList;
+ return yangModelCmHandlesList;
}
/**
- * Add a persistenceCmHandle.
+ * Add a yangModelCmHandle.
*
- * @param persistenceCmHandle the persistenceCmHandle to add
+ * @param yangModelCmHandle the yangModelCmHandle to add
*/
- public void add(final PersistenceCmHandle persistenceCmHandle) {
- persistenceCmHandles.add(persistenceCmHandle);
+ public void add(final YangModelCmHandle yangModelCmHandle) {
+ yangModelCmHandles.add(yangModelCmHandle);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
index f1b3888c6..d1360c325 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java
@@ -22,9 +22,8 @@ package org.onap.cps.ncmp.api.models;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.JsonSetter;
-import com.fasterxml.jackson.annotation.Nulls;
import com.google.common.base.Strings;
+import java.util.Collections;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@@ -39,24 +38,20 @@ import org.onap.cps.ncmp.api.impl.exception.NcmpException;
@JsonInclude(Include.NON_NULL)
public class DmiPluginRegistration {
- @JsonSetter(nulls = Nulls.AS_EMPTY)
private String dmiPlugin;
- @JsonSetter(nulls = Nulls.AS_EMPTY)
private String dmiDataPlugin;
- @JsonSetter(nulls = Nulls.AS_EMPTY)
private String dmiModelPlugin;
- private List<CmHandle> createdCmHandles;
+ private List<NcmpServiceCmHandle> createdCmHandles = Collections.emptyList();
- private List<CmHandle> updatedCmHandles;
+ private List<NcmpServiceCmHandle> updatedCmHandles = Collections.emptyList();
- private List<String> removedCmHandles;
+ private List<String> removedCmHandles = Collections.emptyList();
/**
* Validates plugin service names.
- *
* @throws NcmpException if validation fails.
*/
public void validateDmiPluginRegistration() throws NcmpException {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
index 9a9b6faaf..938127020 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
@@ -20,7 +20,6 @@
package org.onap.cps.ncmp.api.models;
-import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import java.util.Collections;
@@ -31,23 +30,21 @@ import lombok.Setter;
import org.springframework.validation.annotation.Validated;
/**
- * CmHandle.
+ * The NCMP Service model used for the java service API.
+ * NCMP Service CmHandle.
*/
@Validated
@Getter
@Setter
@NoArgsConstructor
-public class CmHandle {
+public class NcmpServiceCmHandle {
- @JsonProperty("cmHandle")
private String cmHandleID;
@JsonSetter(nulls = Nulls.AS_EMPTY)
- @JsonProperty("cmHandleProperties")
private Map<String, String> dmiProperties = Collections.emptyMap();
@JsonSetter(nulls = Nulls.AS_EMPTY)
- @JsonProperty("publicCmHandleProperties")
private Map<String, String> publicProperties = Collections.emptyMap();
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
index 3af4fc00e..553ac7279 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
@@ -24,8 +24,9 @@ import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
-import org.onap.cps.ncmp.api.models.CmHandle
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.model.ModuleReference
import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Specification
@@ -38,38 +39,49 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
def mockCpsAdminService = Mock(CpsAdminService)
def mockDmiModelOperations = Mock(DmiModelOperations)
def mockDmiDataOperations = Mock(DmiDataOperations)
+ def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
def nullNetworkCmProxyDataServicePropertyHandler = null
def objectUnderTest = new NetworkCmProxyDataServiceImpl(nullCpsDataService, mockJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
- mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler)
+ mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler,mockYangModelCmHandleRetriever)
def expectedDataspaceName = 'NFP-Operational'
def 'Sync model for a (new) cm handle with #scenario'() {
- given: 'persistence cm handle is given'
- def cmHandle = new CmHandle()
+ given: 'a cm handle'
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle()
def dmiServiceName = 'some service name'
- cmHandle.cmHandleID = 'cm handle id 1'
- cmHandle.dmiProperties = dmiProperties
- def persistenceCmHandle = PersistenceCmHandle.toPersistenceCmHandle(dmiServiceName, '' , '', cmHandle)
+ ncmpServiceCmHandle.cmHandleID = 'cm handle id 1'
+ def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, '' , '', ncmpServiceCmHandle)
and: 'DMI operations returns some module references'
def moduleReferences = [ new ModuleReference(moduleName:'module1',revision:'1'),
new ModuleReference(moduleName:'module2',revision:'2') ]
- mockDmiModelOperations.getModuleReferences(persistenceCmHandle) >> moduleReferences
+ mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
and: 'CPS-Core returns list of existing module resources'
- mockCpsModuleService.getYangResourceModuleReferences(expectedDataspaceName) >> existingModuleResourcesInCps
+ mockCpsModuleService.getYangResourceModuleReferences(expectedDataspaceName) >> toModuleReference(existingModuleResourcesInCps)
and: 'DMI-Plugin returns resource(s) for "new" module(s)'
- mockDmiModelOperations.getNewYangResourcesFromDmi(persistenceCmHandle, [new ModuleReference('module1', '1')]) >> yangResourceToContentMap
+ mockDmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, [new ModuleReference('module1', '1')]) >> yangResourceToContentMap
when: 'module sync is triggered'
- objectUnderTest.syncModulesAndCreateAnchor(persistenceCmHandle)
+ mockCpsModuleService.identifyNewModuleReferences(moduleReferences) >> toModuleReference(identifiedNewModuleReferences)
+ objectUnderTest.syncModulesAndCreateAnchor(yangModelCmHandle)
then: 'the CPS module service is called once with the correct parameters'
- 1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, persistenceCmHandle.getId(), yangResourceToContentMap, expectedKnownModules)
+ 1 * mockCpsModuleService.createSchemaSetFromModules(expectedDataspaceName, yangModelCmHandle.getId(), yangResourceToContentMap, toModuleReference(expectedKnownModules))
and: 'admin service create anchor method has been called with correct parameters'
- 1 * mockCpsAdminService.createAnchor(expectedDataspaceName, persistenceCmHandle.getId(), persistenceCmHandle.getId())
+ 1 * mockCpsAdminService.createAnchor(expectedDataspaceName, yangModelCmHandle.getId(), yangModelCmHandle.getId())
where: 'the following parameters are used'
- scenario | dmiProperties | existingModuleResourcesInCps | yangResourceToContentMap || expectedKnownModules
- 'one unknown module' | ['name1': 'value1'] | [new ModuleReference('module2', '2'), new ModuleReference('module3', '3')] | [module1: 'some yang source'] || [new ModuleReference('module2', '2')]
- 'no add. properties' | [:] | [new ModuleReference('module2', '2'), new ModuleReference('module3', '3')] | [module1: 'some yang source'] || [new ModuleReference('module2', '2')]
- 'no unknown module' | [:] | [new ModuleReference('module1', '1'), new ModuleReference('module2', '2')] | [:] || [new ModuleReference('module1', '1'), new ModuleReference('module2', '2')]
+ scenario | existingModuleResourcesInCps | identifiedNewModuleReferences | yangResourceToContentMap || expectedKnownModules
+ 'one new module' | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']] | [module1: 'some yang source'] || [['module2' : '2']]
+ 'no add. properties' | [['module2' : '2'], ['module3' : '3']] | [['module1' : '1']] | [module1: 'some yang source'] || [['module2' : '2']]
+ 'no new module' | [['module1' : '1'], ['module2' : '2']] | [] | [:] || [['module1' : '1'], ['module2' : '2']]
}
+
+ def toModuleReference(moduleReferenceAsMap) {
+ def moduleReferences = [].withDefault { [:] }
+ moduleReferenceAsMap.forEach(property ->
+ property.forEach((moduleName, revision) -> {
+ moduleReferences.add(new ModuleReference('moduleName' : moduleName, 'revision' : revision))
+ }))
+ return moduleReferences
+ }
+
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
index 00fda149f..e410463af 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
@@ -28,8 +28,9 @@ import org.onap.cps.api.CpsModuleService
import org.onap.cps.ncmp.api.impl.exception.DmiRequestException
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
-import org.onap.cps.ncmp.api.models.CmHandle
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
import org.onap.cps.ncmp.api.models.DmiPluginRegistration
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataValidationException
import org.onap.cps.utils.JsonObjectMapper
@@ -41,7 +42,7 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
@Shared
- def persistenceCmHandle = new CmHandle()
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle()
@Shared
def cmHandlesArray = ['cmHandle001']
@@ -53,16 +54,17 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def mockDmiModelOperations = Mock(DmiModelOperations)
def mockDmiDataOperations = Mock(DmiDataOperations)
def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler)
+ def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
def noTimestamp = null
def 'Register or re-register a DMI Plugin for the given cm-handle(s) with #scenario process.'() {
given: 'a registration'
def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
- def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server')
- persistenceCmHandle.cmHandleID = '123'
- persistenceCmHandle.dmiProperties = [dmiProp1: 'dmiValue1', dmiProp2: 'dmiValue2']
- persistenceCmHandle.publicProperties = [publicProp1: 'publicValue1', publicProp2: 'publicValue2']
+ def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'my-server')
+ ncmpServiceCmHandle.cmHandleID = '123'
+ ncmpServiceCmHandle.dmiProperties = [dmiProp1: 'dmiValue1', dmiProp2: 'dmiValue2']
+ ncmpServiceCmHandle.publicProperties = [publicProp1: 'publicValue1', publicProp2: 'publicValue2' ]
dmiPluginRegistration.createdCmHandles = createdCmHandles
dmiPluginRegistration.updatedCmHandles = updatedCmHandles
dmiPluginRegistration.removedCmHandles = removedCmHandles
@@ -76,29 +78,29 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
expectedCallsToSaveNode * mockCpsDataService.saveListElements('NCMP-Admin', 'ncmp-dmi-registry',
'/dmi-registry', expectedJsonData, noTimestamp)
and: 'update data node leaves is called with correct parameters'
- expectedCallsToPropertyHandler * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(updatedCmHandles)
+ expectedCallsToUpdateCmHandleProperty * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(updatedCmHandles)
and: 'delete schema set is invoked with the correct parameters'
expectedCallsToDeleteSchemaSetAndListElement * mockCpsModuleService.deleteSchemaSet('NFP-Operational', 'cmHandle001', CASCADE_DELETE_ALLOWED)
and: 'delete list or list element is invoked with the correct parameters'
expectedCallsToDeleteSchemaSetAndListElement * mockCpsDataService.deleteListOrListElement('NCMP-Admin',
- 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
+ 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp)
where:
- scenario | createdCmHandles | updatedCmHandles | removedCmHandles || expectedCallsToSaveNode | expectedCallsToDeleteSchemaSetAndListElement | expectedCallsToPropertyHandler
- 'create' | [persistenceCmHandle] | [] | [] || 1 | 0 | 1
- 'update' | [] | [persistenceCmHandle] | [] || 0 | 0 | 1
- 'delete' | [] | [] | cmHandlesArray || 0 | 1 | 1
- 'create, update and delete' | [persistenceCmHandle] | [persistenceCmHandle] | cmHandlesArray || 1 | 1 | 1
- 'no valid data' | null | null | null || 0 | 0 | 0
+ scenario | createdCmHandles | updatedCmHandles | removedCmHandles || expectedCallsToSaveNode | expectedCallsToDeleteSchemaSetAndListElement | expectedCallsToUpdateCmHandleProperty
+ 'create' | [ncmpServiceCmHandle] | [] | [] || 1 | 0 | 0
+ 'update' | [] | [ncmpServiceCmHandle] | [] || 0 | 0 | 1
+ 'delete' | [] | [] | cmHandlesArray || 0 | 1 | 0
+ 'create, update and delete' | [ncmpServiceCmHandle] | [ncmpServiceCmHandle] | cmHandlesArray || 1 | 1 | 1
+ 'no valid data' | [] | [] | [] || 0 | 0 | 0
}
def 'Register a DMI Plugin for the given cm-handle(s) without DMI properties.'() {
given: 'a registration without cm-handle properties'
NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'my-server')
- persistenceCmHandle.cmHandleID = '123'
- persistenceCmHandle.dmiProperties = Collections.emptyMap()
- persistenceCmHandle.publicProperties = Collections.emptyMap()
- dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+ ncmpServiceCmHandle.cmHandleID = '123'
+ ncmpServiceCmHandle.dmiProperties = Collections.emptyMap()
+ ncmpServiceCmHandle.publicProperties = Collections.emptyMap()
+ dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","dmi-data-service-name":null,"dmi-model-service-name":null,"additional-properties":[],"public-properties":[]}]}'
when: 'registration is updated'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
@@ -107,22 +109,17 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
'/dmi-registry', expectedJsonData, noTimestamp)
}
- def 'Register a DMI Plugin for a given cm-handle(s) with JSON processing errors during #scenario process.'() {
+ def 'Register a DMI Plugin for a given cm-handle(s) with JSON processing errors during process.'() {
given: 'a registration without cm-handle properties '
NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:'some-plugin')
- dmiPluginRegistration.createdCmHandles = createdCmHandles
- dmiPluginRegistration.updatedCmHandles = updatedCmHandles
+ dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
and: 'an json processing exception occurs'
spiedJsonObjectMapper.asJsonString(_) >> { throw (new JsonProcessingException('')) }
when: 'registration is updated and modules are synced'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'a data validation exception is thrown'
thrown(DataValidationException)
- where:
- scenario | createdCmHandles | updatedCmHandles
- 'create' | [persistenceCmHandle] | []
- 'update' | [] | [persistenceCmHandle]
}
def 'Register a DMI Plugin for the given cm-handle(s) with no data found during delete process.'() {
@@ -156,7 +153,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:dmiPlugin, dmiModelPlugin:dmiModelPlugin,
dmiDataPlugin:dmiDataPlugin)
- dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+ dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
when: 'update registration and sync module is called with correct DMI plugin information'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'create cm handles registration and sync modules is called with the correct plugin information'
@@ -173,7 +170,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def objectUnderTest = getObjectUnderTestWithModelSyncDisabled()
def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin:dmiPlugin, dmiModelPlugin:dmiModelPlugin,
dmiDataPlugin:dmiDataPlugin)
- dmiPluginRegistration.createdCmHandles = [persistenceCmHandle]
+ dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle]
when: 'registration is called with incorrect DMI plugin information'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'a DMI Request Exception is thrown with correct message details'
@@ -199,7 +196,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
and: 'dmi plugin registration input update request'
def dmiPluginReg = new DmiPluginRegistration();
dmiPluginReg.dmiPlugin = 'onap.dmap.plugin';
- dmiPluginReg.updatedCmHandles = [new CmHandle(cmHandleID: 'unknownHandle')]
+ dmiPluginReg.updatedCmHandles = [new NcmpServiceCmHandle(cmHandleID: 'unknownHandle')]
and: 'update data node leaves is unable to find data node'
mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> { throw new DataNodeNotFoundException('NCMP-Admin', 'ncmp-dmi-registry') }
when: 'update dmi registration is called'
@@ -211,7 +208,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def getObjectUnderTestWithModelSyncDisabled() {
def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
- mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler))
+ mockCpsModuleService, mockCpsAdminService, mockNetworkCmProxyDataServicePropertyHandler,mockYangModelCmHandleRetriever))
objectUnderTest.syncModulesAndCreateAnchor(*_) >> null
return objectUnderTest
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 6d7bdefb8..b2a3d77ca 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -22,6 +22,9 @@
package org.onap.cps.ncmp.api.impl
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+
import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
@@ -52,9 +55,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
def mockDmiModelOperations = Mock(DmiModelOperations)
def mockDmiDataOperations = Mock(DmiDataOperations)
def nullNetworkCmProxyDataServicePropertyHandler = null
+ def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
- mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler)
+ mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever)
def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
@@ -210,6 +214,22 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
1 * mockCpsAdminService.queryAnchorNames('NFP-Operational', ['some-module-name'])
}
+ def 'Get a cm handle.'() {
+ given: 'the system returns a yang modelled cm handle'
+ def dmiServiceName = 'some service name'
+ def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')]
+ def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')]
+ def yangModelCmHandle = new YangModelCmHandle(id:'Some-Cm-Handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties)
+ 1 * mockYangModelCmHandleRetriever.getDmiServiceNamesAndProperties('Some-Cm-Handle') >> yangModelCmHandle
+ when: 'getting cm handle details for a given cm handle id from ncmp service'
+ def result = objectUnderTest.getNcmpServiceCmHandle('Some-Cm-Handle')
+ then: 'the result returns the correct data'
+ result.cmHandleID == 'Some-Cm-Handle'
+ result.dmiProperties ==[ Book:'Romance Novel' ]
+ result.publicProperties == [ "Public Book":'Public Romance Novel' ]
+
+ }
+
def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() {
given: 'cpsDataService returns valid datanode'
mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy
index 5bdb744b2..9b8d4ada5 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy
@@ -21,7 +21,7 @@
package org.onap.cps.ncmp.api.impl
import org.onap.cps.api.CpsDataService
-import org.onap.cps.ncmp.api.models.CmHandle
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataValidationException
@@ -50,7 +50,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
given: 'the CPS service return a CM handle'
mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
and: 'an update cm handle request with public properties updates'
- def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: updatedPublicProperties)]
+ def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: updatedPublicProperties)]
when: 'update data node leaves is called with the update request'
objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
then: 'the replace list method is called with correct params'
@@ -72,7 +72,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
given: 'the CPS service return a CM handle'
mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
and: 'an update cm handle request with DMI properties updates'
- def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, dmiProperties: updatedDmiProperties)]
+ def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, dmiProperties: updatedDmiProperties)]
when: 'update data node leaves is called with the update request'
objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
then: 'replace list method should is called with correct params'
@@ -96,7 +96,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
def cmHandleDataNode = new DataNode(xpath: cmHandleXpath, childDataNodes: originalPropertyDataNodes)
mockCpsDataService.getDataNode(dataspaceName, anchorName, cmHandleXpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNode
and: 'an update cm handle request that removes all public properties(existing and non-existing)'
- def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])]
+ def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])]
when: 'update data node leaves is called with the update request'
objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest)
then: 'the replace list method is not called'
@@ -115,7 +115,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification {
def 'Exception thrown when we try to update cmHandle'() {
given: 'cm handles request'
- def cmHandleUpdateRequest = [new CmHandle(cmHandleID: cmHandleId, publicProperties: [:], dmiProperties: [:])]
+ def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleID: cmHandleId, publicProperties: [:], dmiProperties: [:])]
and: 'data node cannot be found'
mockCpsDataService.getDataNode(*_) >> { throw new DataNodeNotFoundException(dataspaceName, anchorName, cmHandleXpath) }
when: 'update data node leaves is called using correct parameters'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
index 7873f39bb..e585825ca 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
@@ -46,8 +46,8 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
DmiDataOperations objectUnderTest
def 'call get resource data for #expectedDatastoreInUrl from DMI #scenario.'() {
- given: 'a persistence cm handle for #cmHandleId'
- mockPersistenceCmHandleRetrieval(dmiProperties)
+ given: 'a cm handle for #cmHandleId'
+ mockYangModelCmHandleRetrieval(dmiProperties)
and: 'a positive response from DMI service when it is called with the expected parameters'
def responseFromDmi = new ResponseEntity<Object>(HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData(
@@ -60,15 +60,15 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
where: 'the following parameters are used'
scenario | dmiProperties | dataStore | options || expectedJson | expectedDatastoreInUrl | expectedOptionsInUrl
'without properties' | [] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-operational' | '&options=(a=1,b=2)'
- 'with properties' | [dmiSampleProperty] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)'
- 'null options' | [dmiSampleProperty] | PASSTHROUGH_OPERATIONAL | null || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
- 'empty options' | [dmiSampleProperty] | PASSTHROUGH_OPERATIONAL | '' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
+ 'with properties' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)'
+ 'null options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | null || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
+ 'empty options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | ''
'datastore running' | [] | PASSTHROUGH_RUNNING | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-running' | '&options=(a=1,b=2)'
}
def 'Write data for pass-through:running datastore in DMI.'() {
- given: 'a persistence cm handle for #cmHandleId'
- mockPersistenceCmHandleRetrieval([dmiSampleProperty])
+ given: 'a cm handle for #cmHandleId'
+ mockYangModelCmHandleRetrieval([yangModelCmHandleProperty])
and: 'a positive response from DMI service when it is called with the expected parameters'
def expectedUrl = "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/data/ds" +
"/ncmp-datastore:passthrough-running?resourceIdentifier=${resourceIdentifier}"
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
index bd5fe6f87..cd2cb7112 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
@@ -47,28 +47,28 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
def 'Retrieving module references.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval([])
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval([])
and: 'a positive response from DMI service when it is called with the expected parameters'
def moduleReferencesAsLisOfMaps = [[moduleName:'mod1',revision:'A'],[moduleName:'mod2',revision:'X']]
def responseFromDmi = new ResponseEntity([schemas:moduleReferencesAsLisOfMaps], HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules",
'{"cmHandleProperties":{}}', [:]) >> responseFromDmi
when: 'get module references is called'
- def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
then: 'the result consists of expected module references'
assert result == [new ModuleReference(moduleName:'mod1',revision:'A'), new ModuleReference(moduleName:'mod2',revision:'X')]
}
def 'Retrieving module references edge case: #scenario.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval([])
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval([])
and: 'any response from DMI service when it is called with the expected parameters'
// TODO (toine): production code ignores any error code from DMI, this should be improved in future
def responseFromDmi = new ResponseEntity(bodyAsMap, HttpStatus.NO_CONTENT)
mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi
when: 'get module references is called'
- def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
then: 'the result is empty'
assert result == []
where: 'the DMI response body has the following content'
@@ -80,25 +80,25 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
}
def 'Retrieving module references, DMI property handling: #scenario.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval(dmiProperties)
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval(dmiProperties)
and: 'a positive response from DMI service when it is called with tha expected parameters'
def responseFromDmi = new ResponseEntity<String>(HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules",
'{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', [:]) >> responseFromDmi
when: 'a get module references is called'
- def result = objectUnderTest.getModuleReferences(persistenceCmHandle)
+ def result = objectUnderTest.getModuleReferences(yangModelCmHandle)
then: 'the result is the response from DMI service'
assert result == []
where: 'the following DMI properties are used'
scenario | dmiProperties || expectedAdditionalPropertiesInRequest
- 'with properties' | [dmiSampleProperty] || '{"prop1":"val1"}'
+ 'with properties' | [yangModelCmHandleProperty] || '{"prop1":"val1"}'
'without properties' | [] || '{}'
}
def 'Retrieving yang resources.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval([])
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval([])
and: 'a positive response from DMI service when it is called with the expected parameters'
def responseFromDmi = new ResponseEntity([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source'],
[moduleName: 'mod2', revision: 'C', yangSource: 'other yang source']], HttpStatus.OK)
@@ -106,7 +106,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
'{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', [:]) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
then: 'the result has the 2 expected yang (re)sources (order is not guaranteed)'
assert result.size() == 2
assert result.get('mod1') == 'some yang source'
@@ -114,14 +114,14 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
}
def 'Retrieving yang resources, edge case: scenario.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval([])
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval([])
and: 'a positive response from DMI service when it is called with tha expected parameters'
// TODO (toine): production code ignores any error code from DMI, this should be improved in future
def responseFromDmi = new ResponseEntity(responseFromDmiBody, HttpStatus.NO_CONTENT)
mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, newModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences)
then: 'the result is empty'
assert result == [:]
where: 'the DMI response body has the following content'
@@ -131,40 +131,40 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
}
def 'Retrieving yang resources, DMI property handling #scenario.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval(dmiProperties)
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval(dmiProperties)
and: 'a positive response from DMI service when it is called with the expected parameters'
def responseFromDmi = new ResponseEntity<>([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source']], HttpStatus.OK)
mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources",
'{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":'+expectedAdditionalPropertiesInRequest+'}',
[:]) >> responseFromDmi
when: 'get new yang resources from DMI service'
- def result = objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, unknownModuleReferences)
+ def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, unknownModuleReferences)
then: 'the result is the response from DMI service'
assert result == [mod1:'some yang source']
where: 'the following DMI properties are used'
scenario | dmiProperties | unknownModuleReferences || expectedAdditionalPropertiesInRequest | expectedModuleReferencesInRequest
- 'with module references and properties' | [dmiSampleProperty] | newModuleReferences || '{"prop1":"val1"}' | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
- 'without module references' | [dmiSampleProperty] | [] || '{"prop1":"val1"}' | ''
+ 'with module references and properties' | [yangModelCmHandleProperty] | newModuleReferences || '{"prop1":"val1"}' | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
+ 'without module references' | [yangModelCmHandleProperty] | [] || '{"prop1":"val1"}' | ''
'without properties' | [] | newModuleReferences || '{}' | '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}'
}
def 'Retrieving yang resources from DMI with null DMI properties.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval(null)
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval(null)
when: 'a get new yang resources from DMI is called'
- objectUnderTest.getNewYangResourcesFromDmi(persistenceCmHandle, [])
+ objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, [])
then: 'a null pointer is thrown (we might need to address this later)'
thrown(NullPointerException)
}
def 'Retrieving module references with Json processing exception.'() {
- given: 'a persistence cm handle'
- mockPersistenceCmHandleRetrieval([])
+ given: 'a cm handle'
+ mockYangModelCmHandleRetrieval([])
and: 'a Json processing exception occurs'
spiedJsonObjectMapper.asJsonString(_) >> {throw (new JsonProcessingException('parsing error'))}
when: 'a DMI operation is executed'
- objectUnderTest.getModuleReferences(persistenceCmHandle)
+ objectUnderTest.getModuleReferences(yangModelCmHandle)
then: 'an ncmp exception is thrown'
def exceptionThrown = thrown(JsonProcessingException)
and: 'the message indicates a parsing error'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
index 7b295f68b..dd0d64dd6 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy
@@ -22,7 +22,7 @@ package org.onap.cps.ncmp.api.impl.operations
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.api.impl.client.DmiRestClient
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
import org.spockframework.spring.SpringBean
import spock.lang.Shared
import spock.lang.Specification
@@ -30,27 +30,27 @@ import spock.lang.Specification
abstract class DmiOperationsBaseSpec extends Specification {
@Shared
- def dmiSampleProperty = new PersistenceCmHandle.Property('prop1', 'val1')
+ def yangModelCmHandleProperty = new YangModelCmHandle.Property('prop1', 'val1')
@SpringBean
DmiRestClient mockDmiRestClient = Mock()
@SpringBean
- PersistenceCmHandleRetriever mockCmHandlePropertiesRetriever = Mock()
+ YangModelCmHandleRetriever mockCmHandlePropertiesRetriever = Mock()
@SpringBean
ObjectMapper spyObjectMapper = Spy()
- def persistenceCmHandle = new PersistenceCmHandle()
+ def yangModelCmHandle = new YangModelCmHandle()
def static dmiServiceName = 'some service name'
def static cmHandleId = 'some cm handle'
def static resourceIdentifier = 'parent/child'
- def mockPersistenceCmHandleRetrieval(dmiProperties) {
- persistenceCmHandle.dmiDataServiceName = dmiServiceName
- persistenceCmHandle.dmiServiceName = dmiServiceName
- persistenceCmHandle.dmiProperties = dmiProperties
- persistenceCmHandle.id = cmHandleId
- mockCmHandlePropertiesRetriever.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandleId) >> persistenceCmHandle
+ def mockYangModelCmHandleRetrieval(dmiProperties) {
+ yangModelCmHandle.dmiDataServiceName = dmiServiceName
+ yangModelCmHandle.dmiServiceName = dmiServiceName
+ yangModelCmHandle.dmiProperties = dmiProperties
+ yangModelCmHandle.id = cmHandleId
+ mockCmHandlePropertiesRetriever.getDmiServiceNamesAndProperties(cmHandleId) >> yangModelCmHandle
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy
deleted file mode 100644
index c92234f9a..000000000
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/PersistenceCmHandleRetrieverSpec.groovy
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.operations
-
-import org.onap.cps.api.CpsDataService
-import org.onap.cps.ncmp.api.models.PersistenceCmHandle
-import spock.lang.Shared
-
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-import org.onap.cps.spi.model.DataNode
-import spock.lang.Specification
-
-class PersistenceCmHandleRetrieverSpec extends Specification {
-
- def mockCpsDataService = Mock(CpsDataService)
-
- def objectUnderTest = new PersistenceCmHandleRetriever(mockCpsDataService)
-
- def cmHandleId = 'some cm handle'
- def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"]
- def xpath = "/dmi-registry/cm-handles[@id='some cm handle']"
-
- @Shared
- def childDataNodesForCmHandleProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1","value":"value1"]),
- new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
-
- def "Retrieve CmHandle using datanode #scenario."() {
- given: 'the cps data service returns a data node from the DMI registry'
- def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves)
- mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode
- when: 'retrieving the persisted cm handle'
- def result = objectUnderTest.retrieveCmHandleDmiServiceNameAndDmiProperties(cmHandleId)
- then: 'the result has the correct id and service names'
- result.id == cmHandleId
- result.dmiServiceName == 'common service name'
- result.dmiDataServiceName == 'data service name'
- result.dmiModelServiceName == 'model service name'
- and: 'the expected DMI properties'
- result.dmiProperties == expectedCmHandleProperties
- where: 'the following parameters are used'
- scenario | childDataNodes || expectedCmHandleProperties
- 'without DMI properties' | [] || []
- 'with DMI properties' | childDataNodesForCmHandleProperties || [new PersistenceCmHandle.Property("name1", "value1")]
- }
-}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy
new file mode 100644
index 000000000..593a6ec93
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy
@@ -0,0 +1,72 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021-2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.operations
+
+import org.onap.cps.api.CpsDataService
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import spock.lang.Shared
+
+import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
+import org.onap.cps.spi.model.DataNode
+import spock.lang.Specification
+
+class YangModelCmHandleRetrieverSpec extends Specification {
+
+ def mockCpsDataService = Mock(CpsDataService)
+
+ def objectUnderTest = new YangModelCmHandleRetriever(mockCpsDataService)
+
+ def cmHandleId = 'some cm handle'
+ def leaves = ["dmi-service-name":"common service name","dmi-data-service-name":"data service name","dmi-model-service-name":"model service name"]
+ def xpath = "/dmi-registry/cm-handles[@id='some cm handle']"
+
+ @Shared
+ def childDataNodesForCmHandleWithAllProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"]),
+ new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
+
+ @Shared
+ def childDataNodesForCmHandleWithDMIProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/additional-properties[@name='name1']", leaves: ["name":"name1", "value":"value1"])]
+
+ @Shared
+ def childDataNodesForCmHandleWithPublicProperties = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='some cm handle']/public-properties[@name='name2']", leaves: ["name":"name2","value":"value2"])]
+
+ def "Retrieve CmHandle using datanode with #scenario."() {
+ given: 'the cps data service returns a data node from the DMI registry'
+ def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves)
+ mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode
+ when: 'retrieving the yang modelled cm handle'
+ def result = objectUnderTest.getDmiServiceNamesAndProperties(cmHandleId)
+ then: 'the result has the correct id and service names'
+ result.id == cmHandleId
+ result.dmiServiceName == 'common service name'
+ result.dmiDataServiceName == 'data service name'
+ result.dmiModelServiceName == 'model service name'
+ and: 'the expected DMI properties'
+ result.dmiProperties == expectedDmiProperties
+ result.publicProperties == expectedPublicProperties
+ where: 'the following parameters are used'
+ scenario | childDataNodes || expectedDmiProperties || expectedPublicProperties
+ 'no properties' | [] || [] || []
+ 'DMI and public properties' | childDataNodesForCmHandleWithAllProperties || [new YangModelCmHandle.Property("name1", "value1")] || [new YangModelCmHandle.Property("name2", "value2")]
+ 'just DMI properties' | childDataNodesForCmHandleWithDMIProperties || [new YangModelCmHandle.Property("name1", "value1")] || []
+ 'just public properties' | childDataNodesForCmHandleWithPublicProperties || [] || [new YangModelCmHandle.Property("name2", "value2")]
+ }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/PersistenceCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy
index 49de4422e..470015ec1 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/PersistenceCmHandleSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy
@@ -20,20 +20,21 @@
package org.onap.cps.ncmp.api.models
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
import spock.lang.Specification
import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA
import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL
-class PersistenceCmHandleSpec extends Specification {
+class YangModelCmHandleSpec extends Specification {
- def 'Creating persistence cm handle from a cm handle.'() {
+ def 'Creating yang model cm handle from a service api cm handle.'() {
given: 'a cm handle with properties'
- def cmHandle = new CmHandle()
- cmHandle.dmiProperties = [myDmiProperty:'value1']
- cmHandle.publicProperties = [myPublicProperty:'value2']
- when: 'it is converted to a persistence cm handle'
- def objectUnderTest = PersistenceCmHandle.toPersistenceCmHandle('','','', cmHandle)
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle()
+ ncmpServiceCmHandle.dmiProperties = [myDmiProperty:'value1']
+ ncmpServiceCmHandle.publicProperties = [myPublicProperty:'value2']
+ when: 'it is converted to a yang model cm handle'
+ def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('','','', ncmpServiceCmHandle)
then: 'the result has the right size'
assert objectUnderTest.dmiProperties.size() == 1
and: 'the DMI property in the result has the correct name and value'
@@ -45,8 +46,8 @@ class PersistenceCmHandleSpec extends Specification {
}
def 'Resolve DMI service name: #scenario and #requiredService service require.'() {
- given: 'a Persistence CM Handle'
- def objectUnderTest = PersistenceCmHandle.toPersistenceCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new CmHandle())
+ given: 'a yang model cm handle'
+ def objectUnderTest = YangModelCmHandle.toYangModelCmHandle(dmiServiceName, dmiDataServiceName, dmiModelServiceName, new NcmpServiceCmHandle())
expect:
assert objectUnderTest.resolveDmiServiceName(requiredService) == expectedService
where:
diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml
index 2e0528e97..434464ac6 100755
--- a/cps-parent/pom.xml
+++ b/cps-parent/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml
index 206f0094c..c8b88e8aa 100644
--- a/cps-path-parser/pom.xml
+++ b/cps-path-parser/pom.xml
@@ -23,7 +23,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-rest/docs/openapi/components.yml b/cps-rest/docs/openapi/components.yml
index 5f31569c9..ae0326d7e 100644
--- a/cps-rest/docs/openapi/components.yml
+++ b/cps-rest/docs/openapi/components.yml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2021 Bell Canada.
+# Copyright (c) 2021-2022 Bell Canada.
# Modifications Copyright (C) 2021-2022 Nordix Foundation
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -86,7 +86,7 @@ components:
example: my-schema-set
examples:
- dataSampleRequest:
+ dataSample:
value:
test:bookstore:
bookstore-name: Chapters
@@ -96,16 +96,6 @@ components:
- code: 02
name: kids
- dataSampleResponse:
- summary: The data node returned does not include the root node. This is being investigated as a part of CPS-461
- value:
- bookstore-name: Chapters
- categories:
- - code: 01
- name: SciFi
- - code: 02
- name: kids
-
parameters:
dataspaceNameInQuery:
name: dataspace-name
@@ -269,7 +259,7 @@ components:
schema:
type: object
examples:
- dataSampleResponse:
+ dataSample:
value: ""
Created:
description: Created
diff --git a/cps-rest/docs/openapi/cpsData.yml b/cps-rest/docs/openapi/cpsData.yml
index 099512d7d..265ee23ad 100644
--- a/cps-rest/docs/openapi/cpsData.yml
+++ b/cps-rest/docs/openapi/cpsData.yml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2021 Bell Canada.
+# Copyright (c) 2021-2022 Bell Canada.
# Modifications Copyright (C) 2021-2022 Nordix Foundation
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,8 +37,8 @@ nodeByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleResponse:
- $ref: 'components.yml#/components/examples/dataSampleResponse'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
'400':
$ref: 'components.yml#/components/responses/BadRequest'
'401':
@@ -68,8 +68,8 @@ listElementByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleRequest:
- $ref: 'components.yml#/components/examples/dataSampleRequest'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
responses:
'201':
$ref: 'components.yml#/components/responses/Created'
@@ -99,8 +99,8 @@ listElementByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleRequest:
- $ref: 'components.yml#/components/examples/dataSampleRequest'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
responses:
'200':
$ref: 'components.yml#/components/responses/Ok'
@@ -155,8 +155,8 @@ nodesByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleRequest:
- $ref: 'components.yml#/components/examples/dataSampleRequest'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
responses:
'201':
$ref: 'components.yml#/components/responses/Created'
@@ -188,8 +188,8 @@ nodesByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleRequest:
- $ref: 'components.yml#/components/examples/dataSampleRequest'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
responses:
'200':
$ref: 'components.yml#/components/responses/Ok'
@@ -241,8 +241,8 @@ nodesByDataspaceAndAnchor:
schema:
type: object
examples:
- dataSampleRequest:
- $ref: 'components.yml#/components/examples/dataSampleRequest'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
responses:
'200':
$ref: 'components.yml#/components/responses/Ok'
diff --git a/cps-rest/docs/openapi/cpsQuery.yml b/cps-rest/docs/openapi/cpsQuery.yml
index 06c9ca2a2..dc0402d03 100644
--- a/cps-rest/docs/openapi/cpsQuery.yml
+++ b/cps-rest/docs/openapi/cpsQuery.yml
@@ -1,6 +1,6 @@
# ============LICENSE_START=======================================================
# Copyright (C) 2021 Nordix Foundation
-# Copyright (C) 2021-2022 Nordix Foundation
+# Modifications Copyright (c) 2022 Bell Canada.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -37,8 +37,8 @@ nodesByDataspaceAndAnchorAndCpsPath:
schema:
type: object
examples:
- dataSampleResponse:
- $ref: 'components.yml#/components/examples/dataSampleResponse'
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSample'
'400':
$ref: 'components.yml#/components/responses/BadRequest'
'401':
diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml
index 0ca5fb6aa..20870c369 100755
--- a/cps-rest/pom.xml
+++ b/cps-rest/pom.xml
@@ -27,7 +27,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java b/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
index ceb5dc1ec..9495b3d9e 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java
@@ -63,30 +63,25 @@ public class CpsRestExceptionHandler {
}
@ExceptionHandler({ModelValidationException.class, DataValidationException.class, CpsAdminException.class,
- CpsPathException.class})
- public static ResponseEntity<Object> handleBadRequestExceptions(final CpsException exception) {
+ CpsPathException.class, ValidationException.class})
+ public static ResponseEntity<Object> handleBadRequestExceptions(final Exception exception) {
return buildErrorResponse(HttpStatus.BAD_REQUEST, exception);
}
- @ExceptionHandler({ValidationException.class})
- public static ResponseEntity<Object> handleBadRequestExceptions(final ValidationException validationException) {
- return buildErrorResponse(HttpStatus.BAD_REQUEST, validationException);
- }
-
@ExceptionHandler({NotFoundInDataspaceException.class, DataNodeNotFoundException.class})
- public static ResponseEntity<Object> handleNotFoundExceptions(final CpsException exception,
+ public static ResponseEntity<Object> handleNotFoundExceptions(final Exception exception,
final HttpServletRequest request) {
return buildErrorResponse(HttpMethod.GET.matches(request.getMethod())
? HttpStatus.NOT_FOUND : HttpStatus.BAD_REQUEST, exception);
}
@ExceptionHandler({DataInUseException.class, AlreadyDefinedException.class})
- public static ResponseEntity<Object> handleDataInUseException(final CpsException exception) {
+ public static ResponseEntity<Object> handleDataInUseException(final Exception exception) {
return buildErrorResponse(HttpStatus.CONFLICT, exception);
}
@ExceptionHandler({CpsException.class})
- public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final CpsException exception) {
+ public static ResponseEntity<Object> handleAnyOtherCpsExceptions(final Exception exception) {
return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception);
}
diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml
index 8d860b004..37d93156a 100644
--- a/cps-ri/pom.xml
+++ b/cps-ri/pom.xml
@@ -26,7 +26,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
index 04804726c..f22d83b98 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
@@ -329,22 +329,34 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void deleteDataNode(final String dataspaceName, final String anchorName, final String targetXpath,
- final boolean onlySupportListNodeDeletion) {
- final String parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/'));
- final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
- final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/'));
- final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find();
- boolean targetExist;
- if (isListElement) {
- targetExist = deleteDataNode(parentFragmentEntity, targetXpath);
+ final boolean onlySupportListNodeDeletion) {
+ final String parentNodeXpath;
+ FragmentEntity parentFragmentEntity = null;
+ boolean targetDeleted = false;
+ if (isRootXpath(targetXpath)) {
+ deleteDataNodes(dataspaceName, anchorName);
+ targetDeleted = true;
} else {
- targetExist = deleteAllListElements(parentFragmentEntity, targetXpath);
- final boolean tryToDeleteDataNode = !targetExist && !onlySupportListNodeDeletion;
- if (tryToDeleteDataNode) {
- targetExist = deleteDataNode(parentFragmentEntity, targetXpath);
+ if (isContainerNodeXpath(targetXpath)) {
+ parentNodeXpath = targetXpath;
+ } else {
+ parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/'));
+ }
+ parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
+ final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/'));
+ final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE
+ .matcher(lastXpathElement).find();
+ if (isListElement) {
+ targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath);
+ } else {
+ targetDeleted = deleteAllListElements(parentFragmentEntity, targetXpath);
+ final boolean tryToDeleteDataNode = !targetDeleted && !onlySupportListNodeDeletion;
+ if (tryToDeleteDataNode) {
+ targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath);
+ }
}
}
- if (!targetExist) {
+ if (!targetDeleted) {
final String additionalInformation = onlySupportListNodeDeletion
? "The target is probably not a List." : "";
throw new DataNodeNotFoundException(parentFragmentEntity.getDataspace().getName(),
@@ -353,6 +365,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private boolean deleteDataNode(final FragmentEntity parentFragmentEntity, final String targetXpath) {
+ if (parentFragmentEntity.getXpath().equals(targetXpath)) {
+ fragmentRepository.delete(parentFragmentEntity);
+ return true;
+ }
if (parentFragmentEntity.getChildFragments()
.removeIf(fragment -> fragment.getXpath().equals(targetXpath))) {
fragmentRepository.save(parentFragmentEntity);
@@ -361,7 +377,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return false;
}
-
private boolean deleteAllListElements(final FragmentEntity parentFragmentEntity, final String listXpath) {
final String deleteTargetXpathPrefix = listXpath + "[";
if (parentFragmentEntity.getChildFragments()
@@ -384,7 +399,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
"Cannot replace list elements with empty collection");
}
final String firstChildNodeXpath = newListElements.iterator().next().getXpath();
- return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1);
+ return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1);
}
private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity,
@@ -408,6 +423,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath());
}
+ private static boolean isContainerNodeXpath(final String xpath) {
+ return 0 == xpath.lastIndexOf('/');
+ }
+
private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity,
final DataNode newListElement) {
final FragmentEntity replacementFragmentEntity =
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
index 86d5de6d0..ec720b8a9 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -40,6 +40,7 @@ import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
+import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
@@ -53,9 +54,8 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException;
import org.onap.cps.spi.exceptions.ModelValidationException;
import org.onap.cps.spi.model.ModuleReference;
-import org.onap.cps.spi.repository.AnchorRepository;
import org.onap.cps.spi.repository.DataspaceRepository;
-import org.onap.cps.spi.repository.FragmentRepository;
+import org.onap.cps.spi.repository.ModuleReferenceRepository;
import org.onap.cps.spi.repository.SchemaSetRepository;
import org.onap.cps.spi.repository.YangResourceRepository;
import org.opendaylight.yangtools.yang.common.Revision;
@@ -63,15 +63,14 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
-
-@Component
@Slf4j
+@Component
+@AllArgsConstructor
public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService {
private static final String YANG_RESOURCE_CHECKSUM_CONSTRAINT_NAME = "yang_resource_checksum_key";
@@ -79,24 +78,16 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
private static final Pattern RFC6020_RECOMMENDED_FILENAME_PATTERN = Pattern
.compile("([\\w-]+)@(\\d{4}-\\d{2}-\\d{2})(?:\\.yang)?", Pattern.CASE_INSENSITIVE);
- @Autowired
private YangResourceRepository yangResourceRepository;
- @Autowired
private SchemaSetRepository schemaSetRepository;
- @Autowired
private DataspaceRepository dataspaceRepository;
- @Autowired
- private AnchorRepository anchorRepository;
-
- @Autowired
- private FragmentRepository fragmentRepository;
-
- @Autowired
private CpsAdminPersistenceService cpsAdminPersistenceService;
+ private ModuleReferenceRepository moduleReferenceRepository;
+
@Override
public Map<String, String> getYangSchemaResources(final String dataspaceName, final String schemaSetName) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
@@ -137,9 +128,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
@Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
public void storeSchemaSet(final String dataspaceName, final String schemaSetName,
- final Map<String, String> yangResourcesNameToContentMap) {
+ final Map<String, String> moduleReferenceNameToContentMap) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final var yangResourceEntities = synchronizeYangResources(yangResourcesNameToContentMap);
+ final var yangResourceEntities = synchronizeYangResources(moduleReferenceNameToContentMap);
final var schemaSetEntity = new SchemaSetEntity();
schemaSetEntity.setName(schemaSetName);
schemaSetEntity.setDataspace(dataspaceEntity);
@@ -158,9 +149,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
@Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
public void storeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
- final Map<String, String> newYangResourcesModuleNameToContentMap,
- final List<ModuleReference> moduleReferences) {
- storeSchemaSet(dataspaceName, schemaSetName, newYangResourcesModuleNameToContentMap);
+ final Map<String, String> newModuleNameToContentMap,
+ final Collection<ModuleReference> moduleReferences) {
+ storeSchemaSet(dataspaceName, schemaSetName, newModuleNameToContentMap);
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final var schemaSetEntity =
schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName);
@@ -186,8 +177,15 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
yangResourceRepository.deleteOrphans();
}
- private Set<YangResourceEntity> synchronizeYangResources(final Map<String, String> yangResourcesNameToContentMap) {
- final Map<String, YangResourceEntity> checksumToEntityMap = yangResourcesNameToContentMap.entrySet().stream()
+ @Override
+ public Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck) {
+ return moduleReferenceRepository.identifyNewModuleReferences(moduleReferencesToCheck);
+ }
+
+ private Set<YangResourceEntity> synchronizeYangResources(
+ final Map<String, String> moduleReferenceNameToContentMap) {
+ final Map<String, YangResourceEntity> checksumToEntityMap = moduleReferenceNameToContentMap.entrySet().stream()
.map(entry -> {
final String checksum = DigestUtils.sha256Hex(entry.getValue().getBytes(StandardCharsets.UTF_8));
final Map<String, String> moduleNameAndRevisionMap = createModuleNameAndRevisionMap(entry.getKey(),
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java
new file mode 100644
index 000000000..6551937e1
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java
@@ -0,0 +1,34 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.cps.spi.repository;
+
+import java.util.Collection;
+import org.onap.cps.spi.model.ModuleReference;
+
+/**
+ * This interface is used in conjunction with {@link ModuleReferenceRepository} to create native sql queries.
+ */
+public interface ModuleReferenceQuery {
+
+ Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck);
+
+}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java
new file mode 100644
index 000000000..ce2bfe784
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java
@@ -0,0 +1,36 @@
+/*
+ * ============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=========================================================
+ */
+
+package org.onap.cps.spi.repository;
+
+import java.util.Collection;
+import org.onap.cps.spi.entities.YangResourceEntity;
+import org.onap.cps.spi.model.ModuleReference;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ModuleReferenceRepository extends
+ JpaRepository<YangResourceEntity, Long>, ModuleReferenceQuery {
+
+ Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck);
+
+} \ No newline at end of file
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
new file mode 100644
index 000000000..f4078ffec
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
@@ -0,0 +1,107 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.cps.spi.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.model.ModuleReference;
+import org.springframework.transaction.annotation.Transactional;
+
+@Slf4j
+@Transactional
+public class ModuleReferenceRepositoryImpl implements ModuleReferenceQuery {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Override
+ @SneakyThrows
+ public Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck) {
+
+ if (moduleReferencesToCheck == null || moduleReferencesToCheck.isEmpty()) {
+ return Collections.EMPTY_LIST;
+ }
+
+ final String tempTableName = "moduleReferencesToCheckTemp"
+ + UUID.randomUUID().toString().replaceAll("-", "");
+
+ createTemporaryTable(tempTableName);
+ insertDataIntoTable(tempTableName, moduleReferencesToCheck);
+
+ return identifyNewModuleReferencesForCmHandle(tempTableName);
+ }
+
+ private void createTemporaryTable(final String tempTableName) {
+ final StringBuilder sqlStringBuilder = new StringBuilder("CREATE TEMPORARY TABLE " + tempTableName + "(");
+ sqlStringBuilder.append(" id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,");
+ sqlStringBuilder.append(" module_name varchar NOT NULL,");
+ sqlStringBuilder.append(" revision varchar NOT NULL");
+ sqlStringBuilder.append(");");
+
+ entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate();
+ }
+
+ private void insertDataIntoTable(final String tempTableName, final Collection<ModuleReference> moduleReferences) {
+ final StringBuilder sqlStringBuilder = new StringBuilder("INSERT INTO " + tempTableName);
+ sqlStringBuilder.append(" (module_name, revision) ");
+ sqlStringBuilder.append(" VALUES ");
+
+ for (final ModuleReference moduleReference : moduleReferences) {
+ sqlStringBuilder.append("('");
+ sqlStringBuilder.append(moduleReference.getModuleName());
+ sqlStringBuilder.append("', '");
+ sqlStringBuilder.append(moduleReference.getRevision());
+ sqlStringBuilder.append("'),");
+ }
+
+ // replace last ',' with ';'
+ sqlStringBuilder.replace(sqlStringBuilder.length() - 1, sqlStringBuilder.length(), ";");
+
+ entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate();
+ }
+
+ private Collection<ModuleReference> identifyNewModuleReferencesForCmHandle(final String tempTableName) {
+ final String sql = String.format(
+ "SELECT %1$s.module_name, %1$s.revision"
+ + " FROM %1$s LEFT JOIN yang_resource"
+ + " ON yang_resource.module_name=%1$s.module_name"
+ + " AND yang_resource.revision=%1$s.revision"
+ + " WHERE yang_resource.module_name IS NULL;", tempTableName);
+
+ final List<Object[]> resultsAsObjects =
+ entityManager.createNativeQuery(sql).getResultList();
+
+ final List<ModuleReference> resultsAsModuleReferences = new ArrayList<>(resultsAsObjects.size());
+ for (final Object[] row : resultsAsObjects) {
+ resultsAsModuleReferences.add(new ModuleReference((String) row[0], (String) row[1]));
+ }
+
+ return resultsAsModuleReferences;
+ }
+}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
index 3f5c43dec..895937b60 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Pantheon.tech
- * Modifications Copyright (C) Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
index 2277377a5..ab290051a 100755
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
@@ -511,6 +511,11 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
'child data node, parent still exists' | '/parent-206/child-206' | '/parent-206' || '/parent-206'
'list element' | '/parent-206/child-206/grand-child-206[@key="A"]' | '/parent-206/child-206/grand-child-206[@key="A"]' || null
'list element, sibling still exists' | '/parent-206/child-206/grand-child-206[@key="A"]' | '/parent-206/child-206/grand-child-206[@key="X"]' || '/parent-206/child-206/grand-child-206[@key="X"]'
+ 'container node' | '/parent-206' | '/parent-206' || null
+ 'container list node' | '/parent-206[@key="A"]' | '/parent-206[@key="B"]' || '/parent-206[@key="B"]'
+ 'root node with xpath /' | '/' | '/' || null
+ 'root node with xpath passed as blank' | '' | '' || null
+
}
@Sql([CLEAR_DATA, SET_DATA])
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy
index 75d633026..1b37bef9c 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
@@ -25,18 +25,15 @@ import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.entities.YangResourceEntity
import org.onap.cps.spi.exceptions.AlreadyDefinedException
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
-import org.onap.cps.spi.exceptions.SchemaSetInUseException
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
import org.onap.cps.spi.model.ModuleReference
import org.onap.cps.spi.model.ExtendedModuleReference
import org.onap.cps.spi.repository.AnchorRepository
+import org.onap.cps.spi.repository.ModuleReferenceRepository
import org.onap.cps.spi.repository.SchemaSetRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.jdbc.Sql
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED
-import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
-
class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
@Autowired
@@ -54,7 +51,6 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase
static final String SET_DATA = '/data/schemaset.sql'
static final String EXISTING_SCHEMA_SET_NAME = SCHEMA_SET_NAME1
static final String SCHEMA_SET_NAME_NO_ANCHORS = 'SCHEMA-SET-100'
- static final String SCHEMA_SET_NAME_WITH_ANCHORS_AND_DATA = 'SCHEMA-SET-101'
static final String SCHEMA_SET_NAME_NEW = 'SCHEMA-SET-NEW'
static final String NEW_RESOURCE_NAME = 'some new resource'
@@ -76,9 +72,7 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase
.revision(NEW_RESOURCE_REVISION).build()
def newYangResourcesNameToContentMap = [(NEW_RESOURCE_NAME):NEW_RESOURCE_CONTENT]
- def allYangResourcesModuleAndRevisionList = [new ExtendedModuleReference(name: 'MODULE-NAME-002',namespace:null, revision: 'REVISION-002'), new ExtendedModuleReference(name: 'MODULE-NAME-003',namespace:null, revision: 'REVISION-003'),
- new ExtendedModuleReference(name: 'MODULE-NAME-004',namespace:null, revision: 'REVISION-004'), ExtendedModuleReference.builder().build(),
- ExtendedModuleReference.builder().build(), newModuleReference]
+
def dataspaceEntity
def setup() {
@@ -184,6 +178,19 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase
}
@Sql([CLEAR_DATA, SET_DATA])
+ def 'Identifying new module references where #scenario'() {
+ when: 'identifyNewModuleReferences is called'
+ def result = objectUnderTest.identifyNewModuleReferences(moduleReferences)
+ then: 'the correct module reference collection is returned'
+ assert result == expectedResult
+ where: 'the following data is used'
+ scenario | moduleReferences || expectedResult
+ 'new module references exist' | toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']]) || toModuleReference([['some module 1' : 'some revision 1'], ['some module 2' : 'some revision 2']])
+ 'no new module references exist' | [] || []
+ 'module references collection is null'| null || []
+ }
+
+ @Sql([CLEAR_DATA, SET_DATA])
def 'Delete schema set error scenario: #scenario.'() {
when: 'attempt to delete a schema set where #scenario'
objectUnderTest.deleteSchemaSet(dataspaceName, schemaSetName)
@@ -236,4 +243,13 @@ class CpsModulePersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase
yangResourceEntity.revision == expectedYangResourceRevision
}
+ def toModuleReference(moduleReferenceAsMap) {
+ def moduleReferences = [].withDefault { [:] }
+ moduleReferenceAsMap.forEach(property ->
+ property.forEach((moduleName, revision) -> {
+ moduleReferences.add(new ModuleReference('moduleName' : moduleName, 'revision' : revision))
+ }))
+ return moduleReferences
+ }
+
}
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy
index 8bd7f86ea..9ef973268 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsModulePersistenceServiceSpec.groovy
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (c) 2021 Bell Canada.
+ * 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,9 +20,11 @@
package org.onap.cps.spi.impl
import org.hibernate.exception.ConstraintViolationException
+import org.onap.cps.spi.CpsAdminPersistenceService
import org.onap.cps.spi.CpsModulePersistenceService
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException
import org.onap.cps.spi.repository.DataspaceRepository
+import org.onap.cps.spi.repository.ModuleReferenceRepository
import org.onap.cps.spi.repository.SchemaSetRepository
import org.onap.cps.spi.repository.YangResourceRepository
import org.springframework.dao.DataIntegrityViolationException
@@ -42,6 +45,8 @@ class CpsModulePersistenceServiceSpec extends Specification {
def dataspaceRepositoryMock = Mock(DataspaceRepository)
def yangResourceRepositoryMock = Mock(YangResourceRepository)
def schemaSetRepositoryMock = Mock(SchemaSetRepository)
+ def cpsAdminPersistenceServiceMock = Mock(CpsAdminPersistenceService)
+ def moduleReferenceRepositoryMock = Mock(ModuleReferenceRepository)
// Constants
def yangResourceName = 'my-yang-resource-name'
@@ -73,10 +78,8 @@ class CpsModulePersistenceServiceSpec extends Specification {
anotherIntegrityException = new DataIntegrityViolationException("another integrity exception")
def setup() {
- objectUnderTest = new CpsModulePersistenceServiceImpl()
- objectUnderTest.dataspaceRepository = dataspaceRepositoryMock
- objectUnderTest.yangResourceRepository = yangResourceRepositoryMock
- objectUnderTest.schemaSetRepository = schemaSetRepositoryMock
+ objectUnderTest = new CpsModulePersistenceServiceImpl(yangResourceRepositoryMock, schemaSetRepositoryMock,
+ dataspaceRepositoryMock, cpsAdminPersistenceServiceMock, moduleReferenceRepositoryMock)
}
def 'Store schema set error scenario: #scenario.'() {
diff --git a/cps-ri/src/test/resources/data/fragment.sql b/cps-ri/src/test/resources/data/fragment.sql
index 49c4c9f3e..a27bb5fde 100755
--- a/cps-ri/src/test/resources/data/fragment.sql
+++ b/cps-ri/src/test/resources/data/fragment.sql
@@ -2,7 +2,7 @@
============LICENSE_START=======================================================
Copyright (C) 2021 Nordix Foundation.
Modifications Copyright (C) 2021 Pantheon.tech
- Modifications Copyright (C) 2021 Bell Canada.
+ Modifications Copyright (C) 2021-2022 Bell Canada.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -64,4 +64,7 @@ INSERT INTO FRAGMENT (ID, DATASPACE_ID, ANCHOR_ID, PARENT_ID, XPATH, ATTRIBUTES)
(4227, 1001, 3003, 4226, '/parent-206/child-206', '{}'),
(4228, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206', '{}'),
(4229, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="A"]', '{"key": "A"}'),
- (4230, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="X"]', '{"key": "X"}');
+ (4230, 1001, 3003, 4227, '/parent-206/child-206/grand-child-206[@key="X"]', '{"key": "X"}'),
+ (4231, 1001, 3003, null, '/parent-206[@key="A"]', '{"key": "A"}'),
+ (4232, 1001, 3003, 4231, '/parent-206[@key="A"]/child-206', '{}'),
+ (4233, 1001, 3003, null, '/parent-206[@key="B"]', '{"key": "B"}'); \ No newline at end of file
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index bfc3931bc..9c7031e2f 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
index 1dccf49c9..6ae28fe9c 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
package org.onap.cps.api;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.spi.CascadeDeleteAllowed;
@@ -48,16 +47,14 @@ public interface CpsModuleService {
/**
* Create a schema set from new modules and existing modules.
- *
- * @param dataspaceName Dataspace name
- * @param schemaSetName schema set name
- * @param newYangResourcesModuleNameToContentMap YANG resources map where key is a module name and value is content
- * @param moduleReferences List of YANG resources module references of the modules
- * needed for this handle that are already in CPS
+ * @param dataspaceName Dataspace name
+ * @param schemaSetName schema set name
+ * @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
+ * @param moduleReferences List of YANG resources module references of the modules
*/
void createSchemaSetFromModules(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull Map<String, String> newYangResourcesModuleNameToContentMap,
- @NonNull List<ModuleReference> moduleReferences);
+ @NonNull Map<String, String> newModuleNameToContentMap,
+ Collection<ModuleReference> moduleReferences);
/**
* Read schema set in the given dataspace.
@@ -96,4 +93,14 @@ public interface CpsModuleService {
* @return a list of ModuleReference objects
*/
Collection<ModuleReference> getYangResourcesModuleReferences(String dataspaceName, String anchorName);
+
+ /**
+ * Identify previously unknown Yang Resource module references.
+ *
+ * @param moduleReferencesToCheck the moduleReferencesToCheck
+ * @returns collection of module references
+ */
+ Collection<ModuleReference> identifyNewModuleReferences(
+ Collection<ModuleReference> moduleReferencesToCheck);
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index ffcc5a22f..7267f22b5 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2021 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
@@ -23,7 +23,6 @@
package org.onap.cps.api.impl;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import org.onap.cps.api.CpsAdminService;
@@ -57,10 +56,10 @@ public class CpsModuleServiceImpl implements CpsModuleService {
@Override
public void createSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
- final Map<String, String> newYangResourcesModuleNameToContentMap,
- final List<ModuleReference> moduleReferences) {
+ final Map<String, String> newModuleNameToContentMap,
+ final Collection<ModuleReference> moduleReferences) {
cpsModulePersistenceService.storeSchemaSetFromModules(dataspaceName, schemaSetName,
- newYangResourcesModuleNameToContentMap, moduleReferences);
+ newModuleNameToContentMap, moduleReferences);
}
@@ -102,4 +101,11 @@ public class CpsModuleServiceImpl implements CpsModuleService {
private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
return CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED == cascadeDeleteAllowed;
}
+
+ @Override
+ public Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck) {
+ return cpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck);
+ }
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
index e08273441..4306df78d 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,6 @@
package org.onap.cps.spi;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import org.onap.cps.spi.model.ModuleReference;
@@ -45,11 +44,11 @@ public interface CpsModulePersistenceService {
*
* @param dataspaceName Dataspace name
* @param schemaSetName Schema set name
- * @param newYangResourcesModuleNameToContentMap YANG resources map where key is a module name and value is content
+ * @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
* @param moduleReferences List of YANG resources module references
*/
void storeSchemaSetFromModules(String dataspaceName, String schemaSetName,
- Map<String, String> newYangResourcesModuleNameToContentMap, List<ModuleReference> moduleReferences);
+ Map<String, String> newModuleNameToContentMap, Collection<ModuleReference> moduleReferences);
/**
* Deletes Schema Set.
@@ -98,4 +97,14 @@ public interface CpsModulePersistenceService {
* Remove unused Yang Resource Modules.
*/
void deleteUnusedYangResourceModules();
+
+ /**
+ * Identify new module references from those returned by a node compared to what is in CPS already.
+ *
+ * @param moduleReferencesToCheck the module references ot check
+ * @returns Collection of {@link ModuleReference} of previously unknown module references
+ */
+ Collection<ModuleReference> identifyNewModuleReferences(
+ Collection<ModuleReference> moduleReferencesToCheck);
+
}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
index 67dce1daf..afd8e8666 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2021 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2020-2022 Bell Canada.
* ================================================================================
@@ -37,11 +37,11 @@ import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED
class CpsModuleServiceImplSpec extends Specification {
- def mockModuleStoreService = Mock(CpsModulePersistenceService)
+ def mockCpsModulePersistenceService = Mock(CpsModulePersistenceService)
def mockCpsAdminService = Mock(CpsAdminService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
- def objectUnderTest = new CpsModuleServiceImpl(mockModuleStoreService, mockYangTextSchemaSourceSetCache, mockCpsAdminService)
+ def objectUnderTest = new CpsModuleServiceImpl(mockCpsModulePersistenceService, mockYangTextSchemaSourceSetCache, mockCpsAdminService)
def 'Create schema set.'() {
given: 'Valid yang resource as name-to-content map'
@@ -49,7 +49,7 @@ class CpsModuleServiceImplSpec extends Specification {
when: 'Create schema set method is invoked'
objectUnderTest.createSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap)
then: 'Parameters are validated and processing is delegated to persistence service'
- 1 * mockModuleStoreService.storeSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap)
+ 1 * mockCpsModulePersistenceService.storeSchemaSet('someDataspace', 'someSchemaSet', yangResourcesNameToContentMap)
}
def 'Create schema set from new modules and existing modules.'() {
@@ -59,8 +59,7 @@ class CpsModuleServiceImplSpec extends Specification {
when: 'create schema set from modules method is invoked'
objectUnderTest.createSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference)
then: 'processing is delegated to persistence service'
- 1 * mockModuleStoreService.storeSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference)
-
+ 1 * mockCpsModulePersistenceService.storeSchemaSetFromModules("someDataspaceName", "someSchemaSetName", [newModule: "newContent"], listOfExistingModulesModuleReference)
}
def 'Create schema set from invalid resources'() {
@@ -94,11 +93,11 @@ class CpsModuleServiceImplSpec extends Specification {
then: 'anchor deletion is called #numberOfAnchors times'
numberOfAnchors * mockCpsAdminService.deleteAnchor('my-dataspace', _)
and: 'persistence service method is invoked with same parameters'
- 1 * mockModuleStoreService.deleteSchemaSet('my-dataspace', 'my-schemaset')
+ 1 * mockCpsModulePersistenceService.deleteSchemaSet('my-dataspace', 'my-schemaset')
and: 'schema set will be removed from the cache'
1 * mockYangTextSchemaSourceSetCache.removeFromCache('my-dataspace', 'my-schemaset')
and: 'orphan yang resources are deleted'
- 1 * mockModuleStoreService.deleteUnusedYangResourceModules()
+ 1 * mockCpsModulePersistenceService.deleteUnusedYangResourceModules()
where: 'following parameters are used'
numberOfAnchors << [0, 3]
}
@@ -111,11 +110,11 @@ class CpsModuleServiceImplSpec extends Specification {
then: 'no anchors are deleted'
0 * mockCpsAdminService.deleteAnchor(_, _)
and: 'persistence service method is invoked with same parameters'
- 1 * mockModuleStoreService.deleteSchemaSet('my-dataspace', 'my-schemaset')
+ 1 * mockCpsModulePersistenceService.deleteSchemaSet('my-dataspace', 'my-schemaset')
and: 'schema set will be removed from the cache'
1 * mockYangTextSchemaSourceSetCache.removeFromCache('my-dataspace', 'my-schemaset')
and: 'orphan yang resources are deleted'
- 1 * mockModuleStoreService.deleteUnusedYangResourceModules()
+ 1 * mockCpsModulePersistenceService.deleteUnusedYangResourceModules()
}
def 'Delete schema-set when cascade is prohibited and schema-set has anchors.'() {
@@ -136,7 +135,7 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Get all yang resources module references.'() {
given: 'an already present module reference'
def moduleReferences = [new ExtendedModuleReference()]
- mockModuleStoreService.getYangResourceModuleReferences('someDataspaceName') >> moduleReferences
+ mockCpsModulePersistenceService.getYangResourceModuleReferences('someDataspaceName') >> moduleReferences
expect: 'the list provided by persistence service is returned as result'
objectUnderTest.getYangResourceModuleReferences('someDataspaceName') == moduleReferences
}
@@ -145,8 +144,17 @@ class CpsModuleServiceImplSpec extends Specification {
def 'Get all yang resources module references for the given dataspace name and anchor name.'() {
given: 'the module store service service returns a list module references'
def moduleReferences = [new ModuleReference()]
- mockModuleStoreService.getYangResourceModuleReferences('someDataspaceName', 'someAnchorName') >> moduleReferences
+ mockCpsModulePersistenceService.getYangResourceModuleReferences('someDataspaceName', 'someAnchorName') >> moduleReferences
expect: 'the list provided by persistence service is returned as result'
objectUnderTest.getYangResourcesModuleReferences('someDataspaceName', 'someAnchorName') == moduleReferences
}
+
+ def 'Identifying new module references'(){
+ given: 'module references from cm handle'
+ def moduleReferencesToCheck = [new ModuleReference('some-module', 'some-revision')]
+ when: 'identifyNewModuleReferences is called'
+ objectUnderTest.identifyNewModuleReferences(moduleReferencesToCheck)
+ then: 'cps module persistence service is called with module references to check'
+ 1 * mockCpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck);
+ }
}
diff --git a/csit/tests/cps-model-sync/cps-model-sync.robot b/csit/tests/cps-model-sync/cps-model-sync.robot
index 0b9928bef..dfad94861 100644
--- a/csit/tests/cps-model-sync/cps-model-sync.robot
+++ b/csit/tests/cps-model-sync/cps-model-sync.robot
@@ -34,14 +34,47 @@ ${auth} Basic Y3BzdXNlcjpjcHNyMGNrcyE=
${ncmpInventoryBasePath} /ncmpInventory
${ncmpBasePath} /ncmp
${dmiUrl} http://${DMI_HOST}:${DMI_PORT}
-${jsonData} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":null,"dmiModelPlugin":null,"createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}],"updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
+${jsonDataCreate} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Sci-Fi Book"},"publicCmHandleProperties":{"Contact":"storeemail@bookstore.com"}}]}
+${jsonDataUpdate} {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","updatedCmHandles":[{"cmHandle":"PNFDemo","cmHandleProperties":{"Book1":"Romance Book"},"publicCmHandleProperties":{"Contact":"newemailforstore@bookstore.com"}}]}
*** Test Cases ***
-Register node, update data node and sync modules.
+Register data node and sync modules.
${uri}= Set Variable ${ncmpInventoryBasePath}/v1/ch
${headers}= Create Dictionary Content-Type=application/json Authorization=${auth}
- ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonData}
- Should Be Equal As Strings ${response.status_code} 201
+ ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonDataCreate}
+ Should Be Equal As Strings ${response.status_code} 204
+
+Get CM Handle details and confirm it has been registered.
+ ${uri}= Set Variable ${ncmpBasePath}/v1/ch/PNFDemo
+ ${headers}= Create Dictionary Authorization=${auth}
+ ${response}= GET On Session CPS_URL ${uri} headers=${headers}
+ ${responseJson}= Set Variable ${response.json()}
+ ${schemaCount}= Get length ${responseJson}
+ Should Be Equal As Strings ${response.status_code} 200
+ IF "${responseJson['cmHandle']}" == "PNFDemo"
+ FOR ${item} IN @{responseJson['publicCmHandleProperties']}
+ Should Be Equal As Strings "${item['Contact']}" "storeemail@bookstore.com"
+ END
+ END
+
+Update data node and sync modules.
+ ${uri}= Set Variable ${ncmpInventoryBasePath}/v1/ch
+ ${headers}= Create Dictionary Content-Type=application/json Authorization=${auth}
+ ${response}= POST On Session CPS_URL ${uri} headers=${headers} data=${jsonDataUpdate}
+ Should Be Equal As Strings ${response.status_code} 204
+
+Get CM Handle details and confirm it has been updated.
+ ${uri}= Set Variable ${ncmpBasePath}/v1/ch/PNFDemo
+ ${headers}= Create Dictionary Authorization=${auth}
+ ${response}= GET On Session CPS_URL ${uri} headers=${headers}
+ ${responseJson}= Set Variable ${response.json()}
+ ${schemaCount}= Get length ${responseJson}
+ Should Be Equal As Strings ${response.status_code} 200
+ IF "${responseJson['cmHandle']}" == "PNFDemo"
+ FOR ${item} IN @{responseJson['publicCmHandleProperties']}
+ Should Be Equal As Strings "${item['Contact']}" "newemailforstore@bookstore.com"
+ END
+ END
Get modules for registered data node
${uri}= Set Variable ${ncmpBasePath}/v1/ch/PNFDemo/modules
diff --git a/docs/api/swagger/ncmp/openapi-inventory.yaml b/docs/api/swagger/ncmp/openapi-inventory.yaml
index 67eae41c4..154a4411d 100644
--- a/docs/api/swagger/ncmp/openapi-inventory.yaml
+++ b/docs/api/swagger/ncmp/openapi-inventory.yaml
@@ -20,8 +20,8 @@ paths:
$ref: '#/components/schemas/RestDmiPluginRegistration'
required: true
responses:
- "201":
- description: Created
+ "204":
+ description: No Content
content: {}
"400":
description: Bad Request
@@ -53,6 +53,16 @@ paths:
status: 403
message: Forbidden error message
details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
components:
schemas:
RestDmiPluginRegistration:
@@ -61,26 +71,39 @@ components:
dmiPlugin:
type: string
example: my-dmi-plugin
+ default: ""
dmiDataPlugin:
type: string
example: my-dmi-data-plugin
+ default: ""
dmiModelPlugin:
type: string
example: my-dmi-model-plugin
+ default: ""
createdCmHandles:
type: array
items:
- $ref: '#/components/schemas/RestCmHandle'
+ $ref: '#/components/schemas/RestInputCmHandle'
updatedCmHandles:
type: array
+ example:
+ cmHandle: my-cm-handle
+ cmHandleProperties:
+ add-my-property: add-property
+ update-my-property: updated-property
+ delete-my-property: ~
+ publicCmHandleProperties:
+ add-my-property: add-property
+ update-my-property: updated-property
+ delete-my-property: ~
items:
- $ref: '#/components/schemas/RestCmHandle'
+ $ref: '#/components/schemas/RestInputCmHandle'
removedCmHandles:
type: array
items:
type: string
example: "[\"my-cm-handle1\",\"my-cm-handle2\",\"my-cm-handle3\"]"
- RestCmHandle:
+ RestInputCmHandle:
required:
- cmHandle
type: object
diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml
index a3b9dc750..b7a65632e 100644
--- a/docs/api/swagger/ncmp/openapi.yaml
+++ b/docs/api/swagger/ncmp/openapi.yaml
@@ -4,73 +4,72 @@ info:
description: NCMP to CPS Proxy API
version: "1.0"
servers:
- - url: /ncmp
+- url: /ncmp
paths:
/v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
get:
tags:
- - network-cm-proxy
+ - network-cm-proxy
summary: Get resource data from pass-through operational for cm handle
description: Get resource data from pass-through operational for given cm handle
operationId: getResourceDataOperationalForCmHandle
parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
\ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: resourceIdentifier
- in: query
- description: The format of resource identifier depend on the associated DMI
- Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
- it can really be anything.
- required: true
- allowReserved: true
- schema:
- type: string
- examples:
- sample1:
- value:
- resourceIdentifier: \parent\child
- sample2:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]"
- sample3:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
- sample4:
- value:
- resourceIdentifier: "parent=1,child=abc"
- - name: Accept
- in: header
- description: "Accept parameter for response, if accept parameter is null,\
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Accept
+ in: header
+ description: "Accept parameter for response, if accept parameter is null,\
\ that means client can accept any format."
- required: false
- schema:
- type: string
- enum:
- - application/json
- - application/yang-data+json
- - name: options
- in: query
- description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
- \ in parenthesis'()'."
- required: false
- allowReserved: true
- schema:
- type: string
- examples:
- sample1:
- value:
- options: "(key1=value1,key2=value2)"
- sample2:
- value:
- options: "(key1=value1,key2=value1/value2)"
- sample3:
- value:
- options: "(key1=10,key2=value2,key3=[val31;val32])"
+ required: false
+ schema:
+ type: string
+ enum:
+ - application/json
+ - application/yang-data+json
+ - name: options
+ in: query
+ description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
+ \ in parenthesis'()'. The format of options parameter depend on the associated\
+ \ DMI Plugin implementation."
+ required: false
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ options: (depth=3)
+ sample 2:
+ value:
+ options: (fields=book)
+ sample 3:
+ value:
+ options: "(depth=2,fields=book/authors)"
responses:
"200":
description: OK
@@ -78,95 +77,113 @@ paths:
application/json:
schema:
type: object
+ examples:
+ dataSampleResponse:
+ $ref: '#/components/examples/dataSampleResponse'
"400":
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
"403":
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
/v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running:
get:
tags:
- - network-cm-proxy
+ - network-cm-proxy
summary: Get resource data from pass-through running for cm handle
description: Get resource data from pass-through running for given cm handle
operationId: getResourceDataRunningForCmHandle
parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
\ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: resourceIdentifier
- in: query
- description: The format of resource identifier depend on the associated DMI
- Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
- it can really be anything.
- required: true
- allowReserved: true
- schema:
- type: string
- examples:
- sample1:
- value:
- resourceIdentifier: \parent\child
- sample2:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]"
- sample3:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
- sample4:
- value:
- resourceIdentifier: "parent=1,child=abc"
- - name: Accept
- in: header
- description: "Accept parameter for response, if accept parameter is null,\
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Accept
+ in: header
+ description: "Accept parameter for response, if accept parameter is null,\
\ that means client can accept any format."
- required: false
- schema:
- type: string
- enum:
- - application/json
- - application/yang-data+json
- - name: options
- in: query
- description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
- \ in parenthesis'()'."
- required: false
- allowReserved: true
- schema:
- type: string
- examples:
- sample1:
- value:
- options: "(key1=value1,key2=value2)"
- sample2:
- value:
- options: "(key1=value1,key2=value1/value2)"
- sample3:
- value:
- options: "(key1=10,key2=value2,key3=[val31;val32])"
+ required: false
+ schema:
+ type: string
+ enum:
+ - application/json
+ - application/yang-data+json
+ - name: options
+ in: query
+ description: "options parameter in query, it is mandatory to wrap key(s)=value(s)\
+ \ in parenthesis'()'. The format of options parameter depend on the associated\
+ \ DMI Plugin implementation."
+ required: false
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ options: (depth=3)
+ sample 2:
+ value:
+ options: (fields=book)
+ sample 3:
+ value:
+ options: "(depth=2,fields=book/authors)"
responses:
"200":
description: OK
@@ -174,82 +191,212 @@ paths:
application/json:
schema:
type: object
+ examples:
+ dataSampleResponse:
+ $ref: '#/components/examples/dataSampleResponse'
"400":
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
"403":
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ put:
+ tags:
+ - network-cm-proxy
+ summary: Update resource data from pass-through running for a cm handle
+ description: Update resource data from pass-through running for the given cm
+ handle
+ operationId: updateResourceDataRunningForCmHandle
+ parameters:
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
+ \ or any other cm object by managed Network CM Proxy"
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Content-Type
+ in: header
+ description: "Content parameter for request, if content parameter is null,\
+ \ default value is application/json."
+ required: false
+ schema:
+ type: string
+ example: application/yang-data+json
+ default: application/json
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ examples:
+ dataSampleRequest:
+ $ref: '#/components/examples/dataSampleRequest'
+ application/yang-data+json:
+ schema:
+ type: object
+ examples:
+ dataSampleRequest:
+ $ref: '#/components/examples/dataSampleRequest'
+ required: true
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
+ "401":
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
post:
tags:
- - network-cm-proxy
+ - network-cm-proxy
summary: create resource data from pass-through running for cm handle
description: create resource data from pass-through running for given cm handle
operationId: createResourceDataRunningForCmHandle
parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
\ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: resourceIdentifier
- in: query
- description: The format of resource identifier depend on the associated DMI
- Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
- it can really be anything.
- required: true
- allowReserved: true
- schema:
- type: string
- examples:
- sample1:
- value:
- resourceIdentifier: \parent\child
- sample2:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]"
- sample3:
- value:
- resourceIdentifier: "\\parent\\listElement[key=value]\\grandChild"
- sample4:
- value:
- resourceIdentifier: "parent=1,child=abc"
- - name: Content-Type
- in: header
- description: "Content parameter for request, if content parameter is null,\
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Content-Type
+ in: header
+ description: "Content parameter for request, if content parameter is null,\
\ default value is application/json."
- required: false
- schema:
- type: string
- default: application/json
+ required: false
+ schema:
+ type: string
+ example: application/yang-data+json
+ default: application/json
requestBody:
content:
application/json:
schema:
- type: string
+ type: object
+ examples:
+ dataSampleRequest:
+ $ref: '#/components/examples/dataSampleRequest'
application/yang-data+json:
schema:
- type: string
+ type: object
+ examples:
+ dataSampleRequest:
+ $ref: '#/components/examples/dataSampleRequest'
required: true
responses:
"201":
@@ -261,71 +408,437 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
+ "401":
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ delete:
+ tags:
+ - network-cm-proxy
+ summary: Delete resource data
+ description: Delete resource data from pass-through running for a given cm handle
+ operationId: deleteResourceDataRunningForCmHandle
+ parameters:
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
+ \ or any other cm object by managed Network CM Proxy"
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Content-Type
+ in: header
+ description: "Content parameter for request, if content parameter is null,\
+ \ default value is application/json."
+ required: false
+ schema:
+ type: string
+ example: application/yang-data+json
+ default: application/json
+ responses:
+ "204":
+ description: No Content
+ content: {}
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
"403":
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
"404":
description: The specified resource was not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400
+ message: Not found error message
+ details: Not found error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ patch:
+ tags:
+ - network-cm-proxy
+ summary: Patch resource data from pass-through running
+ description: Patch resource data from pass-through running for the given cm
+ handle
+ operationId: patchResourceDataRunningForCmHandle
+ parameters:
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
+ \ or any other cm object by managed Network CM Proxy"
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ - name: resourceIdentifier
+ in: query
+ description: The format of resource identifier depend on the associated DMI
+ Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but
+ it can really be anything.
+ required: true
+ allowReserved: true
+ schema:
+ type: string
+ examples:
+ sample 1:
+ value:
+ resourceIdentifier: \shops\bookstore
+ sample 2:
+ value:
+ resourceIdentifier: "\\shops\\bookstore\\categories[@code=1]"
+ sample 3:
+ value:
+ resourceIdentifier: "parent=shops,child=bookstore"
+ - name: Content-Type
+ in: header
+ description: "Content parameter for request, if content parameter is null,\
+ \ default value is application/json."
+ required: false
+ schema:
+ type: string
+ example: application/yang-data+json
+ default: application/json
+ requestBody:
+ content:
+ '*/*':
+ schema:
+ type: object
+ examples:
+ dataSampleRequest:
+ $ref: '#/components/examples/dataSamplePatchRequest'
+ required: true
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
+ "401":
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
/v1/ch/{cm-handle}/modules:
get:
tags:
- - network-cm-proxy
+ - network-cm-proxy
summary: Fetch all module references (name and revision) for a given cm handle
description: fetch all module references (name and revision) for a given cm
handle
operationId: getModuleReferencesByCmHandle
parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
\ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
responses:
"200":
description: OK
content:
application/json:
schema:
- type: object
+ type: array
+ items:
+ $ref: '#/components/schemas/ModuleReference'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
+ "401":
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ /v1/ch/searches:
+ post:
+ tags:
+ - network-cm-proxy
+ summary: Execute cm handle search using the available conditions
+ description: Execute cm handle searches using 'hasAllModules' condition to get
+ all cm handles for the given module names
+ operationId: executeCmHandleSearch
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Conditions'
+ required: true
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CmHandles'
+ "400":
+ description: Bad Request
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
+ "401":
+ description: Unauthorized
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
+ "403":
+ description: Forbidden
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ /v1/ch/{cm-handle}:
+ get:
+ tags:
+ - network-cm-proxy
+ summary: Retrieve CM handle details
+ description: Retrieve CM handle details and properties by cm handle id
+ operationId: retrieveCmHandleDetailsById
+ parameters:
+ - name: cm-handle
+ in: path
+ description: "The identifier for a network function, network element, subnetwork\
+ \ or any other cm object by managed Network CM Proxy"
+ required: true
+ schema:
+ type: string
+ example: my-cm-handle
+ responses:
+ "200":
+ description: OK
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RestOutputCmHandle'
"400":
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400 BAD_REQUEST
+ message: Bad request error message
+ details: Bad request error details
"401":
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 401
+ message: Unauthorized error message
+ details: Unauthorized error details
"403":
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 403
+ message: Forbidden error message
+ details: Forbidden error details
"404":
description: The specified resource was not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 400
+ message: Not found error message
+ details: Not found error details
+ "500":
+ description: Internal Server Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
components:
schemas:
ErrorMessage:
@@ -338,3 +851,147 @@ components:
type: string
details:
type: string
+ ModuleReference:
+ title: Module reference details
+ type: object
+ properties:
+ moduleName:
+ type: string
+ example: my-module-name
+ revision:
+ type: string
+ example: my-module-revision
+ Conditions:
+ type: object
+ properties:
+ conditions:
+ $ref: '#/components/schemas/ConditionsData'
+ ConditionsData:
+ type: array
+ items:
+ $ref: '#/components/schemas/ConditionProperties'
+ ConditionProperties:
+ properties:
+ name:
+ type: string
+ example: hasAllModules
+ conditionParameters:
+ $ref: '#/components/schemas/ModuleNamesAsJsonArray'
+ ModuleNamesAsJsonArray:
+ type: array
+ items:
+ $ref: '#/components/schemas/ModuleNameAsJsonObject'
+ ModuleNameAsJsonObject:
+ properties:
+ moduleName:
+ type: string
+ example: my-module
+ CmHandles:
+ type: object
+ properties:
+ cmHandles:
+ $ref: '#/components/schemas/CmHandleProperties'
+ CmHandleProperties:
+ type: array
+ items:
+ $ref: '#/components/schemas/CmHandleProperty'
+ CmHandleProperty:
+ properties:
+ cmHandleId:
+ type: string
+ example: my-cm-handle-id
+ RestOutputCmHandle:
+ title: CM handle Details
+ type: object
+ properties:
+ cmHandle:
+ type: string
+ example: my-cm-handle1
+ publicCmHandleProperties:
+ $ref: '#/components/schemas/CmHandlePublicProperties'
+ CmHandlePublicProperties:
+ type: array
+ items:
+ type: object
+ additionalProperties:
+ type: string
+ example: Book Type
+ examples:
+ dataSampleResponse:
+ summary: Sample response
+ description: Sample response for selecting 'sample 1'.
+ value:
+ bookstore:
+ categories:
+ - code: "01"
+ books:
+ - authors:
+ - Iain M. Banks
+ - Ursula K. Le Guin
+ name: SciFi
+ - code: "02"
+ books:
+ - authors:
+ - Philip Pullman
+ name: kids
+ dataSampleRequest:
+ summary: Sample request
+ description: Sample request body
+ value:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: "01"
+ name: SciFi
+ books:
+ - authors:
+ - Iain M. Banks
+ - Ursula K. Le Guin
+ - code: "02"
+ name: kids
+ books:
+ - authors:
+ - Philip Pullman
+ dataSamplePatchRequest:
+ summary: Sample patch request
+ description: Sample patch request body
+ value:
+ ietf-restconf:yang-patch:
+ patch-id: patch-1
+ edit:
+ - edit-id: edit1
+ operation: merge
+ target: /
+ value:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: "01"
+ name: Science
+ books:
+ - authors:
+ - Author1
+ - Author2
+ - code: "02"
+ name: Arts
+ books:
+ - authors:
+ - Author3
+ - edit-id: edit2
+ operation: merge
+ target: /
+ value:
+ test:bookstore:
+ bookstore-name: Novels
+ categories:
+ - code: "03"
+ name: History
+ books:
+ - authors:
+ - Iain M. Banks
+ - Ursula K. Le Guin
+ - code: "04"
+ name: Fiction
+ books:
+ - authors:
+ - Philip Pullman
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index c7d5d39e6..0ca0547fa 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. Copyright (C) 2021 Nordix Foundation
+.. Copyright (C) 2021-2022 Nordix Foundation
.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING
.. _release_notes:
@@ -19,7 +19,7 @@ CPS Release Notes
.. * * * JAKARTA * * *
.. ========================
-Version: 2.1.0-SNAPSHOT
+Version: 3.0.0-SNAPSHOT
=======================
This section lists the main changes & fixes merged into master (snapshot) version of CPS-NCMP. This information is here to assist developers that want experiment/test using our latest code bases directly. Stability of this is not guaranteed.
@@ -29,9 +29,12 @@ Features
- `CPS-559 <https://jira.onap.org/browse/CPS-559>`_ Define response objects (schemas) in cps-ncmp
- `CPS-636 <https://jira.onap.org/browse/CPS-636>`_ Update operation for datastore pass through running
- `CPS-638 <https://jira.onap.org/browse/CPS-638>`_ Delete operation for datastore pass through running
+ - `CPS-677 <https://jira.onap.org/browse/CPS-677>`_ Support 'public' Cm Handle Properties
- `CPS-741 <https://jira.onap.org/browse/CPS-741>`_ Re sync after removing cm handles
- `CPS-777 <https://jira.onap.org/browse/CPS-777>`_ Ensure all DMI operations use POST method
- `CPS-780 <https://jira.onap.org/browse/CPS-780>`_ Add examples for parameters, request and response in openapi yaml for cps-core
+ - `CPS-817 <https://jira.onap.org/browse/CPS-817>`_ Create Endpoint For Get Cm Handles (incl. public properties) By Name
+ - `CPS-837 <https://jira.onap.org/browse/CPS-837>`_ Add Remove and Update properties (DMI and Public) as part of CM Handle Registration update
Bug Fixes
---------
@@ -40,15 +43,21 @@ Bug Fixes
- `CPS-788 <https://jira.onap.org/browse/CPS-788>`_ Yang Resource formatting is incorrect
- `CPS-783 <https://jira.onap.org/browse/CPS-783>`_ Remove cm handle does not completely remove all cm handle information
- `CPS-841 <https://jira.onap.org/browse/CPS-841>`_ Upgrade log4j to 2.17.1 as recommended by ONAP SECCOM
- - `CPS-867 <https://jira.onap.org/browse/CPS-867>`_ Database port made configurable through env variable DB_PORT
- `CPS-856 <https://jira.onap.org/browse/CPS-856>`_ Retry mechanism not working for concurrent CmHandle registration
+ - `CPS-867 <https://jira.onap.org/browse/CPS-867>`_ Database port made configurable through env variable DB_PORT
+ - `CPS-886 <https://jira.onap.org/browse/CPS-886>`_ Fragment handling decreasing performance for large number of cmHandles
+ - `CPS-887 <https://jira.onap.org/browse/CPS-887>`_ Increase performance of cmHandle registration for large number of schema sets in DB
+ - `CPS-892 <https://jira.onap.org/browse/CPS-892>`_ Fixed the response code during CM-Handle Registration from 201 CREATED to 204 NO_CONTENT
+ - `CPS-893 <https://jira.onap.org/browse/CPS-893>`_ NCMP Java API depends on NCM-Rest-API (cyclic) through json properties on Java API
Known Limitations, Issues and Workarounds
-----------------------------------------
*System Limitations*
-None
+Null can no longer be passed within the dmi plugin service names when registering a cm handle, as part of
+`CPS-837 <https://jira.onap.org/browse/CPS-837>`_ null is now used to indicate if a property should be removed as part
+of cm handle registration.
*Known Vulnerabilities*
@@ -56,7 +65,8 @@ None
*Workarounds*
-None
+Instead of passing null as a value within the dmi plugin service names, remove them from the request completely, or
+pass an empty string as the value if you do not want to include names for these values.
Security Notes
--------------
diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml
index 25a0bfec8..6c2729cc9 100644
--- a/jacoco-report/pom.xml
+++ b/jacoco-report/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/pom.xml b/pom.xml
index c7d622692..87398bd24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
<groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml
index 028cd4955..50cef487e 100644
--- a/spotbugs/pom.xml
+++ b/spotbugs/pom.xml
@@ -25,7 +25,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.cps</groupId>
<artifactId>spotbugs</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<properties>
<nexusproxy>https://nexus.onap.org</nexusproxy>
diff --git a/version.properties b/version.properties
index 07ef49adb..17f2daa6c 100755
--- a/version.properties
+++ b/version.properties
@@ -1,5 +1,6 @@
# ============LICENSE_START=======================================================
# Copyright (C) 2021 Nordix Foundation
+# Modifications Copyright (C) 2022 Bell Canada.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,8 +20,8 @@
# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
# because they are used in Jenkins, whose plug-in doesn't support this
-major=2
-minor=1
+major=3
+minor=0
patch=0
base_version=${major}.${minor}.${patch}