diff options
-rw-r--r-- | INFO.yaml | 2 | ||||
-rw-r--r-- | docs/api/swagger/openapi-datajob.yaml | 167 | ||||
-rw-r--r-- | docs/api/swagger/openapi.yaml | 22 | ||||
-rw-r--r-- | docs/release-notes.rst | 27 | ||||
-rw-r--r-- | openapi/components.yml | 26 | ||||
-rw-r--r-- | openapi/openapi-datajob.yml | 240 | ||||
-rw-r--r-- | openapi/openapi.yml | 1 | ||||
-rw-r--r-- | pom.xml | 4 | ||||
-rw-r--r-- | releases/1.5.0-container.yaml | 9 | ||||
-rw-r--r-- | releases/1.5.0.yaml | 4 | ||||
-rw-r--r-- | src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java | 2 | ||||
-rw-r--r-- | src/main/java/org/onap/cps/ncmp/dmi/rest/controller/DmiRestController.java | 16 | ||||
-rw-r--r-- | src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy | 24 | ||||
-rw-r--r-- | src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy | 11 | ||||
-rw-r--r-- | src/test/groovy/org/onap/cps/ncmp/dmi/rest/controller/DmiRestControllerSpec.groovy | 62 | ||||
-rw-r--r-- | src/test/resources/moduleResources.json | 3 | ||||
-rw-r--r-- | version.properties | 2 |
17 files changed, 450 insertions, 172 deletions
@@ -19,7 +19,7 @@ --- project: 'ncmp-dmi-plugin' project_creation_date: '2021-05-24' -lifecycle_state: 'Incubation' +lifecycle_state: 'Mature' project_category: '' project_lead: &onap_releng_ptl name: 'Toine Siebelink' diff --git a/docs/api/swagger/openapi-datajob.yaml b/docs/api/swagger/openapi-datajob.yaml index 04a5bf1d..b3baa168 100644 --- a/docs/api/swagger/openapi-datajob.yaml +++ b/docs/api/swagger/openapi-datajob.yaml @@ -5,40 +5,69 @@ info: title: NCMP Data Subjob API version: 1.0.0 servers: - - url: /dmi +- url: /dmi tags: - - description: DMI plugin rest apis - name: dmi-datajob +- description: DMI plugin rest apis + name: dmi-datajob paths: - /v1/dataJob/{requestId}: + /dmi/v1/readJob/{requestId}: post: description: Create a read request - operationId: createReadRequest + operationId: readDataJob parameters: - - description: Identifier for the overall Datajob - explode: false - in: path - name: requestId - required: true - schema: - example: some-identifier - type: string - style: simple + - description: Identifier for the overall Datajob + explode: false + in: path + name: requestId + required: true + schema: + example: some-identifier + type: string + style: simple requestBody: content: application/3gpp-json-patch+json: schema: - $ref: '#/components/schemas/SubjobRequest' + $ref: '#/components/schemas/SubjobReadRequest' description: Operation body responses: "200": content: application/json: schema: - $ref: '#/components/schemas/createReadRequest_200_response' + $ref: '#/components/schemas/readDataJob_200_response' description: Response for subjob tags: - - dmi-datajob + - dmi-datajob + /dmi/v1/writeJob/{requestId}: + post: + description: Create a write request + operationId: writeDataJob + parameters: + - description: Identifier for the overall Datajob + explode: false + in: path + name: requestId + required: true + schema: + example: some-identifier + type: string + style: simple + requestBody: + content: + application/3gpp-json-patch+json: + schema: + $ref: '#/components/schemas/SubjobWriteRequest' + description: Operation body + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/readDataJob_200_response' + description: Response for subjob + tags: + - dmi-datajob components: parameters: requestIdInPath: @@ -52,7 +81,7 @@ components: type: string style: simple schemas: - SubjobRequest: + SubjobReadRequest: properties: dataAcceptType: description: Defines the data response accept type @@ -68,33 +97,50 @@ components: example: my-data-producer-identifier type: string data: - $ref: '#/components/schemas/SubjobRequest_data' + example: + op: read + operationId: 1 + path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=2 + attributes: userLabel + scope: + scopeTyp: BASE_ONLY + items: + $ref: '#/components/schemas/SubjobReadRequest_data_inner' + type: array required: - - data - - dataProducerId + - data + - dataProducerId + type: object + SubjobWriteRequest: + properties: + dataAcceptType: + description: Defines the data response accept type + example: application/vnd.3gpp.object-tree-hierarchical+json + type: string + dataContentType: + description: Defines the data request content type + example: application/3gpp-json-patch+json + type: string + dataProducerId: + description: ID of the producer registered by DMI for the paths in the operations + in this request + example: my-data-producer-identifier + type: string + data: + example: + op: add + path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=1/EUtraNetwork=1/EUtranFrequency=12 + value: + id: 12 + attributes: + userLabel: label12 + items: + $ref: '#/components/schemas/SubjobWriteRequest_data_inner' + type: array + required: + - data + - dataProducerId type: object - ReadOperation: - example: - op: read - operationId: 1 - path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=2 - attributes: userLabel - scope: - scopeTyp: BASE_ONLY - items: - $ref: '#/components/schemas/ReadOperation_inner' - type: array - WriteOperation: - example: - op: add - path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=1/EUtraNetwork=1/EUtranFrequency=12 - value: - id: 12 - attributes: - userLabel: label12 - items: - $ref: '#/components/schemas/WriteOperation_inner' - type: array CmHandleProperties: description: Private properties of the cm handle for the given path type: object @@ -119,7 +165,7 @@ components: type: object Object: type: object - createReadRequest_200_response: + readDataJob_200_response: example: dataProducerJobId: dataProducerJobId properties: @@ -127,11 +173,7 @@ components: description: The data job ID. type: string type: object - SubjobRequest_data: - oneOf: - - $ref: '#/components/schemas/ReadOperation' - - $ref: '#/components/schemas/WriteOperation' - ReadOperation_inner: + SubjobReadRequest_data_inner: properties: path: description: Defines the resource on which operation is executed @@ -181,18 +223,18 @@ components: description: Private properties of the cm handle for the given path type: object required: - - op - - path + - op + - path type: object - WriteOperation_inner_value: + SubjobWriteRequest_data_inner_value: description: Value dependent on the op specified. Resource for an add. Object for a replace. ActionParameters for an action. oneOf: - - $ref: '#/components/schemas/Resource' - - $ref: '#/components/schemas/ActionParameters' - - $ref: '#/components/schemas/Object' + - $ref: '#/components/schemas/Resource' + - $ref: '#/components/schemas/ActionParameters' + - $ref: '#/components/schemas/Object' type: object - WriteOperation_inner: + SubjobWriteRequest_data_inner: properties: path: description: Defines the resource on which operation is executed @@ -206,9 +248,16 @@ components: description: Unique identifier for the operation within the request example: "1" type: string + moduleSetTag: + description: Module set identifier + example: my-module-set-tag + type: string + cmHandleProperties: + description: Private properties of the cm handle for the given path + type: object value: - $ref: '#/components/schemas/WriteOperation_inner_value' + $ref: '#/components/schemas/SubjobWriteRequest_data_inner_value' required: - - op - - path + - op + - path type: object diff --git a/docs/api/swagger/openapi.yaml b/docs/api/swagger/openapi.yaml index 4e3ae897..0f690ef5 100644 --- a/docs/api/swagger/openapi.yaml +++ b/docs/api/swagger/openapi.yaml @@ -209,6 +209,15 @@ paths: required: false schema: type: string + - name: moduleSetTag + description: Module set tag of the given cm handle. + in: query + examples: + sample1: + value: module-set-tag1 + required: false + schema: + type: string requestBody: content: application/json: @@ -379,6 +388,16 @@ components: required: false schema: type: string + moduleSetTagParamInQuery: + name: moduleSetTag + in: query + description: Module set tag of the given cm handle. + required: false + schema: + type: string + examples: + sample1: + value: module-set-tag1 requiredTopicParamInQuery: allowReserved: true description: mandatory topic name passed from client(NCMP). @@ -493,6 +512,7 @@ components: type: object ModuleResourcesReadRequest: example: + moduleSetTag: module-set-tag1 data: modules: - name: my-name @@ -651,10 +671,12 @@ components: cmHandleProperties: myProp: some value otherProp: other value + moduleSetTag: module-set-tag1 - id: cmHandle123 cmHandleProperties: myProp: some value otherProp: other value + moduleSetTag: module-set-tag2 operation: read properties: operation: diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 209c9897..75ece03f 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -19,6 +19,29 @@ DMI-Plugin Release Notes .. * * * NEW DELHI * * * .. ========================= +Version: 1.5.1 +============== + +Release Data +------------ + ++--------------------------------------+--------------------------------------------------------+ +| **CPS Project** | DMI-Plugin | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Docker images** | onap/ncmp-dmi-plugin:1.5.1 | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release designation** | 1.5.1 New Delhi | +| | | ++--------------------------------------+--------------------------------------------------------+ +| **Release date** | (not yet released) | +| | | ++--------------------------------------+--------------------------------------------------------+ + +Features +-------- + Version: 1.5.0 ============== @@ -32,10 +55,10 @@ Release Data | **Docker images** | onap/ncmp-dmi-plugin:1.5.0 | | | | +--------------------------------------+--------------------------------------------------------+ -| **Release designation** | 1.5.0 Montreal | +| **Release designation** | 1.5.0 New Delhi | | | | +--------------------------------------+--------------------------------------------------------+ -| **Release date** | 2024 April 3 | +| **Release date** | 2024 May 14 | | | | +--------------------------------------+--------------------------------------------------------+ diff --git a/openapi/components.yml b/openapi/components.yml index 00d71564..ae9710b1 100644 --- a/openapi/components.yml +++ b/openapi/components.yml @@ -76,31 +76,40 @@ components: cmHandles: type: array items: - $ref: '#/components/schemas/cmHandle' + $ref: '#/components/schemas/dmiOperationCmHandle' required: - operation - operationId - datastore - cmHandles - cmHandle: + dmiOperationCmHandle: type: object - title: 'cmHandle' + title: 'CmHandle with properties for DMI' properties: id: type: string cmHandleProperties: additionalProperties: type: string + moduleSetTag: + type: string + example: module-set-tag1 example: id: cmHandle123 cmHandleProperties: myProp: some value otherProp: other value + moduleSetTag: module-set-tag1 ModuleResourcesReadRequest: type: object properties: + moduleSetTag: + type: string + description: Module set tag of the given cm handle + example: Module-set-tag-1 + required: false data: type: object properties: @@ -292,6 +301,17 @@ components: value: topic: my-topic-name + moduleSetTagParamInQuery: + name: moduleSetTag + in: query + description: Module set tag of the given cm handle. + required: false + schema: + type: string + examples: + sample1: + value: tag1 + requiredRequestIdParamInQuery: name: requestId in: query diff --git a/openapi/openapi-datajob.yml b/openapi/openapi-datajob.yml index b572ff3e..8a0f315b 100644 --- a/openapi/openapi-datajob.yml +++ b/openapi/openapi-datajob.yml @@ -27,10 +27,10 @@ tags: - description: DMI plugin rest apis name: dmi-datajob paths: - /v1/dataJob/{requestId}: + /dmi/v1/readJob/{requestId}: post: description: Create a read request - operationId: createReadRequest + operationId: readDataJob parameters: - $ref: '#/components/parameters/requestIdInPath' requestBody: @@ -38,7 +38,32 @@ paths: content: application/3gpp-json-patch+json: schema: - $ref: '#/components/schemas/SubjobRequest' + $ref: '#/components/schemas/SubjobReadRequest' + tags: + - dmi-datajob + responses: + "200": + description: Response for subjob + content: + application/json: + schema: + type: object + properties: + dataProducerJobId: + type: string + description: The data job ID. + /dmi/v1/writeJob/{requestId}: + post: + description: Create a write request + operationId: writeDataJob + parameters: + - $ref: '#/components/parameters/requestIdInPath' + requestBody: + description: Operation body + content: + application/3gpp-json-patch+json: + schema: + $ref: '#/components/schemas/SubjobWriteRequest' tags: - dmi-datajob responses: @@ -63,7 +88,7 @@ components: example: some-identifier type: string schemas: - SubjobRequest: + SubjobReadRequest: type: object required: - dataProducerId @@ -82,100 +107,121 @@ components: example: my-data-producer-identifier type: string data: - oneOf: - - $ref: '#/components/schemas/ReadOperation' - - $ref: '#/components/schemas/WriteOperation' - ReadOperation: - example: - op: read - operationId: 1 - path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=2 - attributes: userLabel - scope: - scopeTyp: BASE_ONLY - type: array - items: - type: object - required: - - path - - op - properties: - path: - description: Defines the resource on which operation is executed - example: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003 - type: string - op: - description: Describes the operation to execute - example: read - type: string - operationId: - description: Unique identifier for the operation within the request - example: 1 - type: string - attributes: - description: This parameter specifies the attributes of the scoped resources that are returned - type: array - items: - example: cellId - type: string - fields: - description: This parameter specifies the attribute fields of the scoped resources that are returned - type: array - items: - type: string - filter: - description: This parameter is used to filter the scoped Managed Objects. Only Managed Objects passing the filter criteria will be fetched - example: NRCellDU/attributes/administrativeState==LOCKED - type: string - scopeType: - description: ScopeType selects MOs depending on relationships with Base Managed Object - example: BASE_ONLY - type: string - scopeLevel: - description: Only used when the scope type is BASE_NTH_LEVEL to specify amount of levels to search - example: 0 - type: integer - moduleSetTag: - description: Module set identifier - example: my-module-set-tag - type: string - cmHandleProperties: - description: Private properties of the cm handle for the given path - $ref: '#/components/schemas/CmHandleProperties' - WriteOperation: - example: - op: add - path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=1/EUtraNetwork=1/EUtranFrequency=12 - value: - id: 12 - attributes: - userLabel: label12 - type: array - items: - type: object - required: - - path - - op - properties: - path: - description: Defines the resource on which operation is executed - example: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003 - type: string - op: - description: Describes the operation to execute - example: add - type: string - operationId: - description: Unique identifier for the operation within the request - example: 1 - type: string - value: - description: Value dependent on the op specified. Resource for an add. Object for a replace. ActionParameters for an action. + example: + op: read + operationId: 1 + path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=2 + attributes: userLabel + scope: + scopeTyp: BASE_ONLY + type: array + items: type: object - oneOf: - - $ref: '#/components/schemas/Resource' - - $ref: '#/components/schemas/ActionParameters' - - $ref: '#/components/schemas/Object' + required: + - path + - op + properties: + path: + description: Defines the resource on which operation is executed + example: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003 + type: string + op: + description: Describes the operation to execute + example: read + type: string + operationId: + description: Unique identifier for the operation within the request + example: 1 + type: string + attributes: + description: This parameter specifies the attributes of the scoped resources that are returned + type: array + items: + example: cellId + type: string + fields: + description: This parameter specifies the attribute fields of the scoped resources that are returned + type: array + items: + type: string + filter: + description: This parameter is used to filter the scoped Managed Objects. Only Managed Objects passing the filter criteria will be fetched + example: NRCellDU/attributes/administrativeState==LOCKED + type: string + scopeType: + description: ScopeType selects MOs depending on relationships with Base Managed Object + example: BASE_ONLY + type: string + scopeLevel: + description: Only used when the scope type is BASE_NTH_LEVEL to specify amount of levels to search + example: 0 + type: integer + moduleSetTag: + description: Module set identifier + example: my-module-set-tag + type: string + cmHandleProperties: + description: Private properties of the cm handle for the given path + $ref: '#/components/schemas/CmHandleProperties' + SubjobWriteRequest: + type: object + required: + - dataProducerId + - data + properties: + dataAcceptType: + description: Defines the data response accept type + example: application/vnd.3gpp.object-tree-hierarchical+json + type: string + dataContentType: + description: Defines the data request content type + example: application/3gpp-json-patch+json + type: string + dataProducerId: + description: ID of the producer registered by DMI for the paths in the operations in this request + example: my-data-producer-identifier + type: string + data: + example: + op: add + path: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003/GNBCUCPFunction=1/EUtraNetwork=1/EUtranFrequency=12 + value: + id: 12 + attributes: + userLabel: label12 + type: array + items: + type: object + required: + - path + - op + properties: + path: + description: Defines the resource on which operation is executed + example: SubNetwork=Europe/SubNetwork=Ireland/MeContext=NR03gNodeBRadio00003/ManagedElement=NR03gNodeBRadio00003 + type: string + op: + description: Describes the operation to execute + example: add + type: string + operationId: + description: Unique identifier for the operation within the request + example: 1 + type: string + moduleSetTag: + description: Module set identifier + example: my-module-set-tag + type: string + cmHandleProperties: + description: Private properties of the cm handle for the given path + $ref: '#/components/schemas/CmHandleProperties' + value: + description: Value dependent on the op specified. Resource for an add. Object for a replace. ActionParameters for an action. + type: object + oneOf: + - $ref: '#/components/schemas/Resource' + - $ref: '#/components/schemas/ActionParameters' + - $ref: '#/components/schemas/Object' CmHandleProperties: description: Private properties of the cm handle for the given path type: object diff --git a/openapi/openapi.yml b/openapi/openapi.yml index 6dbc19f3..38f21c15 100644 --- a/openapi/openapi.yml +++ b/openapi/openapi.yml @@ -128,6 +128,7 @@ paths: - $ref: 'components.yml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yml#/components/parameters/optionsParamInQuery' - $ref: 'components.yml#/components/parameters/topicParamInQuery' + - $ref: 'components.yml#/components/parameters/moduleSetTagParamInQuery' requestBody: description: Contains collection of cm handles with it's private properties and requestId content: @@ -34,13 +34,13 @@ </organization> <groupId>org.onap.cps</groupId> <artifactId>ncmp-dmi-plugin</artifactId> - <version>1.5.0-SNAPSHOT</version> + <version>1.6.0-SNAPSHOT</version> <name>ncmp-dmi-plugin</name> <description>DMI Plugin Service</description> <properties> <app>org.onap.cps.ncmp.dmi.Application</app> <base.image>${docker.pull.registry}/onap/integration-java17:12.0.0</base.image> - <cps.version>3.4.6</cps.version> + <cps.version>3.4.9</cps.version> <image.tag>${project.version}-${maven.build.timestamp}</image.tag> <jacoco.minimum.coverage>0.98</jacoco.minimum.coverage> <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format> diff --git a/releases/1.5.0-container.yaml b/releases/1.5.0-container.yaml new file mode 100644 index 00000000..b6ab4784 --- /dev/null +++ b/releases/1.5.0-container.yaml @@ -0,0 +1,9 @@ +distribution_type: container +container_release_tag: 1.5.0 +project: cps/ncmp-dmi-plugin +log_dir: cps-ncmp-dmi-plugin-maven-docker-stage-master/699/ +ref: 1a83551a2f8b5082399934f9320e9491c372c37f +tag_release: true +containers: + - name: 'ncmp-dmi-plugin' + version: '1.5.0-20240514T113617Z' diff --git a/releases/1.5.0.yaml b/releases/1.5.0.yaml new file mode 100644 index 00000000..3d13559f --- /dev/null +++ b/releases/1.5.0.yaml @@ -0,0 +1,4 @@ +distribution_type: maven +log_dir: cps-ncmp-dmi-plugin-maven-stage-master/699/ +project: cps/ncmp-dmi-plugin +version: 1.5.0
\ No newline at end of file diff --git a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java b/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java index ecfef6f3..da6243ca 100644 --- a/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java +++ b/src/main/java/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumer.java @@ -91,7 +91,7 @@ public class CmNotificationSubscriptionDmiInEventConsumer { if (cmNotificationSubscriptionStatus.equals(CmNotificationSubscriptionStatus.ACCEPTED)) { cmNotificationSubscriptionDmiOutEventData.setStatusCode("1"); cmNotificationSubscriptionDmiOutEventData.setStatusMessage("ACCEPTED"); - } else if (cmNotificationSubscriptionStatus.equals(CmNotificationSubscriptionStatus.REJECTED)) { + } else { cmNotificationSubscriptionDmiOutEventData.setStatusCode("2"); cmNotificationSubscriptionDmiOutEventData.setStatusMessage("REJECTED"); } 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 2ed1ebd3..ec56884c 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 @@ -80,13 +80,13 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi { return ResponseEntity.ok(moduleSet); } - @Override public ResponseEntity<YangResources> retrieveModuleResources( final String cmHandle, final ModuleResourcesReadRequest moduleResourcesReadRequest) { final List<ModuleReference> moduleReferences = convertRestObjectToJavaApiObject(moduleResourcesReadRequest); final YangResources yangResources = dmiService.getModuleResources(cmHandle, moduleReferences); + log.info("Module set tag received: {}", moduleResourcesReadRequest.getModuleSetTag()); return new ResponseEntity<>(yangResources, HttpStatus.OK); } @@ -116,6 +116,17 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi { @Override public ResponseEntity<Void> getResourceDataForCmHandleDataOperation(final String topic, final String requestId, final ResourceDataOperationRequests resourceDataOperationRequests) { + log.info("Request Details (for testing purposes)"); + log.info("Request Id: {}", requestId); + log.info("Topic: {}", topic); + + log.info("Details of the first Operation"); + log.info("Resource Identifier: {}", resourceDataOperationRequests.get(0).getResourceIdentifier()); + log.info("Module Set Tag: {}", resourceDataOperationRequests.get(0).getCmHandles().get(0).getModuleSetTag()); + log.info("Operation Id: {}", resourceDataOperationRequests.get(0).getOperationId()); + log.info("Cm Handles: {}", resourceDataOperationRequests.get(0).getCmHandles()); + log.info("Options: {}", resourceDataOperationRequests.get(0).getOptions()); + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } @@ -138,7 +149,10 @@ public class DmiRestController implements DmiPluginApi, DmiPluginInternalApi { final String resourceIdentifier, final String optionsParamInQuery, final String topicParamInQuery, + final String moduleSetTagParamInQuery, final DataAccessRequest dataAccessRequest) { + + log.info("Module set tag received: {}", moduleSetTagParamInQuery); if (DatastoreType.PASSTHROUGH_OPERATIONAL == DatastoreType.fromDatastoreName(datastoreName)) { return dataAccessPassthroughOperational(resourceIdentifier, cmHandle, dataAccessRequest, optionsParamInQuery, topicParamInQuery); diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy index 7ca2d54c..12ca05cf 100644 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy +++ b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/async/AsyncTaskExecutorIntegrationSpec.groovy @@ -23,6 +23,7 @@ package org.onap.cps.ncmp.dmi.notifications.async import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.dmi.api.kafka.MessagingBaseSpec import org.onap.cps.ncmp.dmi.exception.HttpClientRequestException +import org.onap.cps.ncmp.dmi.model.DataAccessRequest import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent import org.spockframework.spring.SpringBean import org.springframework.boot.test.context.SpringBootTest @@ -31,6 +32,7 @@ import org.springframework.test.annotation.DirtiesContext import org.testcontainers.spock.Testcontainers import java.time.Duration +import java.util.function.Supplier @SpringBootTest(classes = [AsyncTaskExecutor, DmiAsyncRequestResponseEventProducer]) @Testcontainers @@ -42,6 +44,7 @@ class AsyncTaskExecutorIntegrationSpec extends MessagingBaseSpec { new DmiAsyncRequestResponseEventProducer(kafkaTemplate) def spiedObjectMapper = Spy(ObjectMapper) + def mockSupplier = Mock(Supplier) def objectUnderTest = new AsyncTaskExecutor(cpsAsyncRequestResponseEventProducer) @@ -83,4 +86,25 @@ class AsyncTaskExecutorIntegrationSpec extends MessagingBaseSpec { assert event.getEventContent().getResponseCode() == '500' } + def 'Execute an Async Task using asyncTaskExecutor and throw an error'() { + given: 'A task to be executed' + def requestId = '123456' + def operationEnum = DataAccessRequest.OperationEnum.CREATE + def timeOut = 100 + when: 'AsyncTask has been executed' + objectUnderTest.executeAsyncTask(taskSupplierForFailingTask(), TEST_TOPIC, requestId, operationEnum, timeOut) + def records = kafkaConsumer.poll(Duration.ofMillis(1500)) + then: 'the record received is the event sent' + def record = records.iterator().next() + DmiAsyncRequestResponseEvent event = spiedObjectMapper.readValue(record.value(), DmiAsyncRequestResponseEvent) + and: 'the status & code matches expected' + assert event.getEventContent().getResponseStatus() == 'Internal Server Error' + assert event.getEventContent().getResponseCode() == '500' + + } + + def taskSupplierForFailingTask() { + return () -> { throw new RuntimeException('original exception message') } + } + }
\ No newline at end of file diff --git a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy index 47953439..aa331c4b 100644 --- a/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy +++ b/src/test/groovy/org/onap/cps/ncmp/dmi/notifications/cmsubscription/CmNotificationSubscriptionDmiInEventConsumerSpec.groovy @@ -73,23 +73,28 @@ class CmNotificationSubscriptionDmiInEventConsumerSpec extends MessagingBaseSpec objectUnderTest.dmiName = 'test-ncmp-dmi' objectUnderTest.cmNotificationSubscriptionResponseTopic = testTopic def correlationId = 'test-subscriptionId#test-ncmp-dmi' - def cmSubscriptionDmiOutEventData = new Data(statusCode: '1', statusMessage: 'ACCEPTED') + def cmSubscriptionDmiOutEventData = new Data(statusCode: subscriptionStatusCode, statusMessage: subscriptionStatusMessage) def subscriptionEventResponse = new CmNotificationSubscriptionDmiOutEvent().withData(cmSubscriptionDmiOutEventData) and: 'consumer has a subscription' kafkaConsumer.subscribe([testTopic] as List<String>) when: 'an event is published' def eventKey = UUID.randomUUID().toString() - objectUnderTest.createAndSendCmNotificationSubscriptionDmiOutEvent(eventKey, "subscriptionCreatedStatus", correlationId, CmNotificationSubscriptionStatus.ACCEPTED) + objectUnderTest.createAndSendCmNotificationSubscriptionDmiOutEvent(eventKey, "subscriptionCreatedStatus", correlationId, subscriptionAcceptanceType) and: 'topic is polled' def records = kafkaConsumer.poll(Duration.ofMillis(1500)) - then: 'poll returns one record' + then: 'poll returns one record and close kafkaConsumer' assert records.size() == 1 def record = records.iterator().next() + kafkaConsumer.close() and: 'the record value matches the expected event value' def expectedValue = objectMapper.writeValueAsString(subscriptionEventResponse) assert expectedValue == record.value assert eventKey == record.key + where: 'given #scenario' + scenario | subscriptionAcceptanceType | subscriptionStatusCode | subscriptionStatusMessage + 'Subscription is Accepted' | CmNotificationSubscriptionStatus.ACCEPTED | '1' | 'ACCEPTED' + 'Subscription is Rejected' | CmNotificationSubscriptionStatus.REJECTED | '2' | 'REJECTED' } def 'Consume valid message.'() { 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 7b2570b0..23b039bd 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 @@ -21,6 +21,10 @@ package org.onap.cps.ncmp.dmi.rest.controller + +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.read.ListAppender import org.onap.cps.ncmp.dmi.TestUtils import org.onap.cps.ncmp.dmi.config.WebSecurityConfig import org.onap.cps.ncmp.dmi.exception.DmiException @@ -34,6 +38,7 @@ import org.onap.cps.ncmp.dmi.notifications.async.AsyncTaskExecutor import org.onap.cps.ncmp.dmi.notifications.async.DmiAsyncRequestResponseEventProducer import org.onap.cps.ncmp.dmi.service.DmiService import org.onap.cps.ncmp.dmi.service.model.ModuleReference +import org.slf4j.LoggerFactory import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -75,6 +80,17 @@ class DmiRestControllerSpec extends Specification { @SpringBean AsyncTaskExecutor asyncTaskExecutor = new AsyncTaskExecutor(cpsAsyncRequestResponseEventProducer) + def logger = Spy(ListAppender<ILoggingEvent>) + + void setup() { + ((Logger) LoggerFactory.getLogger(DmiRestController.class)).addAppender(logger) + logger.start() + } + + void cleanup() { + ((Logger) LoggerFactory.getLogger(DmiRestController.class)).detachAndStopAllAppenders() + } + @Value('${rest.api.dmi-base-path}/v1') def basePathV1 @@ -189,6 +205,26 @@ class DmiRestControllerSpec extends Specification { response.status == HttpStatus.NOT_FOUND.value() } + def 'Retrieve module resources and ensure module set tag is logged.'() { + given: 'URL to get module resources' + def getModulesEndpoint = "$basePathV1/ch/some-cm-handle/moduleResources" + and: 'request data to get some modules' + String jsonData = TestUtils.getResourceFileContent('moduleResources.json') + and: 'the DMI service returns the yang resources' + def moduleReferences = [] + def yangResources = new YangResources() + def yangResource = new YangResource() + yangResources.add(yangResource) + mockDmiService.getModuleResources('some-cm-handle', moduleReferences) >> yangResources + when: 'the request is posted' + mvc.perform(post(getModulesEndpoint) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonData)) + then: 'the module set tag is logged' + def loggingMessage = getLoggingMessage(0) + assert loggingMessage.contains('module-set-tag1') + } + def 'Get resource data for pass-through operational.'() { given: 'Get resource data url and some request data' def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-operational" + @@ -302,6 +338,19 @@ class DmiRestControllerSpec extends Specification { resourceIdentifier << ['passthrough-operational', 'passthrough-running'] } + def 'PassThrough logs module set tag'(){ + given: 'Passthrough read URL and request data with a module set tag (parameter)' + def readPassThroughUrl ="${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:" + + 'passthrough-running?resourceIdentifier=some-resourceIdentifier&moduleSetTag=module-set-tag1' + def jsonData = TestUtils.getResourceFileContent('readData.json') + when: 'the request is posted' + mvc.perform( + post(readPassThroughUrl).contentType(MediaType.APPLICATION_JSON).content(jsonData)) + then: 'response status is OK' + def loggingMessage = getLoggingMessage(0) + assert loggingMessage.contains('module-set-tag1') + } + def 'Get resource data for pass-through running with #scenario value in resource identifier param.'() { given: 'Get resource data url' def getResourceDataForCmHandleUrl = "${basePathV1}/ch/some-cmHandle/data/ds/ncmp-datastore:passthrough-running" + @@ -335,12 +384,23 @@ class DmiRestControllerSpec extends Specification { def resourceDataUrl = "$basePathV1/data?topic=client-topic-name&requestId=some-requestId" and: 'list of operation details are received into request body' def dataOperationRequestBody = '[{"operation": "read", "operationId": "14", "datastore": "ncmp-datastore:passthrough-operational", "options": "some options", "resourceIdentifier": "some resourceIdentifier",' + - ' "cmhandles": [ {"id": "cmHanlde123", "cmHandleProperties": { "myProp`": "some value", "otherProp": "other value"}}]}]' + '"cmHandles": [ {"id": "cmHandle123", "moduleSetTag": "module-set-tag1", "cmHandleProperties": { "myProp`": "some value", "otherProp": "other value"}}]}]' when: 'the dmi resource data for dataOperation api is called.' def response = mvc.perform( post(resourceDataUrl).contentType(MediaType.APPLICATION_JSON).content(dataOperationRequestBody) ).andReturn().response then: 'the resource data operation endpoint returns the not implemented response' assert response.status == 501 + and: 'the job details are correctly received (logged)' + assert getLoggingMessage(1).contains('some-requestId') + assert getLoggingMessage(2).contains('client-topic-name') + assert getLoggingMessage(4).contains('some resourceIdentifier') + assert getLoggingMessage(5).contains('module-set-tag1') + and: 'the operation Id is correctly received (logged)' + assert getLoggingMessage(6).contains('14') + } + + def getLoggingMessage(int index) { + return logger.list[index].formattedMessage } }
\ No newline at end of file diff --git a/src/test/resources/moduleResources.json b/src/test/resources/moduleResources.json index 57f5aefd..23adfcba 100644 --- a/src/test/resources/moduleResources.json +++ b/src/test/resources/moduleResources.json @@ -13,5 +13,6 @@ }, "cmHandleProperties": { "subsystemId": "system-001" - } + }, + "moduleSetTag": "module-set-tag1" } diff --git a/version.properties b/version.properties index c2dd6f95..1833e74b 100644 --- a/version.properties +++ b/version.properties @@ -21,7 +21,7 @@ # because they are used in Jenkins, whose plug-in doesn't support this major=1 -minor=5 +minor=6 patch=0 base_version=${major}.${minor}.${patch} |