diff options
48 files changed, 2154 insertions, 737 deletions
diff --git a/checkstyle/pom.xml b/checkstyle/pom.xml index 9a5eea5d03..2843c11b25 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <properties> <nexusproxy>https://nexus.onap.org</nexusproxy> diff --git a/cps-application/pom.xml b/cps-application/pom.xml index 7ca50dca21..9c6945a5fe 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> @@ -37,7 +37,7 @@ <app>org.onap.cps.Application</app> <jib-maven-plugin.version>2.8.0</jib-maven-plugin.version> <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format> - <minimum-coverage>0.7</minimum-coverage> + <minimum-coverage>0.82</minimum-coverage> <base.image>${docker.pull.registry}/onap/integration-java11:8.0.0</base.image> <image.tag>${project.version}-${maven.build.timestamp}</image.tag> </properties> diff --git a/cps-bom/pom.xml b/cps-bom/pom.xml index 2a729024cd..148b14508d 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <packaging>pom</packaging> <description>This artifact contains dependencyManagement declarations of all published CPS components.</description> diff --git a/cps-dependencies/pom.xml b/cps-dependencies/pom.xml index d8f46ccba1..348244de37 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>${project.groupId}:${project.artifactId}</name> diff --git a/cps-events/pom.xml b/cps-events/pom.xml index e952220eb9..6f51479bb0 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> @@ -62,16 +62,7 @@ <serializable>true</serializable> </configuration> </plugin> - <plugin> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <configuration> - <excludes> - <exclude>org/onap/cps/event/model/*</exclude> - </excludes> - </configuration> - </plugin> </plugins> </build> -</project>
\ No newline at end of file +</project> diff --git a/cps-ncmp-rest/docs/openapi/ncmproxy.yml b/cps-ncmp-rest/docs/openapi/ncmproxy.yml index 5e2957f340..2e5eba754d 100755 --- a/cps-ncmp-rest/docs/openapi/ncmproxy.yml +++ b/cps-ncmp-rest/docs/openapi/ncmproxy.yml @@ -266,10 +266,10 @@ resourceDataForPassthroughRunning: content: application/json: schema: - type: object + type: string application/yang-data+json: schema: - type: object + type: string responses: 201: $ref: 'components.yaml#/components/responses/Created' diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml index c243983309..2c44c24807 100644 --- a/cps-ncmp-rest/pom.xml +++ b/cps-ncmp-rest/pom.xml @@ -27,139 +27,139 @@ <parent> <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>2.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> <artifactId>cps-ncmp-rest</artifactId> -<properties> - <minimum-coverage>0.5</minimum-coverage> -</properties> + <properties> + <minimum-coverage>0.95</minimum-coverage> + </properties> -<dependencies> - <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>cps-ncmp-service</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - <exclusions> - <exclusion> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-tomcat</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-jetty</artifactId> - </dependency> - <dependency> - <groupId>io.swagger.core.v3</groupId> - <artifactId>swagger-annotations</artifactId> - </dependency> - <!-- T E S T D E P E N D E N C I E S --> - <dependency> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.codehaus.groovy</groupId> - <artifactId>groovy-json</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.spockframework</groupId> - <artifactId>spock-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.spockframework</groupId> - <artifactId>spock-spring</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>cglib</groupId> - <artifactId>cglib-nodep</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>org.junit.vintage</groupId> - <artifactId>junit-vintage-engine</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - </dependency> -</dependencies> + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-ncmp-service</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-jetty</artifactId> + </dependency> + <dependency> + <groupId>io.swagger.core.v3</groupId> + <artifactId>swagger-annotations</artifactId> + </dependency> + <!-- T E S T D E P E N D E N C I E S --> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-json</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.spockframework</groupId> + <artifactId>spock-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.spockframework</groupId> + <artifactId>spock-spring</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib-nodep</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + </dependencies> -<build> - <plugins> - <!-- Swagger code generation. --> - <plugin> - <groupId>io.swagger.codegen.v3</groupId> - <artifactId>swagger-codegen-maven-plugin</artifactId> - <executions> - <execution> - <id>code-gen</id> - <goals> - <goal>generate</goal> - </goals> - <configuration> - <inputSpec>${project.basedir}/docs/openapi/openapi.yml</inputSpec> - <invokerPackage>org.onap.cps.ncmp.rest.controller</invokerPackage> - <modelPackage>org.onap.cps.ncmp.rest.model</modelPackage> - <apiPackage>org.onap.cps.ncmp.rest.api</apiPackage> - <language>spring</language> - <generateSupportingFiles>false</generateSupportingFiles> - <configOptions> - <sourceFolder>src/gen/java</sourceFolder> - <dateLibrary>java11</dateLibrary> - <interfaceOnly>true</interfaceOnly> - <useTags>true</useTags> - </configOptions> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <artifactId>maven-resources-plugin</artifactId> - <executions> - <execution> - <id>copy-resources</id> - <phase>compile</phase> - <goals> - <goal>copy-resources</goal> - </goals> - <configuration> - <outputDirectory>${project.basedir}/target/classes/static/api-docs/cps-ncmp</outputDirectory> - <resources> - <resource> - <directory>${project.basedir}/target/generated-sources/swagger/</directory> - <includes> - <include>openapi.yaml</include> - </includes> - </resource> - </resources> - </configuration> - </execution> - </executions> - </plugin> - </plugins> -</build> + <build> + <plugins> + <!-- Swagger code generation. --> + <plugin> + <groupId>io.swagger.codegen.v3</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <executions> + <execution> + <id>code-gen</id> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <inputSpec>${project.basedir}/docs/openapi/openapi.yml</inputSpec> + <invokerPackage>org.onap.cps.ncmp.rest.controller</invokerPackage> + <modelPackage>org.onap.cps.ncmp.rest.model</modelPackage> + <apiPackage>org.onap.cps.ncmp.rest.api</apiPackage> + <language>spring</language> + <generateSupportingFiles>false</generateSupportingFiles> + <configOptions> + <sourceFolder>src/gen/java</sourceFolder> + <dateLibrary>java11</dateLibrary> + <interfaceOnly>true</interfaceOnly> + <useTags>true</useTags> + </configOptions> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-resources</id> + <phase>compile</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${project.basedir}/target/classes/static/api-docs/cps-ncmp</outputDirectory> + <resources> + <resource> + <directory>${project.basedir}/target/generated-sources/swagger/</directory> + <includes> + <include>openapi.yaml</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> 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 b78241662e..a4d94cebfd 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 @@ -214,7 +214,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { @Override public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String cmHandle, final String resourceIdentifier, - final Object requestBody, + final String requestBody, final String contentType) { networkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, requestBody, contentType); 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 613243e28b..9f2b4e19a3 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 @@ -232,7 +232,7 @@ class NetworkCmProxyControllerSpec extends Specification { response.getContentAsString() == '{valid-json}' } - def 'Create Resource Data from pass-through running using POST.' () { + def 'Create Resource Data from pass-through running with #scenario.' () { given: 'resource data url' def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" + "/testResourceIdentifier" @@ -240,13 +240,17 @@ class NetworkCmProxyControllerSpec extends Specification { def response = mvc.perform( post(getUrl) .contentType(MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON_VALUE).content('{"some-json":"value"}') + .accept(MediaType.APPLICATION_JSON_VALUE).content(requestBody) ).andReturn().response then: 'ncmp service method to create resource called' 1 * mockNetworkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceIdentifier', ['some-json':'value'], 'application/json;charset=UTF-8') + 'testResourceIdentifier', requestBody, 'application/json;charset=UTF-8') and: 'resource is created' response.status == HttpStatus.CREATED.value() + where: 'given request body' + scenario | requestBody + 'body contains " and new line' | 'body with " quote and \n new line' + 'body contains normal string' | 'normal request body' } def 'Get module references for the given dataspace and cm handle.' () { diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml index 39ceeb7264..0ee81c784c 100644 --- a/cps-ncmp-service/pom.xml +++ b/cps-ncmp-service/pom.xml @@ -22,53 +22,53 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> -<modelVersion>4.0.0</modelVersion> -<parent> - <groupId>org.onap.cps</groupId> - <artifactId>cps-parent</artifactId> - <version>2.0.0-SNAPSHOT</version> - <relativePath>../cps-parent/pom.xml</relativePath> -</parent> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.cps</groupId> + <artifactId>cps-parent</artifactId> + <version>2.0.1-SNAPSHOT</version> + <relativePath>../cps-parent/pom.xml</relativePath> + </parent> -<artifactId>cps-ncmp-service</artifactId> + <artifactId>cps-ncmp-service</artifactId> -<properties> - <minimum-coverage>0.7</minimum-coverage> -</properties> + <properties> + <minimum-coverage>0.87</minimum-coverage> + </properties> -<dependencies> - <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>cps-service</artifactId> - </dependency> - <dependency> - <groupId>org.spockframework</groupId> - <artifactId>spock-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.spockframework</groupId> - <artifactId>spock-spring</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>org.junit.vintage</groupId> - <artifactId>junit-vintage-engine</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-web</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> - </dependency> -</dependencies> + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-service</artifactId> + </dependency> + <dependency> + <groupId>org.spockframework</groupId> + <artifactId>spock-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.spockframework</groupId> + <artifactId>spock-spring</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + </dependencies> </project> 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 60669b9169..2f91ed30e1 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 @@ -153,7 +153,7 @@ public interface NetworkCmProxyDataService { */ void createResourceDataPassThroughRunningForCmHandle(@NotNull String cmHandle, @NotNull String resourceIdentifier, - @NotNull Object requestBody, + @NotNull String requestBody, String contentType); /** diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/JsonUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/JsonUtils.java index 9ce32e3906..6768777e17 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/JsonUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/JsonUtils.java @@ -26,6 +26,9 @@ public class JsonUtils { private static final String NEW_LINE = "\n"; private static final String QUOTE = "\""; + private JsonUtils() { + throw new IllegalStateException(); + } /** * Remove redundant beginning and end characters. 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 24203c0d7f..ff9502d501 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 @@ -76,6 +76,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private static final String NCMP_DMI_SERVICE_NAME = "dmi-service-name"; + private static final String REVISION = "revision"; + private CpsDataService cpsDataService; private ObjectMapper objectMapper; @@ -88,8 +90,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private CpsAdminService cpsAdminService; - public static final String NO_NAMESPACE = null; - /** * Constructor Injection for Dependencies. * @param dmiOperations DMI operation @@ -202,7 +202,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService @Override public void createResourceDataPassThroughRunningForCmHandle(final @NotNull String cmHandle, final @NotNull String resourceIdentifier, - final @NotNull Object requestBody, + final @NotNull String requestBody, final String contentType) { final var cmHandleDataNode = fetchDataNodeFromDmiRegistryForCmHandle(cmHandle); final var dmiServiceName = String.valueOf(cmHandleDataNode.getLeaves().get(NCMP_DMI_SERVICE_NAME)); @@ -279,11 +279,11 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private String getGenericRequestBody(final DataNode cmHandleDataNode) { final Collection<DataNode> cmHandlePropertiesList = cmHandleDataNode.getChildDataNodes(); final Map<String, String> cmHandlePropertiesMap = getCmHandlePropertiesAsMap(cmHandlePropertiesList); - final var requetBodyObject = GenericRequestBody.builder() + final var requestBodyObject = GenericRequestBody.builder() .operation(GenericRequestBody.OperationEnum.READ) .cmHandleProperties(cmHandlePropertiesMap) .build(); - return prepareOperationBody(requetBodyObject); + return prepareOperationBody(requestBodyObject); } private void parseAndUpdateCmHandlesInDmiRegistration(final DmiPluginRegistration dmiPluginRegistration) { @@ -299,10 +299,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry", cmHandlesJsonData, NO_TIMESTAMP); } catch (final JsonProcessingException e) { - log.error("Parsing error occurred while converting Object to JSON DMI Registry."); - throw new DataValidationException( - "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e - .getMessage(), e); + handleJsonProcessingException(dmiPluginRegistration, e); } } @@ -317,17 +314,21 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList); - registerAndSyncNode(dmiPluginRegistration, persistenceCmHandlesList, cmHandleJsonData); + registerAndSyncNode(persistenceCmHandlesList, cmHandleJsonData); } catch (final JsonProcessingException e) { - log.error("Parsing error occurred while converting Object to JSON for DMI Registry."); - throw new DataValidationException( - "Parsing error occurred while processing DMI Plugin Registration" + dmiPluginRegistration, e - .getMessage(), e); + handleJsonProcessingException(dmiPluginRegistration, e); } } - private void registerAndSyncNode(final DmiPluginRegistration dmiPluginRegistration, - final PersistenceCmHandlesList persistenceCmHandlesList, + private static void handleJsonProcessingException(final DmiPluginRegistration dmiPluginRegistration, + final JsonProcessingException e) { + final String message = "Parsing error occurred while processing DMI Plugin Registration" + + dmiPluginRegistration; + log.error(message); + throw new DataValidationException(message, e.getMessage(), e); + } + + private void registerAndSyncNode(final PersistenceCmHandlesList persistenceCmHandlesList, final String cmHandleJsonData) { cpsDataService.saveListNodeData(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry", cmHandleJsonData, NO_TIMESTAMP); @@ -390,7 +391,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService cpsAdminService.createAnchor(NF_PROXY_DATASPACE_NAME, cmHandle.getId(), cmHandle.getId()); } - private JsonObject getRequestBodyAsJson(final List<ModuleReference> unknownModuleReferences) { + private static JsonObject getRequestBodyAsJson(final List<ModuleReference> unknownModuleReferences) { final JsonObject requestBodyAsJson = new JsonObject(); requestBodyAsJson.addProperty("operation", "read"); @@ -404,13 +405,13 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return requestBodyAsJson; } - private JsonArray getModuleReferencesAsJson(final List<ModuleReference> unknownModuleReferences) { + private static JsonArray getModuleReferencesAsJson(final List<ModuleReference> unknownModuleReferences) { final JsonArray moduleReferences = new JsonArray(); for (final ModuleReference moduleReference : unknownModuleReferences) { final JsonObject moduleReferenceAsJson = new JsonObject(); moduleReferenceAsJson.addProperty("name", moduleReference.getModuleName()); - moduleReferenceAsJson.addProperty("revision", moduleReference.getRevision()); + moduleReferenceAsJson.addProperty(REVISION, moduleReference.getRevision()); moduleReferences.add(moduleReferenceAsJson); } return moduleReferences; @@ -444,7 +445,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return yangResource; } - private List<ModuleReference> getModuleReferences(final ResponseEntity<String> response) { + private static List<ModuleReference> getModuleReferences(final ResponseEntity<String> response) { final List<ModuleReference> modulesFromDmiForCmHandle = new ArrayList<>(); final JsonObject convertedObject = new Gson().fromJson(response.getBody(), JsonObject.class); final JsonArray moduleReferencesAsJson = convertedObject.getAsJsonArray("schemas"); @@ -456,7 +457,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return modulesFromDmiForCmHandle; } - private ModuleReference toModuleReference(final JsonObject moduleReferenceAsJson) { + private static ModuleReference toModuleReference(final JsonObject moduleReferenceAsJson) { final var moduleReference = new ModuleReference(); moduleReference.setModuleName(moduleReferenceAsJson.get("moduleName").getAsString()); moduleReference.setRevision(moduleReferenceAsJson.get("revision").getAsString()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java index a834bfcd90..c4e82d3290 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java @@ -41,7 +41,7 @@ public class NcmpConfiguration { } @Bean - public RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { + public static RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder.build(); } -}
\ No newline at end of file +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java index ff53464096..2c75b5d992 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/NcmpException.java @@ -43,17 +43,5 @@ public class NcmpException extends RuntimeException { this.details = details; } - /** - * Constructor. - * - * @param message the error message - * @param details the error details - * @param cause the cause of the exception - */ - public NcmpException(final String message, final String details, final Throwable cause) { - super(message, cause); - this.details = details; - } - } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java index 9ed78de6e7..4f6f0ef491 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/GenericRequestBody.java @@ -49,6 +49,6 @@ public class GenericRequestBody { private OperationEnum operation; private String dataType; - private Object data; + private String data; private Map<String, String> cmHandleProperties; } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/JsonUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/JsonUtilsSpec.groovy index 2b3d998645..be27dfad5d 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/JsonUtilsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/JsonUtilsSpec.groovy @@ -40,5 +40,12 @@ class JsonUtilsSpec extends Specification { 'a string in apostrophes' | "'abc'" || 'abc' 'a string inside any other tokens' | 'abcde' || 'bcd' } + + def 'Cannot use constructor.'() { + when: 'attempt to construct object' + new JsonUtils() + then: 'an exception is thrown' + thrown(IllegalStateException) + } } 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 3ebb4550c3..8739355c8b 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 @@ -36,6 +36,8 @@ import org.onap.cps.ncmp.api.models.DmiPluginRegistration import org.onap.cps.ncmp.api.models.PersistenceCmHandle import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.spi.FetchDescendantsOption +import org.onap.cps.spi.exceptions.DataNodeNotFoundException +import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.spi.model.DataNode import org.onap.cps.spi.model.ModuleReference import org.springframework.http.HttpStatus @@ -56,9 +58,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def mockCpsModuleService = Mock(CpsModuleService) def mockCpsAdminService = Mock(CpsAdminService) def mockDmiProperties = Mock(NcmpConfiguration.DmiProperties) + def spyObjectMapper = Spy(ObjectMapper) def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsModuleService, - mockCpsDataService, mockCpsQueryService, mockCpsAdminService, new ObjectMapper()) + mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper) def cmHandle = 'some handle' def noTimestamp = null @@ -154,12 +157,12 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'ncmp-dmi-registry', "/dmi-registry/cm-handles[@id='cmHandle001']", noTimestamp) where: - scenario | createdCmHandles | updatedCmHandles | removedCmHandles || expectedCallsToSaveNode | expectedCallsToUpdateNode | expectedCallsToDeleteListDataNode - 'create' | [persistenceCmHandle ] | [] | [] || 1 | 0 | 0 - 'update' | [] | [persistenceCmHandle ] | [] || 0 | 1 | 0 - 'delete' | [] | [] | cmHandlesArray || 0 | 0 | 1 - 'create, update and delete' | [persistenceCmHandle ] | [persistenceCmHandle ] | cmHandlesArray || 1 | 1 | 1 - + scenario | createdCmHandles | updatedCmHandles | removedCmHandles || expectedCallsToSaveNode | expectedCallsToUpdateNode | expectedCallsToDeleteListDataNode + 'create' | [persistenceCmHandle] | [] | [] || 1 | 0 | 0 + 'update' | [] | [persistenceCmHandle] | [] || 0 | 1 | 0 + 'delete' | [] | [] | cmHandlesArray || 0 | 0 | 1 + 'create, update and delete' | [persistenceCmHandle] | [persistenceCmHandle] | cmHandlesArray || 1 | 1 | 1 + 'no valid data' | null | null | null || 0 | 0 | 0 } def 'Register a DMI Plugin for the given cmHandle without additional properties.'() { @@ -169,7 +172,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { dmiPluginRegistration.dmiPlugin = 'my-server' persistenceCmHandle.cmHandleID = '123' persistenceCmHandle.cmHandleProperties = null - dmiPluginRegistration.createdCmHandles = [persistenceCmHandle ] + dmiPluginRegistration.createdCmHandles = [persistenceCmHandle] def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","additional-properties":[]}]}' when: 'registration is updated' objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) @@ -178,6 +181,37 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { '/dmi-registry', expectedJsonData, noTimestamp) } + def 'Register a DMI Plugin with JSON processing errors during #scenario.'() { + given: 'a registration without cmHandle properties ' + NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled() + def dmiPluginRegistration = new DmiPluginRegistration() + dmiPluginRegistration.createdCmHandles = createdCmHandles + dmiPluginRegistration.updatedCmHandles = updatedCmHandles + and: 'an JSON processing exception occurs' + spyObjectMapper.writeValueAsString(_) >> { throw (new JsonProcessingException('')) } + when: 'registration is updated' + 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 with no data found during delete.'() { + given: 'a registration without cmHandle properties ' + NetworkCmProxyDataServiceImpl objectUnderTest = getObjectUnderTestWithModelSyncDisabled() + def dmiPluginRegistration = new DmiPluginRegistration() + dmiPluginRegistration.removedCmHandles = ['some cm handle'] + and: 'an JSON processing exception occurs' + mockCpsDataService.deleteListNodeData(*_) >> { throw (new DataNodeNotFoundException('','')) } + when: 'registration is updated' + objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) + then: 'no exception is thrown' + noExceptionThrown() + } + def 'Get resource data for pass-through operational from dmi.'() { given: 'data node representing cmHandle and its properties' def cmHandleDataNode = getCmHandleDataNodeForTest() @@ -211,15 +245,16 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { and: 'objectMapper not able to parse object' def mockObjectMapper = Mock(ObjectMapper) objectUnderTest.objectMapper = mockObjectMapper - mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException("testException") } + mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('testException') } when: 'get resource data is called' def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle', 'testResourceId', 'testAcceptParam', 'testFieldQuery', 5) - then: 'exception is thrown' - thrown(NcmpException.class) + then: 'exception is thrown with the expected details' + def exceptionThrown = thrown(NcmpException.class) + exceptionThrown.details == 'testException' } def 'Get resource data for pass-through operational from dmi return NOK response.'() { @@ -244,7 +279,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'testFieldQuery', 5) then: 'exception is thrown' - thrown(NcmpException.class) + def exceptionThrown = thrown(NcmpException.class) + and: 'details contains the original response' + exceptionThrown.details.contains('NOK-json') } def 'Get resource data for pass-through running from dmi.'() { @@ -280,15 +317,16 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { and: 'objectMapper not able to parse object' def mockObjectMapper = Mock(ObjectMapper) objectUnderTest.objectMapper = mockObjectMapper - mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException("testException") } + mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('testException') } when: 'get resource data is called' def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle', 'testResourceId', 'testAcceptParam', 'testFieldQuery', 5) - then: 'exception is thrown' - thrown(NcmpException.class) + then: 'exception is thrown with the expected details' + def exceptionThrown = thrown(NcmpException.class) + exceptionThrown.details == 'testException' } def 'Get resource data for pass-through running from dmi return NOK response.'() { @@ -313,7 +351,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'testFieldQuery', 5) then: 'exception is thrown' - thrown(NcmpException.class) + def exceptionThrown = thrown(NcmpException.class) + and: 'details contains the original response' + exceptionThrown.details.contains('NOK-json') } def 'Write resource data for pass-through running from dmi using POST.'() { @@ -348,7 +388,9 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'testResourceId', '{some-json}', 'application/json') then: 'exception is thrown' - thrown(NcmpException.class) + def exceptionThrown = thrown(NcmpException.class) + and: 'details contains (not found) error code: 404' + exceptionThrown.details.contains('404') } def 'Sync model for a (new) cm handle with #scenario'() { @@ -373,6 +415,13 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 'no unknown module' | '[]' || [:] } + def 'Getting Yang Resources.'() { + when: 'yang resources is called' + objectUnderTest.getYangResourcesModuleReferences('some cm handle') + then: 'CPS module services is invoked for the correct dataspace and cm handle' + 1 * mockCpsModuleService.getYangResourcesModuleReferences('NFP-Operational','some cm handle') + } + def getModulesForCmHandle() { def jsonData = TestUtils.getResourceFileContent('cmHandleModules.json') mockDmiProperties.getAuthUsername() >> 'someUser' @@ -384,7 +433,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def getObjectUnderTestWithModelSyncDisabled() { def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsModuleService, - mockCpsDataService, mockCpsQueryService, mockCpsAdminService, new ObjectMapper())) + mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper)) objectUnderTest.createAnchorAndSyncModel(_) >> null return objectUnderTest } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy index 809c48a619..bf6179ba1b 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy @@ -21,24 +21,30 @@ package org.onap.cps.ncmp.api.impl.client import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration +import org.spockframework.spring.SpringBean +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders +import org.springframework.http.HttpMethod import org.springframework.http.ResponseEntity +import org.springframework.test.context.ContextConfiguration import org.springframework.web.client.RestTemplate import spock.lang.Specification -import org.springframework.http.HttpMethod +@SpringBootTest +@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiRestClient]) class DmiRestClientSpec extends Specification { - def mockDmiProperties = Mock(NcmpConfiguration.DmiProperties) - def mockRestTemplate = Mock(RestTemplate) - def objectUnderTest = new DmiRestClient(mockRestTemplate, mockDmiProperties) + @SpringBean + RestTemplate mockRestTemplate = Mock(RestTemplate) + + @Autowired + DmiRestClient objectUnderTest def 'DMI PUT operation.'() { given: 'a PUT url' def getResourceDataUrl = 'http://some-uri/getResourceDataUrl' - and: 'dmi properties' - setupTestConfigurationData() and: 'the rest template returns a valid response entity' def mockResponseEntity = Mock(ResponseEntity) mockRestTemplate.exchange(getResourceDataUrl, HttpMethod.PUT, _ as HttpEntity, Object.class) >> mockResponseEntity @@ -51,8 +57,6 @@ class DmiRestClientSpec extends Specification { def 'DMI POST operation.'() { given: 'a POST url' def getResourceDataUrl = 'http://some-uri/createResourceDataUrl' - and: 'dmi properties' - setupTestConfigurationData() and: 'the rest template returns a valid response entity' def mockResponseEntity = Mock(ResponseEntity) mockRestTemplate.postForEntity(getResourceDataUrl, _ as HttpEntity, String.class) >> mockResponseEntity @@ -62,8 +66,4 @@ class DmiRestClientSpec extends Specification { result == mockResponseEntity } - def setupTestConfigurationData() { - mockDmiProperties.authUsername >> 'some-username' - mockDmiProperties.authPassword >> 'some-password' - } -}
\ No newline at end of file +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy new file mode 100644 index 0000000000..dd4c1375b0 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/config/NcmpConfigurationSpec.groovy @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.cps.ncmp.api.impl.config + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.test.context.ContextConfiguration +import org.springframework.web.client.RestTemplate +import spock.lang.Specification + +@SpringBootTest +@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties]) +class NcmpConfigurationSpec extends Specification{ + + @Autowired + NcmpConfiguration.DmiProperties dmiProperties + + def 'DMI Properties.'() { + expect: 'properties are set to values in test configuration yaml file' + dmiProperties.authUsername == 'some-user' + dmiProperties.authPassword == 'some-password' + } + + def 'Rest Template creation.'() { + given: 'a rest template builder' + def mockRestTemplateBuilder = Mock(RestTemplateBuilder) + def expectedRestTemplate = Mock(RestTemplate) + mockRestTemplateBuilder.build() >> expectedRestTemplate + when: 'a rest template is created' + def result = NcmpConfiguration.restTemplate(mockRestTemplateBuilder) + then: 'the rest template from the builder is returned' + assert result == expectedRestTemplate + } +} 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/PersistenceCmHandleSpec.groovy new file mode 100644 index 0000000000..bfed795f76 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/PersistenceCmHandleSpec.groovy @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.models + +import spock.lang.Specification + +class PersistenceCmHandleSpec extends Specification { + + def objectUnderTest = new PersistenceCmHandle() + + def 'Setting and getting additional properties.'() { + given: 'a map of one property is added' + objectUnderTest.setAdditionalProperties([myProperty: 'some value']) + when: 'the additional properties are retrieved' + def result = objectUnderTest.getAdditionalProperties() + then: 'the result has the right size' + assert result.size() == 1 + and: 'the property in the result has the correct name and value' + def actualAdditionalProperty = result.get(0) + def expectedAdditionalProperty = new PersistenceCmHandle.AdditionalProperty('myProperty','some value') + assert actualAdditionalProperty.name == expectedAdditionalProperty.name + assert actualAdditionalProperty.value == expectedAdditionalProperty.value + } + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/moduleReferenceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/moduleReferenceSpec.groovy index 9f161a9e53..444a25804b 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/moduleReferenceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/moduleReferenceSpec.groovy @@ -1,3 +1,22 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.models import org.onap.cps.spi.model.ExtendedModuleReference diff --git a/cps-ncmp-service/src/test/resources/application.yml b/cps-ncmp-service/src/test/resources/application.yml new file mode 100644 index 0000000000..71ac2c9a03 --- /dev/null +++ b/cps-ncmp-service/src/test/resources/application.yml @@ -0,0 +1,23 @@ +# ============LICENSE_START======================================================= +# Copyright (C) 2021 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========================================================= + +dmi: + auth: + username: some-user + password: some-password + diff --git a/cps-parent/pom.xml b/cps-parent/pom.xml index bfb3a97523..3c2eab5e0f 100755 --- a/cps-parent/pom.xml +++ b/cps-parent/pom.xml @@ -32,30 +32,17 @@ <groupId>org.onap.cps</groupId> <artifactId>cps-parent</artifactId> - <version>2.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> <app>org.onap.cps.Application</app> <java.version>11</java.version> - <minimum-coverage>0.9</minimum-coverage> + <minimum-coverage>0.97</minimum-coverage> <jacoco.reportDirectory.aggregate>${project.reporting.outputDirectory}/jacoco-aggregate</jacoco.reportDirectory.aggregate> <sonar.coverage.jacoco.xmlReportPaths> - ../cps-ri/target/site/jacoco-ut/jacoco.xml, - ../cps-ri/target/site/jacoco-aggregate/jacoco.xml, - ../cps-service/target/site/jacoco-ut/jacoco.xml, - ../cps-service/target/site/jacoco-aggregate/jacoco.xml, - ../cps-rest/target/site/jacoco-ut/jacoco.xml, - ../cps-rest/target/site/jacoco-aggregate/jacoco.xml, - ../cps-ncmp-service/target/site/jacoco-ut/jacoco.xml, - ../cps-ncmp-service/target/site/jacoco-aggregate/jacoco.xml, - ../cps-ncmp-rest/target/site/jacoco-ut/jacoco.xml, - ../cps-ncmp-rest/target/site/jacoco-aggregate/jacoco.xml, - ../cps-path-parser/target/site/jacoco-ut/jacoco.xml, - ../cps-path-parser/target/site/jacoco-aggregate/jacoco.xml, - ../cps-application/target/site/jacoco-ut/jacoco.xml, - ../cps-application/target/site/jacoco-aggregate/jacoco.xml + ../jacoco-report/target/site/jacoco-aggregate/jacoco.xml </sonar.coverage.jacoco.xmlReportPaths> </properties> @@ -346,10 +333,10 @@ <artifactId>jacoco-maven-plugin</artifactId> <configuration> <excludes> + <exclude>org/onap/cps/event/model/*</exclude> <exclude>org/onap/cps/rest/model/*</exclude> <exclude>org/onap/cps/cpspath/parser/antlr4/*</exclude> <exclude>org/onap/cps/ncmp/rest/model/*</exclude> - <exclude>org/onap/cps/ncmp/api/models/*</exclude> </excludes> </configuration> <executions> @@ -380,18 +367,6 @@ </rules> </configuration> </execution> - <execution> - <id>report</id> - <goals> - <goal>report-aggregate</goal> - </goals> - <phase>verify</phase> - <configuration> - <dataFileIncludes> - <fileInclude>**/code-coverage/jacoco-ut.exec</fileInclude> - </dataFileIncludes> - </configuration> - </execution> </executions> </plugin> <plugin> diff --git a/cps-path-parser/pom.xml b/cps-path-parser/pom.xml index 1884ea4c10..cb454c2ac1 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-rest/pom.xml b/cps-rest/pom.xml index c76677fe99..a3e5fd9481 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <relativePath>../cps-parent/pom.xml</relativePath> </parent> diff --git a/cps-ri/pom.xml b/cps-ri/pom.xml index e1be2bed3d..00911f83f6 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.0.0-SNAPSHOT</version>
+ <version>2.0.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
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 8217a4fb0d..e2316e8636 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 @@ -21,11 +21,6 @@ */ package org.onap.cps.spi.impl -import org.onap.cps.spi.exceptions.DataValidationException - -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS - import com.google.common.collect.ImmutableSet import com.google.gson.Gson import com.google.gson.GsonBuilder @@ -42,6 +37,9 @@ import org.springframework.test.context.jdbc.Sql import javax.validation.ConstraintViolationException +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { @Autowired @@ -155,17 +153,25 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Add list-node fragment with multiple elements.'() { - given: 'list node data fragment as a collection of data nodes' + def 'Add list-node fragment with multiple elements including an element with a child datanode.'() { + given: 'two new data nodes for an existing list' def listNodeXpaths = ['/parent-201/child-204[@key="B"]', '/parent-201/child-204[@key="C"]'] def listNodeCollection = buildDataNodeCollection(listNodeXpaths) - when: 'list-node elements added to existing parent node' + and: 'a child node for one of the new data nodes' + def childDataNode = buildDataNode('/parent-201/child-204[@key="C"]/grand-child-204[@key2="Z"]', [leave:'value'], []) + listNodeCollection.iterator().next().childDataNodes = [childDataNode] + when: 'the data nodes (list elements) are added to existing parent node' objectUnderTest.addListDataNodes(DATASPACE_NAME, ANCHOR_NAME3, '/parent-201', listNodeCollection) then: 'new entries successfully persisted, parent node now contains 5 children (2 new + 3 existing before)' def parentFragment = fragmentRepository.getById(LIST_DATA_NODE_PARENT201_FRAGMENT_ID) def allChildXpaths = parentFragment.getChildFragments().collect { it.getXpath() } assert allChildXpaths.size() == 5 assert allChildXpaths.containsAll(listNodeXpaths) + and: 'the child node of the new list entry is also present' + def dataspaceEntity = dataspaceRepository.getByName(DATASPACE_NAME) + def anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, ANCHOR_NAME3) + def listElementChild = fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, childDataNode.xpath) + assert listElementChild.isPresent() } @Sql([CLEAR_DATA, SET_DATA]) diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy index 9fcd550bd1..162a56682a 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy @@ -22,6 +22,7 @@ import org.hibernate.StaleStateException import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.entities.FragmentEntity import org.onap.cps.spi.exceptions.ConcurrencyException +import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.spi.model.DataNodeBuilder import org.onap.cps.spi.repository.AnchorRepository import org.onap.cps.spi.repository.DataspaceRepository @@ -95,4 +96,17 @@ class CpsDataPersistenceServiceSpec extends Specification { 'text and numbers' | '"String = \'1234\'"' || "String = '1234'" | String 'number as String' | '"12345"' || '12345' | String } + + def 'Retrieving a data node with invalid JSON'() { + given: 'a fragment with invalid JSON' + mockFragmentRepository.getByDataspaceAndAnchorAndXpath(_, _, _) >> { + new FragmentEntity(childFragments: Collections.emptySet(), attributes: '{invalid json') + } + when: 'getting the data node represented by this fragment' + def dataNode = objectUnderTest.getDataNode('my-dataspace', 'my-anchor', + 'parent-01', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + then: 'a data validation exception is thrown' + thrown(DataValidationException) + } + } diff --git a/cps-service/pom.xml b/cps-service/pom.xml index 028a0608bb..0e0831558d 100644 --- a/cps-service/pom.xml +++ b/cps-service/pom.xml @@ -28,12 +28,16 @@ <parent>
<groupId>org.onap.cps</groupId>
<artifactId>cps-parent</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>2.0.1-SNAPSHOT</version>
<relativePath>../cps-parent/pom.xml</relativePath>
</parent>
<artifactId>cps-service</artifactId>
+ <properties>
+ <minimum-coverage>0.94</minimum-coverage>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.onap.cps</groupId>
diff --git a/csit/install-robotframework.sh b/csit/install-robotframework.sh new file mode 100644 index 0000000000..dada62215f --- /dev/null +++ b/csit/install-robotframework.sh @@ -0,0 +1,16 @@ +ROBOT_VENV=$(mktemp -d --suffix=robot_venv) +echo "ROBOT_VENV=${ROBOT_VENV}" >> "${WORKSPACE}/env.properties" + +echo "Python version is: $(python3 --version)" + +python3 -m venv "${ROBOT_VENV}" +source "${ROBOT_VENV}/bin/activate" + +set -exu + +# Make sure pip3 itself us up-to-date. +python3 -m pip install --upgrade pip + +echo "Installing Python Requirements" +python3 -m pip install -r ${WORKSPACE}/pylibs.txt +python3 -m pip freeze diff --git a/csit/plans/default/setup.sh b/csit/plans/default/setup.sh index cf29b53ac5..e8074ddc0f 100755 --- a/csit/plans/default/setup.sh +++ b/csit/plans/default/setup.sh @@ -40,7 +40,6 @@ chmod +x docker-compose # start CPS and PostgreSQL containers with docker compose ./docker-compose up -d - # Validate CPS service initialization completed via periodic log checking for line like below: # org.onap.cps.Application ... Started Application in X.XXX seconds diff --git a/csit/prepare-csit.sh b/csit/prepare-csit.sh index d46b17ae04..8ef6323d6d 100755 --- a/csit/prepare-csit.sh +++ b/csit/prepare-csit.sh @@ -26,7 +26,7 @@ fi TESTPLANDIR=${WORKSPACE}/${TESTPLAN} -# Assume that if ROBOT_VENV is set and virtualenv with system site packages can be activated, +# Assume that if ROBOT_VENV is set and virtualenv with system site packages can be activated, # ci-management/jjb/integration/include-raw-integration-install-robotframework.sh has already # been executed @@ -39,9 +39,13 @@ else rm -rf /tmp/ci-management rm -f ${WORKSPACE}/env.properties cd /tmp - git clone "https://gerrit.onap.org/r/ci-management" - source /tmp/ci-management/jjb/integration/include-raw-integration-install-robotframework.sh + source ${WORKSPACE}/install-robotframework.sh fi +# install eteutils +mkdir -p ${ROBOT_VENV}/src/onap +rm -rf ${ROBOT_VENV}/src/onap/testsuite +python3 -m pip install --upgrade --extra-index-url="https://nexus3.onap.org/repository/PyPi.staging/simple" 'robotframework-onap==0.5.1.*' --pre + pip freeze diff --git a/csit/pylibs.txt b/csit/pylibs.txt new file mode 100644 index 0000000000..d6250dbab5 --- /dev/null +++ b/csit/pylibs.txt @@ -0,0 +1,27 @@ +docker-py +ipaddr +netaddr +netifaces +pyhocon +requests +robotframework-httplibrary +robotframework-requests +robotframework-selenium2library +robotframework-extendedselenium2library +robotframework-sshlibrary +scapy +# Module jsonpath is needed by current AAA idmlite suite. +jsonpath-rw +# Modules for longevity framework robot library +elasticsearch +elasticsearch-dsl +# Module for pyangbind used by lispflowmapping project +pyangbind +# Module for iso8601 datetime format +isodate +# Module for TemplatedRequests.robot library +jmespath +# Module for backup-restore support library +jsonpatch +# odltools for extra debugging +odltools diff --git a/docs/api/swagger/openapi.yml b/docs/api/swagger/cps/openapi.yaml index 4d64b01b85..fb219eb652 100755..100644 --- a/docs/api/swagger/openapi.yml +++ b/docs/api/swagger/cps/openapi.yaml @@ -1,822 +1,920 @@ -# ============LICENSE_START======================================================= -# Copyright (C) 2021 Nordix Foundation -# Modifications Copyright (C) 2021 Bell Canada. -# ================================================================================ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# ============LICENSE_END========================================================= - openapi: 3.0.1 info: title: ONAP Open API v3 Configuration Persistence Service description: Configuration Persistence Service is a Model Driven Generic Database - version: 1.0.0 contact: name: ONAP - url: 'https://onap.readthedocs.io' + url: https://onap.readthedocs.io email: onap-discuss@lists.onap.org license: name: Apache 2.0 - url: 'http://www.apache.org/licenses/LICENSE-2.0' - x-planned-retirement-date: '202212' + url: http://www.apache.org/licenses/LICENSE-2.0 + version: 1.0.0 + x-planned-retirement-date: "202212" x-component: Modeling x-logo: url: cps_logo.png servers: - - url: '//localhost:8088' +- url: /cps/api tags: - - name: cps-admin - description: cps Admin - - name: cps-data - description: cps Data +- name: cps-admin + description: cps Admin +- name: cps-data + description: cps Data paths: /v1/dataspaces: post: - description: Create a new dataspace tags: - - cps-admin + - cps-admin summary: Create a dataspace + description: Create a new dataspace operationId: createDataspace parameters: - - name: dataspace-name - in: query - description: dataspace-name - required: true - schema: - type: string + - name: dataspace-name + in: query + description: dataspace-name + required: true + schema: + type: string responses: - '201': + "201": description: Created content: text/plain: schema: type: string - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}': - delete: - description: Delete the given dataspace - DRAFT - tags: - - cps-admin - summary: Delete a dataspace - operationId: deleteDataspace - parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - '204': - description: No Content - content: {} - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/anchors': + /v1/dataspaces/{dataspace-name}/anchors: get: - description: 'Read all anchors, given a dataspace' tags: - - cps-admin + - cps-admin summary: Get anchors + description: "Read all anchors, given a dataspace" operationId: getAnchors parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string responses: - '200': + "200": description: OK content: application/json: schema: - type: object - '400': + type: array + items: + $ref: '#/components/schemas/AnchorDetails' + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': + "404": description: The specified resource was not found content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' post: - description: Create a new anchor in the given dataspace tags: - - cps-admin + - cps-admin summary: Create an anchor + description: Create a new anchor in the given dataspace operationId: createAnchor parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: schema-set-name - in: query - description: schema-set-name - required: true - schema: - type: string - - name: anchor-name - in: query - description: anchor-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: schema-set-name + in: query + description: schema-set-name + required: true + schema: + type: string + - name: anchor-name + in: query + description: anchor-name + required: true + schema: + type: string responses: - '201': + "201": description: Created content: text/plain: schema: type: string - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}': + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}: get: - description: Read an anchor given an anchor name and a dataspace tags: - - cps-admin + - cps-admin summary: Get an anchor + description: Read an anchor given an anchor name and a dataspace operationId: getAnchor parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string responses: - '200': + "200": description: OK content: application/json: schema: - type: object - '400': + $ref: '#/components/schemas/AnchorDetails' + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': + "404": description: The specified resource was not found content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' delete: - description: Delete an anchor given an anchor name and a dataspace - DRAFT tags: - - cps-admin + - cps-admin summary: Delete an anchor + description: Delete an anchor given an anchor name and a dataspace operationId: deleteAnchor parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string responses: - '200': - description: OK - content: - application/json: - schema: - type: object - '204': + "204": description: No Content content: {} - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/schema-sets': + /v1/dataspaces/{dataspace-name}/schema-sets: post: - description: Create a new schema set in the given dataspace tags: - - cps-admin + - cps-admin summary: Create a schema set + description: Create a new schema set in the given dataspace operationId: createSchemaSet parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: schema-set-name - in: query - description: schema-set-name - required: true - schema: - type: string - requestBody: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: schema-set-name + in: query + description: schema-set-name required: true + schema: + type: string + requestBody: content: multipart/form-data: schema: - type: object - required: - - file - properties: - file: - type: string - description: multipartFile - format: binary - example: 'http://example.com/examples/example.yang' + $ref: '#/components/schemas/MultipartFile' + required: true responses: - '201': + "201": description: Created content: text/plain: schema: type: string - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/schema-sets/{schema-set-name}': + /v1/dataspaces/{dataspace-name}/schema-sets/{schema-set-name}: get: - description: Read a schema set given a schema set name and a dataspace tags: - - cps-admin + - cps-admin summary: Get a schema set + description: Read a schema set given a schema set name and a dataspace operationId: getSchemaSet parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: schema-set-name - in: path - description: schema-set-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: schema-set-name + in: path + description: schema-set-name + required: true + schema: + type: string responses: - '200': + "200": description: OK content: application/json: schema: - type: object - '400': + $ref: '#/components/schemas/SchemaSetDetails' + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': + "404": description: The specified resource was not found content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' delete: - description: Delete a schema set given a schema set name and a dataspace tags: - - cps-admin + - cps-admin summary: Delete a schema set + description: Delete a schema set given a schema set name and a dataspace operationId: deleteSchemaSet parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: schema-set-name - in: path - description: schema-set-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: schema-set-name + in: path + description: schema-set-name + required: true + schema: + type: string responses: - '204': + "204": description: No Content content: {} - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '409': + "409": description: Conflict content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/node': + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/node: get: - description: >- - Get a node with an option to retrieve all the children for a given - anchor and dataspace tags: - - cps-data + - cps-data summary: Get a node + description: Get a node with an option to retrieve all the children for a given + anchor and dataspace operationId: getNodeByDataspaceAndAnchor parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string - - name: xpath - in: query - description: xpath - required: false - schema: - type: string - default: / - - name: include-descendants - in: query - description: include-descendants - required: false - schema: - type: boolean - default: false + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + - name: include-descendants + in: query + description: include-descendants + required: false + schema: + type: boolean + default: false responses: - '200': + "200": description: OK content: application/json: schema: type: object - '400': + example: + child: my_child + leafList: "leafListElement1, leafListElement2" + leaf: my_leaf + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': + "404": description: The specified resource was not found content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' x-codegen-request-body-name: xpath - '/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes': + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes: + put: + tags: + - cps-data + summary: Replace a node with descendants + description: "Replace a node with descendants for a given dataspace, anchor\ + \ and a parent node xpath" + operationId: replaceNode + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + requestBody: + content: + application/json: + schema: + type: string + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + example: + key: value + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' post: - description: Create a node for a given anchor and dataspace tags: - - cps-data + - cps-data summary: Create a node + description: Create a node for a given anchor and dataspace operationId: createNode parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string - requestBody: + - name: dataspace-name + in: path + description: dataspace-name required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + requestBody: content: application/json: schema: type: string + required: true responses: - '201': + "201": description: Created content: text/plain: schema: type: string - '400': + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' patch: - description: >- - Update a data node leaves for a given dataspace and anchor and a parent - node xpath tags: - - cps-data + - cps-data summary: Update node leaves + description: Update a data node leaves for a given dataspace and anchor and + a parent node xpath operationId: updateNodeLeaves parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string - - name: xpath - in: query - description: xpath - required: false - schema: - type: string - default: / - requestBody: + - name: dataspace-name + in: path + description: dataspace-name required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + requestBody: content: application/json: schema: type: string + required: true responses: - '200': + "200": description: OK content: application/json: schema: type: object - '400': + example: + key: value + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/list-nodes: put: - description: >- - Replace a node with descendants for a given dataspace, anchor and a - parent node xpath tags: - - cps-data - summary: Replace a node with descendants - operationId: replaceNode + - cps-data + summary: Replace list-node child element(s) under existing parent node + description: Replace list-node child elements under existing node for a given + anchor and dataspace + operationId: replaceListNodeElements parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string - - name: xpath - in: query - description: xpath - required: false - schema: - type: string - default: / - requestBody: + - name: dataspace-name + in: path + description: dataspace-name required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: true + schema: + type: string + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + requestBody: content: application/json: schema: type: string + required: true responses: - '200': - description: OK + "200": + description: Created content: - application/json: + text/plain: schema: - type: object - '400': + type: string + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '/v1/dataspaces/{dataspace-name}/nodes': - get: - description: >- - Get all nodes for a given dataspace using an xpath or schema node - identifier - DRAFT + post: tags: - - cps-data - summary: Get nodes - operationId: getNodesByDataspace + - cps-data + summary: Add list-node child element(s) under existing parent node + description: Add list-node child elements to existing node for a given anchor + and dataspace + operationId: addListNodeElements parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: true + schema: + type: string + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + requestBody: + content: + application/json: + schema: + type: string + required: true responses: - '200': - description: OK + "201": + description: Created content: - application/json: + text/plain: schema: - type: object - '400': + type: string + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': - description: The specified resource was not found + delete: + tags: + - cps-data + summary: Delete list-node child element(s) under existing parent node + description: Delete list-node child elements under existing node for a given + anchor and dataspace + operationId: deleteListNodeElements + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: xpath + in: query + description: xpath + required: true + schema: + type: string + - name: observed-timestamp + in: query + description: observed-timestamp + required: false + schema: + type: string + example: 2021-03-21T00:10:34.030-0100 + responses: + "204": + description: No Content + content: {} + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - x-codegen-request-body-name: requestBody - '/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query': + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query: get: - description: Query data nodes for the given dataspace and anchor using CPS path tags: - - cps-query + - cps-query summary: Query data nodes + description: Query data nodes for the given dataspace and anchor using CPS path operationId: getNodesByDataspaceAndAnchorAndCpsPath parameters: - - name: dataspace-name - in: path - description: dataspace-name - required: true - schema: - type: string - - name: anchor-name - in: path - description: anchor-name - required: true - schema: - type: string - - name: cps-path - in: query - description: cps-path - required: false - schema: - type: string - default: / - - name: include-descendants - in: query - description: include-descendants - required: false - schema: - type: boolean - default: false + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: string + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: string + - name: cps-path + in: query + description: cps-path + required: false + schema: + type: string + default: / + - name: include-descendants + in: query + description: include-descendants + required: false + schema: + type: boolean + default: false responses: - '200': + "200": description: OK content: application/json: schema: type: object - '400': + example: + key: value + "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '401': + "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '403': + "403": description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - '404': + "404": description: The specified resource was not found content: application/json: @@ -826,15 +924,64 @@ paths: components: schemas: ErrorMessage: - type: object title: Error + type: object properties: status: type: string - example: 400 + example: "400" message: type: string example: Dataspace not found details: type: string example: Dataspace with name D1 does not exist. + AnchorDetails: + title: Anchor details by anchor Name + type: object + properties: + name: + type: string + example: my_anchor + dataspaceName: + type: string + example: my_dataspace + schemaSetName: + type: string + example: my_schema_set + MultipartFile: + required: + - file + type: object + properties: + file: + type: string + description: multipartFile + format: binary + SchemaSetDetails: + title: Schema set details by dataspace and schemasetName + type: object + properties: + dataspaceName: + type: string + example: my_dataspace + moduleReferences: + type: array + items: + $ref: '#/components/schemas/ModuleReferences' + name: + type: string + example: my_schema_set + ModuleReferences: + title: Module reference object + type: object + properties: + name: + type: string + example: module_reference_name + namespace: + type: string + example: module_reference_namespace + revision: + type: string + example: module_reference_revision diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml new file mode 100644 index 0000000000..0edce20c17 --- /dev/null +++ b/docs/api/swagger/ncmp/openapi.yaml @@ -0,0 +1,659 @@ +openapi: 3.0.1 +info: + title: NCMP to CPS Proxy API + description: NCMP to CPS Proxy API + version: "1.0" +servers: +- url: /ncmp +paths: + /v1/cm-handles/{cm-handle}/node: + get: + tags: + - network-cm-proxy + summary: Get a node given a cm Handle and xpath + description: Get a node with an option to retrieve all the children for a given + cm Handle + operationId: getNodeByCmHandleAndXpath + 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 + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + - name: include-descendants + in: query + description: include-descendants + required: false + schema: + type: boolean + default: false + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + /v1/cm-handles/{cm-handle}/list-node: + post: + tags: + - network-cm-proxy + summary: Add list-node child element(s) + description: Add one or more list-node child elements under existing node for + the given CM Handle + operationId: addListNodeElements + 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 + - name: xpath + in: query + description: xpath + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + required: true + responses: + "201": + description: Created + content: {} + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + /v1/cm-handles/{cm-handle}/nodes/query: + get: + tags: + - network-cm-proxy + summary: Query data nodes + description: Query nodes for the given cps path and cm Handle + operationId: queryNodesByCmHandleAndCpsPath + 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 + - name: cps-path + in: query + description: cps-path + required: false + schema: + type: string + default: / + - name: include-descendants + in: query + description: include-descendants + required: false + schema: + type: boolean + default: false + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + /v1/cm-handles/{cm-handle}/nodes: + put: + tags: + - network-cm-proxy + summary: Replace a node with descendants + description: Replace a node with descendants for the given cps path and cm Handle + operationId: replaceNode + 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 + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + requestBody: + content: + application/json: + schema: + type: string + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + post: + tags: + - network-cm-proxy + summary: Create a node with descendants + description: Create a node with descendants for the given CM Handle; top level + or under existing node (requires xpath) + operationId: createNode + 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 + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + requestBody: + content: + application/json: + schema: + type: string + required: true + responses: + "201": + description: Created + content: {} + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + patch: + tags: + - network-cm-proxy + summary: Update node leaves + description: Update node leaves for the given cps path and cm Handle + operationId: updateNodeLeaves + 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 + - name: xpath + in: query + description: xpath + required: false + schema: + type: string + default: / + requestBody: + content: + application/json: + schema: + type: string + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + deprecated: true + /v1/ch: + post: + tags: + - network-cm-proxy + summary: DMI notifies NCMP of new CM Handles + description: "Register a DMI Plugin with any new, updated or removed CM Handles." + operationId: updateDmiPluginRegistration + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RestDmiPluginRegistration' + required: true + responses: + "201": + description: Created + content: {} + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational/{resourceIdentifier}: + get: + tags: + - 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\ + \ or any other cm object by managed Network CM Proxy" + required: true + schema: + type: string + - name: resourceIdentifier + in: path + description: Resource identifier to get/set the resource data + required: true + schema: + type: string + - 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: fields + in: query + description: Fields parameter to filter resource + required: false + schema: + type: string + - name: depth + in: query + description: Depth parameter for response + required: false + schema: + minimum: 1 + type: integer + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running/{resourceIdentifier}: + get: + tags: + - 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\ + \ or any other cm object by managed Network CM Proxy" + required: true + schema: + type: string + - name: resourceIdentifier + in: path + description: Resource identifier to get/set the resource data + required: true + schema: + type: string + - 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: fields + in: query + description: Fields parameter to filter resource + required: false + schema: + type: string + - name: depth + in: query + description: Depth parameter for response + required: false + schema: + minimum: 1 + type: integer + responses: + "200": + description: OK + content: + application/json: + schema: + type: object + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + post: + tags: + - 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\ + \ or any other cm object by managed Network CM Proxy" + required: true + schema: + type: string + - name: resourceIdentifier + in: path + description: Resource identifier to get/set the resource data + required: true + schema: + type: string + - 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 + requestBody: + content: + application/json: + schema: + type: object + application/yang-data+json: + schema: + type: object + required: true + responses: + "201": + description: Created + content: {} + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' + "404": + description: The specified resource was not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorMessage' +components: + schemas: + ErrorMessage: + title: Error + type: object + properties: + status: + type: string + message: + type: string + details: + type: string + RestDmiPluginRegistration: + type: object + properties: + dmiPlugin: + type: string + example: onap-dmi-plugin + createdCmHandles: + type: array + items: + $ref: '#/components/schemas/RestCmHandle' + updatedCmHandles: + type: array + items: + $ref: '#/components/schemas/RestCmHandle' + removedCmHandles: + type: array + items: + type: string + RestCmHandle: + required: + - cmHandle + type: object + properties: + cmHandle: + type: string + example: cmHandle123 + cmHandleProperties: + $ref: '#/components/schemas/RestCmHandleAdditionalProperties' + RestCmHandleAdditionalProperties: + type: object + additionalProperties: + type: string + example: system-001 diff --git a/docs/architecture.rst b/docs/architecture.rst index 51acf66f0e..b703cfa535 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -6,6 +6,8 @@ CPS Architecture ################ +.. warning:: draft + .. toctree:: :maxdepth: 1 @@ -16,10 +18,12 @@ High Level Component Definition and Architectural Relationships The Configuration Persistence Service (CPS) provides storage for run-time configuration and operational parameters that need to be used by ONAP. -In this release the CPS is a stand-alone component. Project page describing eventual scope and ambition is here: -`Configuration Persistence Service Project <https://wiki.onap.org/display/DW/Configuration+Persistence+Service+Project>`_ +In this release CPS is no longer a stand alone component and is released along with Cps-Temporal and the NCMP-DMI Plugin. + +Project page describing eventual scope and ambition is here: +`Configuration Persistence Service Project <https://wiki.onap.org/display/DW/Configuration+Persistence+Service+Project>`_ -This page reflects the state for Honolulu-R8 release. +This page reflects the state for Istanbul-R9 release. .. image:: _static/cps-r8-arch-diagram.png diff --git a/docs/conf.py b/docs/conf.py index 1a9a5475aa..3aaddd194f 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,24 +16,97 @@ # SPDX-License-Identifier: Apache-2.0 # ============LICENSE_END========================================================= + +from docutils.parsers.rst import directives from docs_conf.conf import * branch = 'latest' +doc_url = 'https://docs.onap.org/projects' master_doc = 'index' -extensions = [ - 'sphinx.ext.autosectionlabel', - 'sphinxcontrib.swaggerdoc' - ] + +intersphinx_mapping = {} + +# Latest (change to branch) +intersphinx_mapping['onap-cps'] = ('{}/onap-cps/en/%s'.format(doc_url) % branch, None) linkcheck_ignore = [ 'http://localhost', + 'https://example.com', + 'about:config', + # this URL is not directly reachable and must be configured in the system hosts file. + 'https://portal.api.simpledemo.onap.org:30225/ONAPPORTAL/login.htm', + # anchor issues + 'https://docs.onap.org/projects/onap-integration/en/latest/docs_usecases_release.html#.*', + 'https://docs.linuxfoundation.org/docs/communitybridge/easycla/contributors/contribute-to-a-gerrit-project#.*', + 'https://docs.onap.org/projects/onap-integration/en/latest/docs_robot.html#docs-robot', + 'https://docs.onap.org/projects/onap-integration/en/latest/docs_usecases_release.html#docs-usecases-release', + 'https://docs.onap.org/projects/onap-integration/en/latest/docs_usecases.html#docs-usecases', + 'https://docs.onap.org/projects/onap-integration/en/latest/usecases/release_non_functional_requirements.html#release-non-functional-requirements', ] -intersphinx_mapping = {} html_last_updated_fmt = '%d-%b-%y %H:%M' -autosectionlabel_maxdepth = 2 def setup(app): - app.add_stylesheet("css/ribbon.css") + app.add_css_file("css/ribbon.css") + + +needs_extra_options = { + "target": directives.unchanged, + "keyword": directives.unchanged, + "introduced": directives.unchanged, + "updated": directives.unchanged, + "impacts": directives.unchanged, + "validation_mode": directives.unchanged, + "validated_by": directives.unchanged, + "test": directives.unchanged, + "test_case": directives.unchanged, + "test_file": directives.unchanged, + "notes": directives.unchanged, +} + +needs_id_regex = "^[A-Z0-9]+-[A-Z0-9]+" +needs_id_required = True +needs_title_optional = True + +needs_template_collapse = """ +.. _{{id}}: + +{% if hide == false -%} +.. role:: needs_tag +.. role:: needs_status +.. role:: needs_type +.. role:: needs_id +.. role:: needs_title + +.. rst-class:: need +.. rst-class:: need_{{type_name}} + +.. container:: need + + `{{id}}` - {{content|indent(4)}} + + .. container:: toggle + + .. container:: header + + Details + +{% if status and status|upper != "NONE" and not hide_status %} | status: :needs_status:`{{status}}`{% endif %} +{% if tags and not hide_tags %} | tags: :needs_tag:`{{tags|join("` :needs_tag:`")}}`{% endif %} +{% if keyword %} | keyword: `{{keyword}}` {% endif %} +{% if target %} | target: `{{target}}` {% endif %} +{% if introduced %} | introduced: `{{introduced}}` {% endif %} +{% if updated %} | updated: `{{updated}}` {% endif %} +{% if impacts %} | impacts: `{{impacts}}` {% endif %} +{% if validation_mode %} | validation mode: `{{validation_mode}}` {% endif %} +{% if validated_by %} | validated by: `{{validated_by}}` {% endif %} +{% if test %} | test: `{{test}}` {% endif %} +{% if test_case %} | test case: {{test_case}} {% endif %} +{% if test_file %} | test file: `{{test_file}}` {% endif %} +{% if notes %} | notes: `{{notes}}` {% endif %} + | children: :need_incoming:`{{id}}` + | parents: :need_outgoing:`{{id}}` +{% endif -%} +""" diff --git a/docs/cps-path.rst b/docs/cps-path.rst index 0271d07e1d..cb26548de2 100644 --- a/docs/cps-path.rst +++ b/docs/cps-path.rst @@ -1,5 +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 .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _design: @@ -8,6 +9,8 @@ CPS Path ######## +.. warning:: draft + .. toctree:: :maxdepth: 1 diff --git a/docs/deployment.rst b/docs/deployment.rst new file mode 100644 index 0000000000..d538cbbfee --- /dev/null +++ b/docs/deployment.rst @@ -0,0 +1,15 @@ +.. 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 + +.. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING +.. _deployment: + + +CPS Deployment +############## + +.. warning:: draft + +.. toctree:: + :maxdepth: 1
\ No newline at end of file diff --git a/docs/design.rst b/docs/design.rst index c7691ae35c..f9f12de432 100755 --- a/docs/design.rst +++ b/docs/design.rst @@ -1,5 +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 .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _design: @@ -8,6 +9,8 @@ CPS Design ########## +.. warning:: draft + .. toctree:: :maxdepth: 1 @@ -16,7 +19,9 @@ Offered APIs CPS supports the public APIs listed in the link below: -:download:`OpenApi Specification <api/swagger/openapi.yml>` +:download:`CPS Rest OpenApi Specification <api/swagger/cps/openapi.yaml>` + +:download:`CPS NCMP RestOpenApi Specification <api/swagger/ncmp/openapi.yaml>` Exposed API ----------- diff --git a/docs/index.rst b/docs/index.rst index 57ab3b9b05..ec2ec5dd88 100755 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +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 .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _master_index: @@ -7,8 +8,10 @@ .. THIS IS USED INTERNALLY IN CPS ONLY .. _cps-framework-doc: -CPS Documentation for the Honolulu-R8 Release ---------------------------------------------- +CPS-Core Documentation +---------------------- + +.. warning:: draft .. toctree:: :maxdepth: 1 @@ -17,5 +20,16 @@ CPS Documentation for the Honolulu-R8 Release architecture.rst design.rst modeling.rst + deployment.rst cps-path.rst release-notes.rst + +ONAP DMI Plugin Documentation +----------------------------- + +* `DMI Plugin(placeholder) `_ + +CPS-Temporal Documentation +-------------------------- + +* `CPS Temporal(placeholder) `_
\ No newline at end of file diff --git a/docs/modeling.rst b/docs/modeling.rst index 6b15abcfa3..4e46e71b7a 100644 --- a/docs/modeling.rst +++ b/docs/modeling.rst @@ -6,6 +6,8 @@ CPS Modeling ############ +.. warning:: draft + .. toctree:: :maxdepth: 1 diff --git a/docs/overview.rst b/docs/overview.rst index 776e179482..b1f4755b66 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -1,11 +1,13 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2021 Pantheon.tech +.. Copyright (C) 2021 Pantheon.tech, Nordix Foundation .. _overview: CPS Overview ============ +.. warning:: draft + The Configuration Persistence Service (CPS) is a platform component that is designed to serve as a data repository for runtime data that needs persistence. @@ -36,3 +38,6 @@ Contact Information ------------------- onap-discuss@lists.onap.org + +Meeting details `Join <https://zoom.us/j/836561560?pwd=TTZNcFhXTWYxMmZ4SlgzcVZZQXluUT09>`_ +`Agenda <https://wiki.onap.org/pages/viewpage.action?pageId=111117075>`_ diff --git a/docs/release-notes.rst b/docs/release-notes.rst index f213c7e4de..797a11cf5f 100755 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -1,5 +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 .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _release_notes: @@ -10,11 +11,140 @@ CPS Release Notes ================= +.. warning:: draft + .. contents:: :depth: 2 .. +.. ======================== +.. * * * ISTANBUL * * * +.. ======================== + +Version: 2.0.0 +============== + +Abstract +-------- + +This document provides the release notes for Istanbul release. + +Release Data +------------ + ++--------------------------------------+--------------------------------------------------------+ +| **CPS Project** | | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Docker images** | onap/cps-and-ncmp:2.0.0 | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release designation** | 2.0.0 Istanbul | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release date** | 2021-14-10 | +| | | ++--------------------------------------+--------------------------------------------------------+ + +Features +-------- +* Register DMI Plugins with NCMP for CM Handle registrations. +* Update, Create and Remove CM Handles. +* Add support for retrieving and writing CM Handle data through NCMP datastores. +* Automatic retrieval and caching of model information for CM Handles within NCMP. + +.. _istanbul_deliverable: + +Deliverables +------------ + +Software Deliverables + +.. csv-table:: + :header: "Repository", "SubModules", "Version & Docker Image (if applicable)" + :widths: auto + + "cps", "", "onap/cps-and-ncmp-proxy:2.0.0" + +Bug Fixes +--------- + + - `CPS-316 <https://jira.onap.org/browse/CPS-316>`_ Xpath cannot be created for augmentation data node + - `CPS-336 <https://jira.onap.org/browse/CPS-336>`_ Ends-with functionality in cpsPath does not conform with standard xPath behavior + - `CPS-367 <https://jira.onap.org/browse/CPS-367>`_ Get descendent does not support xpaths that end in list values + - `CPS-377 <https://jira.onap.org/browse/CPS-377>`_ Init ran model validation is failing, error details are not provided + - `CPS-422 <https://jira.onap.org/browse/CPS-422>`_ REST 404 response returned instead of 400 for POST/PUT/PATCH request types + - `CPS-450 <https://jira.onap.org/browse/CPS-450>`_ Datanode query using full path to node causes NPE + - `CPS-466 <https://jira.onap.org/browse/CPS-466>`_ Concurrent requests to create schema sets for the same yang model are not supported + - `CPS-479 <https://jira.onap.org/browse/CPS-479>`_ Get Nodes API does not always return the object from the root + - `CPS-501 <https://jira.onap.org/browse/CPS-501>`_ Put DataNode API has missing transaction and error handling for concurrency issues + - `CPS-504 <https://jira.onap.org/browse/CPS-504>`_ Checkstyle rules are not enforced for cps-ncmp-dmi-plugin + - `CPS-515 <https://jira.onap.org/browse/CPS-515>`_ Maven build is not failing when test containers are not able to run + - `CPS-520 <https://jira.onap.org/browse/CPS-520>`_ Fix docker profile in cps-temporal and cps-ncmp-dmi-plugin + - `CPS-524 <https://jira.onap.org/browse/CPS-524>`_ Issue with CPSData API to add an item to an existing list node + - `CPS-560 <https://jira.onap.org/browse/CPS-560>`_ Response from cps query using text() contains escape characters + - `CPS-566 <https://jira.onap.org/browse/CPS-566>`_ Can't access grandparent node through ancestor axis + - `CPS-586 <https://jira.onap.org/browse/CPS-586>`_ App username and password environment variables are missing from temporal docker compose + +This document provides the release notes for Istanbul release. + +Summary +------- + +Following CPS components are available with default ONAP/CPS installation. + + + * Platform components + + - CPS (Helm charts) + + * Service components + + - CPS Core and NCMP + - CPS Temporal + - DMI Plugin + + * Additional resources that CPS utilizes deployed using ONAP common charts + + - Postgres Database + + +Below service components (mS) are available to be deployed on-demand. + - CPS-TBDMT + + +Under OOM (Kubernetes) all CPS component containers are deployed as Kubernetes Pods/Deployments/Services into Kubernetes cluster. + +Known Limitations, Issues and Workarounds +----------------------------------------- + - `CPS-524 <https://jira.onap.org/browse/CPS-524>`_ Issue with CPSData API to add an item to an existing list node + +*System Limitations* + +Limitations to the amount of child nodes that can be added to the fix above. The current limit is 3. + +*Known Vulnerabilities* + +None + +*Workarounds* + +Add recursive method to save list node data to loop through all corresponding child nodes. + +Security Notes +-------------- + +*Fixed Security Issues* + + - `CPS-249 <https://jira.onap.org/browse/CPS-249>`_ Exception stack trace is exposed + - `CPS-581 <https://jira.onap.org/browse/CPS-581>`_ Remove security vulnerabilities + +*Known Security Issues* + +Test Results +------------ + * `Integration tests` .. ======================== .. * * * HONOLULU * * * diff --git a/jacoco-report/pom.xml b/jacoco-report/pom.xml new file mode 100644 index 0000000000..2c2a4db97b --- /dev/null +++ b/jacoco-report/pom.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>cps-aggregator</artifactId> + <groupId>org.onap.cps</groupId> + <version>2.0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>jacoco-report</artifactId> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-application</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-events</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-ncmp-rest</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-ncmp-service</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-path-parser</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-rest</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-ri</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>cps-service</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <configuration> + <excludes> + <exclude>org/onap/cps/event/model/*</exclude> + <exclude>org/onap/cps/rest/model/*</exclude> + <exclude>org/onap/cps/cpspath/parser/antlr4/*</exclude> + <exclude>org/onap/cps/ncmp/rest/model/*</exclude> + </excludes> + </configuration> + <executions> + <execution> + <id>default-prepare-agent</id> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>report</id> + <goals> + <goal>report-aggregate</goal> + </goals> + <phase>verify</phase> + <configuration> + <dataFileIncludes> + <fileInclude>**/code-coverage/jacoco-ut.exec</fileInclude> + </dataFileIncludes> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> @@ -32,7 +32,7 @@ <groupId>org.onap.cps</groupId>
<artifactId>cps-aggregator</artifactId>
- <version>2.0.0-SNAPSHOT</version>
+ <version>2.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cps</name>
@@ -62,6 +62,7 @@ <module>checkstyle</module>
<module>spotbugs</module>
<module>cps-application</module>
+ <module>jacoco-report</module>
</modules>
<build>
@@ -74,6 +75,47 @@ <processAllModules>true</processAllModules>
</configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-resources-ncmp</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.basedir}/docs/api/swagger/ncmp/</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/cps-ncmp-rest/target/generated-sources/swagger</directory>
+ <includes>
+ <include>openapi.yaml</include>
+ </includes>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>copy-resources-cps</id>
+ <phase>compile</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.basedir}/docs/api/swagger/cps/</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/cps-rest/target/generated-sources/swagger/</directory>
+ <includes>
+ <include>openapi.yaml</include>
+ </includes>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
diff --git a/spotbugs/pom.xml b/spotbugs/pom.xml index 2a52fb7ecf..96bcac2e38 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.0.0-SNAPSHOT</version> + <version>2.0.1-SNAPSHOT</version> <properties> <nexusproxy>https://nexus.onap.org</nexusproxy> |