Transform module information from NetConf node to Generic format for NCMP
Issue-ID: CPS-531
Signed-off-by: niamhcore <niamh.core@est.tech>
Change-Id: I918be4db5066d92b23e25fc7fbc22d4535fafc8c
diff --git a/docs/openapi/components.yml b/docs/openapi/components.yml
index 05f1ac0..3d8aa2c 100644
--- a/docs/openapi/components.yml
+++ b/docs/openapi/components.yml
@@ -43,6 +43,21 @@
type: string
example: system-001
+ ModuleSet:
+ type: object
+ properties:
+ schemas:
+ type: array
+ items:
+ type: object
+ properties:
+ moduleName:
+ type: string
+ revision:
+ type: string
+ namespace:
+ type: string
+
OperationalRequest:
type: object
properties:
diff --git a/docs/openapi/openapi.yml b/docs/openapi/openapi.yml
index a4a238c..114c521 100644
--- a/docs/openapi/openapi.yml
+++ b/docs/openapi/openapi.yml
@@ -51,22 +51,16 @@
content:
application/json:
schema:
- type: string
+ $ref: 'components.yml#/components/schemas/ModuleSet'
example: {
- 'schemas': {
- 'schema': [
- {
- 'identifier': 'example-identifier',
- 'version': 'example-version',
- 'format': 'example-format',
- 'namespace': 'example:namespace',
- 'location': [
- 'example-location'
- ]
- }
- ]
- }
- }
+ "schemas": [
+ {
+ "moduleName": "example-identifier",
+ "revision": "example-version",
+ "namespace": "example-namespace"
+ }
+ ]
+ }
'400':
$ref: 'components.yml#/components/responses/BadRequest'
'401':
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaList.java b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaList.java
new file mode 100644
index 0000000..1e7dcb0
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaList.java
@@ -0,0 +1,36 @@
+/*
+ * ============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.dmi.model;
+
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * ModuleSchemaList.
+ */
+@Getter
+@Setter
+public class ModuleSchemaList {
+
+ private List<ModuleSchemaProperties> schema;
+
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaProperties.java b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaProperties.java
new file mode 100644
index 0000000..507758a
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemaProperties.java
@@ -0,0 +1,40 @@
+/*
+ * ============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.dmi.model;
+
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * ModuleSchemaProperties.
+ */
+@Getter
+@Setter
+public class ModuleSchemaProperties {
+
+ private String identifier;
+ private String version;
+ private String format;
+ private String namespace;
+ private List<String> location;
+
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemas.java b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemas.java
new file mode 100644
index 0000000..1794ded
--- /dev/null
+++ b/src/main/java/org/onap/cps/ncmp/dmi/model/ModuleSchemas.java
@@ -0,0 +1,34 @@
+/*
+ * ============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.dmi.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * ModuleSchemas.
+ */
+@Getter
+@Setter
+public class ModuleSchemas {
+
+ private ModuleSchemaList schemas;
+}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
index 969e08d..3d49b78 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java
@@ -28,6 +28,7 @@
import org.onap.cps.ncmp.dmi.model.CmHandles;
import org.onap.cps.ncmp.dmi.model.ModuleReference;
import org.onap.cps.ncmp.dmi.model.ModuleRequestParent;
+import org.onap.cps.ncmp.dmi.model.ModuleSet;
import org.onap.cps.ncmp.dmi.model.OperationalRequest;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi;
import org.onap.cps.ncmp.dmi.rest.api.DmiPluginInternalApi;
@@ -52,10 +53,9 @@
}
@Override
- public ResponseEntity<String> getModulesForCmHandle(final String cmHandle) {
-
- final String modulesListAsJson = dmiService.getModulesForCmHandle(cmHandle);
- return new ResponseEntity<>(modulesListAsJson, HttpStatus.OK);
+ public ResponseEntity<ModuleSet> getModulesForCmHandle(final String cmHandle) {
+ final var moduleSet = dmiService.getModulesForCmHandle(cmHandle);
+ return new ResponseEntity<ModuleSet>(moduleSet, HttpStatus.OK);
}
@Override
@@ -118,6 +118,7 @@
private List<ModuleReference> convertRestObjectToJavaApiObject(final ModuleRequestParent moduleRequestParent) {
return objectMapper
- .convertValue(moduleRequestParent.getData().getModules(), new TypeReference<List<ModuleReference>>() {});
+ .convertValue(moduleRequestParent.getData().getModules(), new TypeReference<List<ModuleReference>>() {
+ });
}
}
\ No newline at end of file
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
index 528eb64..a7c9434 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiService.java
@@ -25,6 +25,7 @@
import javax.validation.constraints.NotNull;
import org.onap.cps.ncmp.dmi.exception.DmiException;
import org.onap.cps.ncmp.dmi.model.ModuleReference;
+import org.onap.cps.ncmp.dmi.model.ModuleSet;
/**
* Interface for handling Dmi plugin Data.
@@ -38,7 +39,7 @@
* @return {@code String} returns all modules
* @throws DmiException can throw dmi exception
*/
- String getModulesForCmHandle(String cmHandle) throws DmiException;
+ ModuleSet getModulesForCmHandle(String cmHandle) throws DmiException;
/**
* This method used to register the given {@code CmHandles}
diff --git a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
index 32c8526..94bd97d 100644
--- a/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
+++ b/src/main/java/org/onap/cps/ncmp/dmi/service/DmiServiceImpl.java
@@ -39,6 +39,10 @@
import org.onap.cps.ncmp.dmi.model.CmHandleOperation;
import org.onap.cps.ncmp.dmi.model.CreatedCmHandle;
import org.onap.cps.ncmp.dmi.model.ModuleReference;
+import org.onap.cps.ncmp.dmi.model.ModuleSchemaProperties;
+import org.onap.cps.ncmp.dmi.model.ModuleSchemas;
+import org.onap.cps.ncmp.dmi.model.ModuleSet;
+import org.onap.cps.ncmp.dmi.model.ModuleSetSchemas;
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient;
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations;
import org.springframework.http.HttpStatus;
@@ -73,14 +77,15 @@
}
@Override
- public String getModulesForCmHandle(final String cmHandle) throws DmiException {
+ public ModuleSet getModulesForCmHandle(final String cmHandle) throws DmiException {
final ResponseEntity<String> responseEntity = sdncOperations.getModulesFromNode(cmHandle);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
final String responseBody = responseEntity.getBody();
if (StringUtils.isEmpty(responseBody)) {
throw new ModulesNotFoundException(cmHandle, "SDNC returned no modules for given cm-handle.");
}
- return responseBody;
+ final ModuleSet moduleSet = createModuleSchema(responseBody);
+ return moduleSet;
} else {
throw new DmiException("SDNC is not able to process request.",
"response code : " + responseEntity.getStatusCode() + " message : " + responseEntity.getBody());
@@ -129,6 +134,36 @@
}
}
+ private ModuleSet createModuleSchema(final String responseBody) {
+ final var moduleSchemas = convertModulesToNodeSchema(responseBody);
+ final List<ModuleSetSchemas> moduleSetSchemas = new ArrayList<>();
+ for (final ModuleSchemaProperties schemaProperties : moduleSchemas.getSchemas().getSchema()) {
+ moduleSetSchemas.add(convertModulesToModuleSchemas(schemaProperties));
+ }
+ final var moduleSet = new ModuleSet();
+ moduleSet.setSchemas(moduleSetSchemas);
+ return moduleSet;
+ }
+
+ private ModuleSetSchemas convertModulesToModuleSchemas(final ModuleSchemaProperties moduleSchemaProperties) {
+ final var moduleSetSchemas = new ModuleSetSchemas();
+ moduleSetSchemas.setModuleName(moduleSchemaProperties.getIdentifier());
+ moduleSetSchemas.setNamespace(moduleSchemaProperties.getNamespace());
+ moduleSetSchemas.setRevision(moduleSchemaProperties.getVersion());
+ return moduleSetSchemas;
+ }
+
+ private ModuleSchemas convertModulesToNodeSchema(final String modulesListAsJson) {
+ try {
+ return objectMapper.readValue(modulesListAsJson, ModuleSchemas.class);
+ } catch (final JsonProcessingException e) {
+ log.error("JSON exception occurred when converting the following modules to node schema "
+ + "{}", modulesListAsJson);
+ throw new DmiException("Unable to process JSON.",
+ "JSON exception occurred when mapping modules.", e);
+ }
+ }
+
@Override
public Object getResourceDataOperationalForCmHandle(final @NotNull String cmHandle,
final @NotNull String resourceIdentifier,
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
index 0c8ae3f..f24f65a 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy
@@ -20,11 +20,19 @@
package org.onap.cps.ncmp.dmi.rest.controller
+
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.dmi.TestUtils
import org.onap.cps.ncmp.dmi.exception.DmiException
import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException
import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException
+
import org.onap.cps.ncmp.dmi.model.ModuleReference
+import org.onap.cps.ncmp.dmi.model.ModuleSchemaList
+import org.onap.cps.ncmp.dmi.model.ModuleSchemaProperties
+import org.onap.cps.ncmp.dmi.model.ModuleSchemas
+import org.onap.cps.ncmp.dmi.model.ModuleSet
+import org.onap.cps.ncmp.dmi.model.ModuleSetSchemas
import org.onap.cps.ncmp.dmi.service.DmiService
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
@@ -47,6 +55,9 @@
@SpringBean
DmiService mockDmiService = Mock()
+ @SpringBean
+ ObjectMapper mockObjectMapper = Spy()
+
@Autowired
private MockMvc mvc
@@ -57,8 +68,14 @@
given: 'REST endpoint for getting all modules'
def getModuleUrl = "$basePathV1/ch/node1/modules"
and: 'get modules for cm-handle returns a json'
- def someJson = 'some-json'
- mockDmiService.getModulesForCmHandle('node1') >> someJson
+ def moduleSetSchema = new ModuleSetSchemas()
+ moduleSetSchema.namespace('some-namespace')
+ moduleSetSchema.moduleName('some-moduleName')
+ moduleSetSchema.revision('some-revision')
+ def moduleSetSchemasList = [moduleSetSchema] as List<ModuleSetSchemas>
+ def moduleSet = new ModuleSet()
+ moduleSet.schemas(moduleSetSchemasList)
+ mockDmiService.getModulesForCmHandle('node1') >> moduleSet
when: 'post is being called'
def response = mvc.perform(post(getModuleUrl)
.contentType(MediaType.APPLICATION_JSON))
@@ -66,7 +83,21 @@
then: 'status is OK'
response.status == HttpStatus.OK.value()
and: 'the response content matches the result from the DMI service'
- response.getContentAsString() == someJson
+ response.getContentAsString() == '{"schemas":[{"moduleName":"some-moduleName","revision":"some-revision","namespace":"some-namespace"}]}'
+ }
+
+ def 'Get all modules for given cm handle with invalid json.'() {
+ given: 'REST endpoint for getting all modules'
+ def getModuleUrl = "$basePathV1/ch/node1/modules"
+ and: 'get modules for cmHandle throws an exception'
+ mockObjectMapper.readValue(_ as String, _ as ModuleSchemaList) >> { throw Mock(DmiException.class) }
+ mockDmiService.getModulesForCmHandle('node1') >> 'some-value'
+ when: 'post is being called'
+ def response = mvc.perform(post(getModuleUrl)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andReturn().response
+ then: 'the status is as expected'
+ response.status == HttpStatus.INTERNAL_SERVER_ERROR.value()
}
def 'Get all modules for given cm handle with exception handling of #scenario.'() {
@@ -75,16 +106,16 @@
and: 'get modules for cm-handle throws #exceptionClass'
mockDmiService.getModulesForCmHandle('node1') >> { throw Mock(exceptionClass) }
when: 'post is invoked'
- def response = mvc.perform(post(getModuleUrl)
+ def response = mvc.perform( post(getModuleUrl)
.contentType(MediaType.APPLICATION_JSON))
.andReturn().response
then: 'response status is #expectedResponse'
response.status == expectedResponse
where: 'the scenario is #scenario'
- scenario | exceptionClass || expectedResponse
- 'dmi service exception' | DmiException.class || HttpStatus.INTERNAL_SERVER_ERROR.value()
- 'no modules found' | ModulesNotFoundException.class || HttpStatus.NOT_FOUND.value()
- 'any other runtime exception' | RuntimeException.class || HttpStatus.INTERNAL_SERVER_ERROR.value()
+ scenario | exceptionClass || expectedResponse
+ 'dmi service exception' | DmiException.class || HttpStatus.INTERNAL_SERVER_ERROR.value()
+ 'no modules found' | ModulesNotFoundException.class || HttpStatus.NOT_FOUND.value()
+ 'any other runtime exception' | RuntimeException.class || HttpStatus.INTERNAL_SERVER_ERROR.value()
}
def 'Register given list of cm handles.'() {
diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
index da8ff6b..e456d41 100644
--- a/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
+++ b/src/test/groovy/org/onap/cps/ncmp/dmi/service/DmiServiceImplSpec.groovy
@@ -22,6 +22,7 @@
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.ncmp.dmi.TestUtils
import org.onap.cps.ncmp.dmi.config.DmiPluginConfig
import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException
import org.onap.cps.ncmp.dmi.exception.DmiException
@@ -29,6 +30,8 @@
import org.onap.cps.ncmp.dmi.exception.ModulesNotFoundException
import org.onap.cps.ncmp.dmi.exception.ResourceDataNotFound
import org.onap.cps.ncmp.dmi.model.ModuleReference
+import org.onap.cps.ncmp.dmi.model.ModuleSchemaList
+import org.onap.cps.ncmp.dmi.model.ModuleSchemas
import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient
import org.onap.cps.ncmp.dmi.service.operation.SdncOperations
import org.springframework.http.HttpStatus
@@ -49,12 +52,25 @@
given: 'cm handle id'
def cmHandle = 'node1'
and: 'request operation returns OK'
- def body = 'body'
+ def body = TestUtils.getResourceFileContent('ModuleSchema.json')
mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>(body, HttpStatus.OK)
when: 'get modules for cm-handle is called'
def result = objectUnderTest.getModulesForCmHandle(cmHandle)
then: 'result is equal to the response from the SDNC service'
- result == body
+ result.toString().contains('moduleName: example-identifier')
+ result.toString().contains('revision: example-version')
+ }
+
+ def 'Call get modules for cm-handle with invalid json.'() {
+ given: 'cm handle id'
+ def cmHandle = 'node1'
+ and: 'request operation returns invalid json'
+ def body = TestUtils.getResourceFileContent('ModuleSchema.json')
+ mockSdncOperations.getModulesFromNode(cmHandle) >> new ResponseEntity<String>('invalid json', HttpStatus.OK)
+ when: 'get modules for cm-handle is called'
+ def result = objectUnderTest.getModulesForCmHandle(cmHandle)
+ then: 'a dmi exception is thrown'
+ thrown(DmiException)
}
def 'Call get modules for cm-handle and SDNC returns "bad request" status.'() {
diff --git a/src/test/resources/ModuleSchema.json b/src/test/resources/ModuleSchema.json
new file mode 100644
index 0000000..07a0a03
--- /dev/null
+++ b/src/test/resources/ModuleSchema.json
@@ -0,0 +1,15 @@
+{
+ "schemas": {
+ "schema": [
+ {
+ "identifier": "example-identifier",
+ "version": "example-version",
+ "format": "example-format",
+ "namespace": "example:namespace",
+ "location": [
+ "example-location"
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file