From 4f431887d66854589354c7361f2614f76420d738 Mon Sep 17 00:00:00 2001 From: niamhcore Date: Tue, 21 Sep 2021 16:08:29 +0100 Subject: Add get modules response type to openapi Issue-ID: CPS-657 Signed-off-by: niamhcore Change-Id: Ifcd22b6e82aaf4993f9071ad56b524fe620afaf7 --- docs/openapi/components.yml | 15 + docs/openapi/openapi.yaml | 428 --------------------- docs/openapi/openapi.yml | 6 +- pom.xml | 1 + .../dmi/rest/controller/DmiRestController.java | 8 +- .../org/onap/cps/ncmp/dmi/service/DmiService.java | 5 +- .../onap/cps/ncmp/dmi/service/DmiServiceImpl.java | 24 +- src/main/resources/spotbugs-exclude.xml | 54 +++ .../rest/controller/DmiRestControllerSpec.groovy | 19 +- .../cps/ncmp/dmi/service/DmiServiceImplSpec.groovy | 26 +- 10 files changed, 112 insertions(+), 474 deletions(-) delete mode 100644 docs/openapi/openapi.yaml create mode 100644 src/main/resources/spotbugs-exclude.xml diff --git a/docs/openapi/components.yml b/docs/openapi/components.yml index 3866b834..94742c82 100644 --- a/docs/openapi/components.yml +++ b/docs/openapi/components.yml @@ -58,6 +58,21 @@ components: namespace: type: string + YangResources: + type: array + items: + type: object + $ref: '#/components/schemas/YangResource' + + YangResource: + properties: + yangSource: + type: string + moduleName: + type: string + revision: + type: string + DataAccessReadRequest: type: object properties: diff --git a/docs/openapi/openapi.yaml b/docs/openapi/openapi.yaml deleted file mode 100644 index 037bc9fd..00000000 --- a/docs/openapi/openapi.yaml +++ /dev/null @@ -1,428 +0,0 @@ -openapi: 3.0.1 -info: - title: NCMP DMI Plugin - description: Adds Data Model Inventory Registry capability for ONAP - version: 1.0.0 -servers: -- url: //localhost:8088/ -tags: -- name: dmi-plugin-internal - description: DMI plugin internal rest apis -- name: dmi-plugin - description: DMI plugin rest apis -paths: - /v1/ch/{cmHandle}/modules: - post: - tags: - - dmi-plugin - summary: Get all modules for cm handle - description: Get all modules for given cm handle - operationId: getModulesForCmHandle - parameters: - - name: cmHandle - in: path - description: The cm handle to fetch all the modules - required: true - style: simple - explode: false - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ModuleSet' - "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/inventory/cmHandles: - post: - tags: - - dmi-plugin-internal - summary: register given list of cm handles (internal use only) - description: register given list of cm handles (internal use only) - operationId: registerCmHandles - requestBody: - description: list of cm handles - content: - application/json: - schema: - $ref: '#/components/schemas/CmHandles' - required: true - responses: - "201": - description: Created - content: - text/plain: - schema: - type: string - "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-api-audience: component-internal - /v1/ch/{cmHandle}/moduleResources: - post: - tags: - - dmi-plugin - summary: Retrieve module resources - description: Retrieve module resources for one or more modules - operationId: retrieveModuleResources - parameters: - - name: cmHandle - 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 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DmiReadRequestBody' - 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' - /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-operational/{resourceIdentifier}: - put: - tags: - - dmi-plugin - summary: Get resource data from passthrough-operational for cm handle - description: Get resource data from passthrough-operational for cm handle - operationId: getResourceDataOperationalForCmHandle - parameters: - - name: cmHandle - 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. - 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 - requestBody: - description: Operational body - content: - application/json: - schema: - $ref: '#/components/schemas/DataAccessReadRequest' - 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' - /v1/ch/{cmHandle}/data/ds/ncmp-datastore:passthrough-running/{resourceIdentifier}: - put: - tags: - - dmi-plugin - summary: Get resource data from passthrough-running for cm handle - description: Get resource data from passthrough-running for cm handle - operationId: getResourceDataPassthroughRunningForCmHandle - parameters: - - name: cmHandle - 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. - 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 - requestBody: - description: Operational body - content: - application/json: - schema: - $ref: '#/components/schemas/DataAccessReadRequest' - 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' - post: - tags: - - dmi-plugin - summary: Write data for a cmHandle - description: Write data for a cmHandle using passthrough-running - operationId: writeDataByPassthroughRunningForCmHandle - parameters: - - name: cmHandle - 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 - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DataAccessWriteRequest' - required: true - responses: - "201": - description: Created - content: - text/plain: - schema: - type: string - "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' -components: - schemas: - ModuleSet: - type: object - properties: - schemas: - type: array - items: - $ref: '#/components/schemas/ModuleSet_schemas' - ErrorMessage: - title: Error - type: object - properties: - status: - type: string - message: - type: string - details: - type: string - CmHandles: - type: object - properties: - cmHandles: - type: array - items: - type: string - DmiReadRequestBody: - type: object - properties: - operation: - type: string - enum: - - read - data: - $ref: '#/components/schemas/DmiReadRequestBody_data' - cmHandleProperties: - type: object - additionalProperties: - type: string - example: system-001 - DataAccessReadRequest: - type: object - properties: - operation: - type: string - enum: - - read - cmHandleProperties: - type: object - additionalProperties: - type: string - DataAccessWriteRequest: - type: object - properties: - operation: - type: string - enum: - - create - dataType: - type: string - data: - type: string - cmHandleProperties: - type: object - additionalProperties: - type: string - ModuleSet_schemas: - type: object - properties: - moduleName: - type: string - revision: - type: string - namespace: - type: string - DmiReadRequestBody_data_modules: - type: object - properties: - name: - type: string - revision: - type: string - DmiReadRequestBody_data: - type: object - properties: - modules: - type: array - items: - $ref: '#/components/schemas/DmiReadRequestBody_data_modules' diff --git a/docs/openapi/openapi.yml b/docs/openapi/openapi.yml index a9accdb9..716528b1 100644 --- a/docs/openapi/openapi.yml +++ b/docs/openapi/openapi.yml @@ -110,7 +110,11 @@ paths: $ref: 'components.yml#/components/schemas/DmiReadRequestBody' responses: '200': - $ref: 'components.yml#/components/responses/Ok' + description: OK + content: + application/json: + schema: + $ref: 'components.yml#/components/schemas/YangResources' '400': $ref: 'components.yml#/components/responses/BadRequest' '401': diff --git a/pom.xml b/pom.xml index 1836f227..2eca0b26 100644 --- a/pom.xml +++ b/pom.xml @@ -431,6 +431,7 @@ Low true spotbugs-exclude.xml + true true ${basedir}/target/spotbugs 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 37381fb1..9f192841 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 @@ -32,6 +32,7 @@ import org.onap.cps.ncmp.dmi.model.DataAccessWriteRequest; import org.onap.cps.ncmp.dmi.model.DmiReadRequestBody; import org.onap.cps.ncmp.dmi.model.ModuleReference; import org.onap.cps.ncmp.dmi.model.ModuleSet; +import org.onap.cps.ncmp.dmi.model.YangResources; import org.onap.cps.ncmp.dmi.rest.api.DmiPluginApi; import org.onap.cps.ncmp.dmi.rest.api.DmiPluginInternalApi; import org.onap.cps.ncmp.dmi.service.DmiService; @@ -62,17 +63,14 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi { } @Override - public ResponseEntity retrieveModuleResources(@Valid final DmiReadRequestBody dmiReadRequestBody, + public ResponseEntity retrieveModuleResources(@Valid final DmiReadRequestBody dmiReadRequestBody, final String cmHandle) { if (dmiReadRequestBody.getOperation().toString().equals("read")) { final var moduleReferenceList = convertRestObjectToJavaApiObject(dmiReadRequestBody); final var response = dmiService.getModuleResources(cmHandle, moduleReferenceList); - if (response.isEmpty()) { - return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); - } return new ResponseEntity<>(response, HttpStatus.OK); } - return new ResponseEntity<>("Unsupported operation", HttpStatus.CONFLICT); + return new ResponseEntity<>(HttpStatus.CONFLICT); } /** 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 7f79a04c..bd0dc600 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 @@ -26,6 +26,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; +import org.onap.cps.ncmp.dmi.model.YangResources; /** * Interface for handling Dmi plugin Data. @@ -54,9 +55,9 @@ public interface DmiService { * * @param cmHandle cmHandle * @param modules a list of module data - * @return returns all module resources + * @return returns all yang resources */ - String getModuleResources(String cmHandle, List modules); + YangResources getModuleResources(String cmHandle, List modules); /** * This method use to fetch the resource data from cm handle for datastore pass-through operational and resource 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 11668904..182bdd84 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 @@ -30,8 +30,6 @@ import java.util.List; import java.util.Map; import javax.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONArray; -import net.minidev.json.JSONObject; import org.apache.groovy.parser.antlr4.util.StringUtils; import org.onap.cps.ncmp.dmi.config.DmiPluginConfig.DmiPluginProperties; import org.onap.cps.ncmp.dmi.exception.CmHandleRegistrationException; @@ -46,6 +44,8 @@ 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.model.YangResource; +import org.onap.cps.ncmp.dmi.model.YangResources; import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient; import org.onap.cps.ncmp.dmi.service.operation.SdncOperations; import org.springframework.http.HttpStatus; @@ -100,13 +100,13 @@ public class DmiServiceImpl implements DmiService { } @Override - public String getModuleResources(final String cmHandle, final List moduleReferences) { - final var getModuleResponses = new JSONArray(); + public YangResources getModuleResources(final String cmHandle, final List moduleReferences) { + final YangResources yangResources = new YangResources(); for (final var moduleReference : moduleReferences) { final var moduleRequest = createModuleRequest(moduleReference); final ResponseEntity responseEntity = sdncOperations.getModuleResource(cmHandle, moduleRequest); if (responseEntity.getStatusCode() == HttpStatus.OK) { - getModuleResponses.add(toJsonObject(moduleReference, responseEntity)); + yangResources.add(toYangResource(moduleReference, responseEntity)); } else if (responseEntity.getStatusCode() == HttpStatus.NOT_FOUND) { log.error("SDNC did not return a module resource for the given cmHandle {}", cmHandle); throw new ModuleResourceNotFoundException(cmHandle, @@ -117,7 +117,7 @@ public class DmiServiceImpl implements DmiService { RESPONSE_CODE + responseEntity.getStatusCode() + MESSAGE + responseEntity.getBody()); } } - return getModuleResponses.toJSONString(); + return yangResources; } @Override @@ -248,13 +248,13 @@ public class DmiServiceImpl implements DmiService { return moduleRequest; } - private JSONObject toJsonObject(final ModuleReference moduleReference, + private YangResource toYangResource(final ModuleReference moduleReference, final ResponseEntity response) { - final var jsonObject = new JSONObject(); - jsonObject.put("moduleName", moduleReference.getName()); - jsonObject.put("revision", moduleReference.getRevision()); - jsonObject.put("yangSource", extractYangSourceFromBody(response)); - return jsonObject; + final YangResource yangResource = new YangResource(); + yangResource.setModuleName(moduleReference.getName()); + yangResource.setRevision(moduleReference.getRevision()); + yangResource.setYangSource(extractYangSourceFromBody(response)); + return yangResource; } private String extractYangSourceFromBody(final ResponseEntity responseEntity) { diff --git a/src/main/resources/spotbugs-exclude.xml b/src/main/resources/spotbugs-exclude.xml new file mode 100644 index 00000000..e8a1f6e2 --- /dev/null +++ b/src/main/resources/spotbugs-exclude.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 ac4fde3d..dd5e79da 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 @@ -30,6 +30,8 @@ import org.onap.cps.ncmp.dmi.model.ModuleReference import org.onap.cps.ncmp.dmi.model.ModuleSchemaList import org.onap.cps.ncmp.dmi.model.ModuleSet import org.onap.cps.ncmp.dmi.model.ModuleSetSchemas +import org.onap.cps.ncmp.dmi.model.YangResource +import org.onap.cps.ncmp.dmi.model.YangResources import org.onap.cps.ncmp.dmi.service.DmiService import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired @@ -149,15 +151,14 @@ class DmiRestControllerSpec extends Specification { given: 'an endpoint and json data' def getModulesEndpoint = "$basePathV1/ch/some-cm-handle/moduleResources" def jsonData = TestUtils.getResourceFileContent('GetModules.json') - and: 'the DMI service returns some json data' - ModuleReference moduleReference1 = new ModuleReference() - moduleReference1.name = 'ietf-yang-library' - moduleReference1.revision = '2016-06-21' - ModuleReference moduleReference2 = new ModuleReference() - moduleReference2.name = 'nc-notifications' - moduleReference2.revision = '2008-07-14' + and: 'the DMI service returns the yang resources' + ModuleReference moduleReference1 = new ModuleReference(name: 'ietf-yang-library', revision: '2016-06-21') + ModuleReference moduleReference2 = new ModuleReference(name: 'nc-notifications', revision: '2008-07-14') def moduleReferences = [moduleReference1, moduleReference2] - mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> '{some-json}' + def yangResources = new YangResources() + def yangResource = new YangResource(yangSource: '"some-data"', moduleName: 'NAME', revision: 'REVISION') + yangResources.add(yangResource) + mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> yangResources when: 'get module resource api is invoked' def response = mvc.perform(post(getModulesEndpoint) .contentType(MediaType.APPLICATION_JSON) @@ -165,7 +166,7 @@ class DmiRestControllerSpec extends Specification { then: 'a OK status is returned' response.status == HttpStatus.OK.value() and: 'the expected response is returned' - response.getContentAsString() == '{some-json}' + response.getContentAsString() == '[{"yangSource":"\\"some-data\\"","moduleName":"NAME","revision":"REVISION"}]' } def 'Retrieve module resources with exception handling.'() { 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 c1700a2e..93bc641e 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 @@ -30,6 +30,8 @@ import org.onap.cps.ncmp.dmi.exception.ModuleResourceNotFoundException 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.YangResource +import org.onap.cps.ncmp.dmi.model.YangResources import org.onap.cps.ncmp.dmi.service.client.NcmpRestClient import org.onap.cps.ncmp.dmi.service.operation.SdncOperations import org.springframework.http.HttpStatus @@ -134,21 +136,6 @@ class DmiServiceImplSpec extends Specification { thrown(DmiException.class) } - def 'Get a single module resource.'() { - given: 'a cmHandle and module reference list' - def cmHandle = 'some-cmHandle' - def moduleReference = new ModuleReference(name: 'NAME',revision: 'REVISION') - def moduleList = [moduleReference] - and: 'the sdnc request body contains the correct name and revision' - def expectedRequestBody = '{"ietf-netconf-monitoring:input":{"ietf-netconf-monitoring:identifier":"NAME","ietf-netconf-monitoring:version":"REVISION"}}' - when: 'get module resources is invoked with the given cm handle and a module list' - def result = objectUnderTest.getModuleResources(cmHandle, moduleList) - then: 'get modules resources is called once with the expected cm handle and request body' - 1 * mockSdncOperations.getModuleResource(cmHandle, expectedRequestBody) >> new ResponseEntity('{"ietf-netconf-monitoring:output": {"data": "some-data"}}', HttpStatus.OK) - and: 'the result is an array containing one json object with the expected name, revision and yang-source' - assert result == '[{"yangSource":"\\"some-data\\"","moduleName":"NAME","revision":"REVISION"}]' - } - def 'Get multiple module resources.'() { given: 'a cmHandle and module reference list' def cmHandle = 'some-cmHandle' @@ -160,8 +147,13 @@ class DmiServiceImplSpec extends Specification { then: 'get modules resources is called twice' 2 * mockSdncOperations.getModuleResource(cmHandle, _) >>> [new ResponseEntity('{"ietf-netconf-monitoring:output": {"data": "some-data1"}}', HttpStatus.OK), new ResponseEntity('{"ietf-netconf-monitoring:output": {"data": "some-data2"}}', HttpStatus.OK)] - and: 'the result is an array containing json objects with the expected name, revision and yang-source' - assert result == '[{"yangSource":"\\"some-data1\\"","moduleName":"name-1","revision":"revision-1"},{"yangSource":"\\"some-data2\\"","moduleName":"name-2","revision":"revision-2"}]' + and: 'the result is a yang resources object with the expected names, revisions and yang-sources' + def yangResources = new YangResources() + def yangResource1 = new YangResource(yangSource: '"some-data1"', moduleName: 'name-1', revision: 'revision-1') + def yangResource2 = new YangResource(yangSource: '"some-data2"', moduleName: 'name-2', revision: 'revision-2') + yangResources.add(yangResource1) + yangResources.add(yangResource2) + assert result == yangResources } def 'Get a module resource with module resource not found exception for #scenario.'() { -- cgit 1.2.3-korg