Async: NCMP Rest impl. including Request ID generation
[cps.git] / cps-ncmp-service / src / test / groovy / org / onap / cps / ncmp / api / impl / NetworkCmProxyDataServiceImplSpec.groovy
index 6d7bdef..e6d18d9 100644 (file)
 
 package org.onap.cps.ncmp.api.impl
 
+import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import spock.lang.Shared
+
 import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL
 import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING
 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE
@@ -52,15 +56,19 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
     def mockDmiModelOperations = Mock(DmiModelOperations)
     def mockDmiDataOperations = Mock(DmiDataOperations)
     def nullNetworkCmProxyDataServicePropertyHandler = null
+    def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever)
+    def NO_TOPIC = null
+    def NO_REQUEST_ID = null
+    @Shared
+    def OPTIONS_PARAM = '(a=1,b=2)'
 
     def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
-        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler)
+        mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever)
 
     def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
 
     def dataNode = new DataNode(leaves: ['dmi-service-name': 'testDmiService'])
 
-
     def 'Write resource data for pass-through running from DMI using POST #scenario cm handle properties.'() {
         given: 'cpsDataService returns valid datanode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
@@ -100,18 +108,21 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
         and: 'get resource data from DMI is called'
             mockDmiDataOperations.getResourceDataFromDmi(
-                'testCmHandle',
-                'testResourceId',
-                '(a=1,b=2)',
-                'testAcceptParam' ,
-                PASSTHROUGH_OPERATIONAL) >> new ResponseEntity<>('result-json', HttpStatus.OK)
+                    'testCmHandle',
+                    'testResourceId',
+                    OPTIONS_PARAM,
+                    'testAcceptParam',
+                    PASSTHROUGH_OPERATIONAL,
+                    NO_REQUEST_ID,
+                    NO_TOPIC) >> new ResponseEntity<>('dmi-response', HttpStatus.OK)
         when: 'get resource data operational for cm-handle is called'
             def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
-                'testResourceId',
-                'testAcceptParam',
-                '(a=1,b=2)')
+                    'testResourceId',
+                    'testAcceptParam',
+                    OPTIONS_PARAM,
+                    NO_TOPIC)
         then: 'DMI returns a json response'
-            response == 'result-json'
+            response == 'dmi-response'
     }
 
     def 'Get resource data for pass-through operational from DMI with Json Processing Exception.'() {
@@ -125,9 +136,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
         when: 'get resource data is called'
             objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
-                'testResourceId',
-                'testAcceptParam',
-                '(a=1,b=2)')
+                    'testResourceId',
+                    'testAcceptParam',
+                    OPTIONS_PARAM,
+                    NO_TOPIC)
         then: 'exception is thrown with the expected details'
             def exceptionThrown = thrown(ServerNcmpException.class)
             exceptionThrown.details == 'DMI status code: 404, DMI response body: NOK-json'
@@ -139,16 +151,19 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
         and: 'DMI returns NOK response'
             mockDmiDataOperations.getResourceDataFromDmi('testCmHandle',
-                'testResourceId',
-                '(a=1,b=2)',
-                'testAcceptParam',
-                PASSTHROUGH_OPERATIONAL)
-                >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
+                    'testResourceId',
+                    OPTIONS_PARAM,
+                    'testAcceptParam',
+                    PASSTHROUGH_OPERATIONAL,
+                    NO_REQUEST_ID,
+                    NO_TOPIC)
+                    >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
         when: 'get resource data is called'
             objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
-                'testResourceId',
-                'testAcceptParam',
-                '(a=1,b=2)')
+                    'testResourceId',
+                    'testAcceptParam',
+                    OPTIONS_PARAM,
+                    NO_TOPIC)
         then: 'exception is thrown'
             def exceptionThrown = thrown(ServerNcmpException.class)
         and: 'details contains the original response'
@@ -161,17 +176,20 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
         and: 'DMI returns valid response and data'
             mockDmiDataOperations.getResourceDataFromDmi('testCmHandle',
-                'testResourceId',
-                '(a=1,b=2)',
-                'testAcceptParam',
-                PASSTHROUGH_RUNNING) >> new ResponseEntity<>('{result-json}', HttpStatus.OK)
+                    'testResourceId',
+                    OPTIONS_PARAM,
+                    'testAcceptParam',
+                    PASSTHROUGH_RUNNING,
+                    NO_REQUEST_ID,
+                    NO_TOPIC) >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
         when: 'get resource data is called'
             def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                'testResourceId',
-                'testAcceptParam',
-                '(a=1,b=2)')
+                    'testResourceId',
+                    'testAcceptParam',
+                    OPTIONS_PARAM,
+                    NO_TOPIC)
         then: 'get resource data returns expected response'
-            response == '{result-json}'
+            response == '{dmi-response}'
     }
 
     def 'Get resource data for pass-through running from DMI return NOK response.'() {
@@ -180,22 +198,91 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
         and: 'DMI returns NOK response'
             mockDmiDataOperations.getResourceDataFromDmi('testCmHandle',
-                'testResourceId',
-                '(a=1,b=2)',
-                'testAcceptParam',
-                PASSTHROUGH_RUNNING)
-                >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
+                    'testResourceId',
+                    OPTIONS_PARAM,
+                    'testAcceptParam',
+                    PASSTHROUGH_RUNNING,
+                    NO_REQUEST_ID,
+                    NO_TOPIC)
+                    >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
         when: 'get resource data is called'
             objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
-                'testResourceId',
-                'testAcceptParam',
-                '(a=1,b=2)')
+                    'testResourceId',
+                    'testAcceptParam',
+                    OPTIONS_PARAM,
+                    NO_TOPIC)
         then: 'exception is thrown'
             def exceptionThrown = thrown(ServerNcmpException.class)
         and: 'details contains the original response'
             exceptionThrown.details.contains('NOK-json')
     }
 
+    def 'Get resource data for operational from DMI with empty topic sync request.'() {
+        given: 'cps data service returns valid data node'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+        and: 'dmi data operation returns valid response and data'
+            mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, NO_REQUEST_ID, NO_TOPIC)
+                    >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
+        when: 'get resource data is called data operational with blank topic'
+            def responseData = objectUnderTest.getResourceDataOperationalForCmHandle('', '',
+                    '', '', emptyTopic)
+        then: '(synchronous) the dmi response is expected'
+            assert responseData == '{dmi-response}'
+        where: 'the following parameters are used'
+            scenario             | emptyTopic
+            'No topic in url'    | ''
+            'Null topic in url'  | null
+            'Empty topic in url' | '\"\"'
+            'Blank topic in url' | ' '
+    }
+
+    def 'Get resource data for data operational from DMI with valid topic i.e. async request.'() {
+        given: 'cps data service returns valid data node'
+            mockCpsDataService.getDataNode(*_) >> dataNode
+        and: 'dmi data operation returns valid response and data'
+            mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, _, 'my-topic-name')
+                    >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
+        when: 'get resource data is called for data operational with valid topic'
+            def responseData = objectUnderTest.getResourceDataOperationalForCmHandle('', '', '', '', 'my-topic-name')
+        then: 'non empty request id is generated'
+            assert responseData.body.requestId.length() > 0
+    }
+
+    def 'Get resource data for pass through running from DMI with valid topic async request.'() {
+        given: 'cps data service returns valid data node'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+        and: 'dmi data operation returns valid response and data'
+            mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, _, 'my-topic-name')
+                    >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
+        when: 'get resource data is called for data operational with valid topic'
+            def responseData = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('',
+                    '', '', OPTIONS_PARAM, 'my-topic-name')
+        then: 'non empty request id is generated'
+            assert responseData.body.requestId.length() > 0
+    }
+
+    def 'Get resource data for pass through running from DMI sync request where #scenario.'() {
+        given: 'cps data service returns valid data node'
+            mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
+                    cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
+        and: 'dmi data operation returns valid response and data'
+            mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, NO_REQUEST_ID, NO_TOPIC)
+                    >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK)
+        when: 'get resource data is called for data operational with valid topic'
+            def responseData = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('',
+                    '', '', '', emptyTopic)
+        then: '(synchronous) the dmi response is expected'
+            assert responseData == '{dmi-response}'
+        where: 'the following parameters are used'
+            scenario             | emptyTopic
+            'No topic in url'    | ''
+            'Null topic in url'  | null
+            'Empty topic in url' | '\"\"'
+            'Blank topic in url' | ' '
+    }
+
     def 'Getting Yang Resources.'() {
         when: 'yang resources is called'
             objectUnderTest.getYangResourcesModuleReferences('some cm handle')
@@ -210,6 +297,22 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
             1 * mockCpsAdminService.queryAnchorNames('NFP-Operational', ['some-module-name'])
     }
 
+    def 'Get a cm handle.'() {
+        given: 'the system returns a yang modelled cm handle'
+            def dmiServiceName = 'some service name'
+            def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')]
+            def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')]
+            def yangModelCmHandle = new YangModelCmHandle(id:'Some-Cm-Handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties)
+            1 * mockYangModelCmHandleRetriever.getDmiServiceNamesAndProperties('Some-Cm-Handle') >> yangModelCmHandle
+        when: 'getting cm handle details for a given cm handle id from ncmp service'
+            def result = objectUnderTest.getNcmpServiceCmHandle('Some-Cm-Handle')
+        then: 'the result returns the correct data'
+            result.cmHandleID == 'Some-Cm-Handle'
+            result.dmiProperties ==[ Book:'Romance Novel' ]
+            result.publicProperties == [ "Public Book":'Public Romance Novel' ]
+
+    }
+
     def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() {
         given: 'cpsDataService returns valid datanode'
             mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
@@ -235,7 +338,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
                 givenOperation,
                 '{some-json}',
                 'application/json')
-        then: 'an exception is thrown with the expected error message detailsd with correct operation'
+        then: 'an exception is thrown with the expected error message details with correct operation'
             def exceptionThrown = thrown(ServerNcmpException.class)
             exceptionThrown.getMessage().contains(expectedResponseMessage)
         where: