package org.onap.cps.ncmp.rest.controller
import org.mapstruct.factory.Mappers
+import org.onap.cps.ncmp.api.inventory.CmHandleState
+import org.onap.cps.ncmp.api.inventory.CompositeState
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle
+import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper
+import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor
import spock.lang.Shared
+import java.time.OffsetDateTime
+import java.time.ZoneOffset
+import java.time.format.DateTimeFormatter
+
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
+import static org.onap.cps.ncmp.api.inventory.CompositeState.DataStores
+import static org.onap.cps.ncmp.api.inventory.CompositeState.LockReason
+import static org.onap.cps.ncmp.api.inventory.CompositeState.Operational
+import static org.onap.cps.ncmp.api.inventory.CompositeState.Running
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
@SpringBean
NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper)
+ @SpringBean
+ RestOutputCmHandleStateMapper restOutputCmHandleStateMapper = Mappers.getMapper(RestOutputCmHandleStateMapper)
+
+ @SpringBean
+ CpsNcmpTaskExecutor spiedCpsTaskExecutor = Spy()
+
@Value('${rest.api.ncmp-base-path}/v1')
def ncmpBasePathV1
def NO_TOPIC = null
def NO_REQUEST_ID = null
+ def formattedDateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
+ .format(OffsetDateTime.of(2022, 12, 31, 20, 30, 40, 1, ZoneOffset.UTC))
+
def 'Get Resource Data from pass-through operational.'() {
given: 'resource data url'
def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
"?resourceIdentifier=parent/child&options=(a=1,b=2)${topicQueryParam}"
when: 'get data resource request is performed'
def response = mvc.perform(
- get(getUrl)
- .contentType(MediaType.APPLICATION_JSON)
- ).andReturn().response
- then: 'the NCMP data service is called with operational data for cm handle'
- expectedNumberOfMethodExecutions
- * mockNetworkCmProxyDataService."${expectedMethodName}"('testCmHandle',
- 'parent/child',
- '(a=1,b=2)',
- expectedTopicName,
- _)
- then: 'response status is expected'
- response.status == expectedHttpStatus
+ get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
+ then: 'task executor is called appropriate number of times'
+ expectedNumberOfExecutorExecutions * spiedCpsTaskExecutor.executeTask(_, 2000)
+ and: 'response status is expected'
+ response.status == HttpStatus.OK.value()
where: 'the following parameters are used'
- scenario | datastoreInUrl | topicQueryParam || expectedTopicName | expectedMethodName | expectedNumberOfMethodExecutions | expectedHttpStatus
- 'url with valid topic' | 'passthrough-operational' | '&topic=my-topic-name' || 'my-topic-name' | 'getResourceDataOperationalForCmHandle' | 1 | HttpStatus.OK.value()
- 'no topic in url' | 'passthrough-operational' | '' || NO_TOPIC | 'getResourceDataOperationalForCmHandle' | 1 | HttpStatus.OK.value()
- 'null topic in url' | 'passthrough-operational' | '&topic=null' || 'null' | 'getResourceDataOperationalForCmHandle' | 1 | HttpStatus.OK.value()
- 'empty topic in url' | 'passthrough-operational' | '&topic=\"\"' || null | 'getResourceDataOperationalForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'missing topic in url' | 'passthrough-operational' | '&topic=' || null | 'getResourceDataOperationalForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'blank topic value in url' | 'passthrough-operational' | '&topic=\" \"' || null | 'getResourceDataOperationalForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'invalid non-empty topic value in url' | 'passthrough-operational' | '&topic=1_5_*_#' || null | 'getResourceDataOperationalForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'url with valid topic' | 'passthrough-running' | '&topic=my-topic-name' || 'my-topic-name' | 'getResourceDataPassThroughRunningForCmHandle' | 1 | HttpStatus.OK.value()
- 'no topic in url' | 'passthrough-running' | '' || NO_TOPIC | 'getResourceDataPassThroughRunningForCmHandle' | 1 | HttpStatus.OK.value()
- 'null topic in url' | 'passthrough-running' | '&topic=null' || 'null' | 'getResourceDataPassThroughRunningForCmHandle' | 1 | HttpStatus.OK.value()
- 'empty topic in url' | 'passthrough-running' | '&topic=\"\"' || null | 'getResourceDataPassThroughRunningForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'missing topic in url' | 'passthrough-running' | '&topic=' || null | 'getResourceDataPassThroughRunningForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'blank topic value in url' | 'passthrough-running' | '&topic=\" \"' || null | 'getResourceDataPassThroughRunningForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
- 'invalid non-empty topic value in url' | 'passthrough-running' | '&topic=1_5_*_#' || null | 'getResourceDataPassThroughRunningForCmHandle' | 0 | HttpStatus.BAD_REQUEST.value()
+ scenario | datastoreInUrl | topicQueryParam || expectedTopicName | expectedNumberOfExecutorExecutions
+ 'url with valid topic' | 'passthrough-operational' | '&topic=my-topic-name' || 'my-topic-name' | 1
+ 'no topic in url' | 'passthrough-operational' | '' || NO_TOPIC | 0
+ 'null topic in url' | 'passthrough-operational' | '&topic=null' || 'null' | 1
+ 'url with valid topic' | 'passthrough-running' | '&topic=my-topic-name' || 'my-topic-name' | 1
+ 'no topic in url' | 'passthrough-running' | '' || NO_TOPIC | 0
+ 'null topic in url' | 'passthrough-running' | '&topic=null' || 'null' | 1
+ }
+
+ def 'Fail to get Resource Data from #datastoreInUrl when #scenario.'() {
+ given: 'resource data url'
+ def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:${datastoreInUrl}" +
+ "?resourceIdentifier=parent/child&options=(a=1,b=2)${topicQueryParam}"
+ when: 'get data resource request is performed'
+ def response = mvc.perform(
+ get(getUrl).contentType(MediaType.APPLICATION_JSON)).andReturn().response
+ then: 'abad request is returned'
+ response.status == HttpStatus.BAD_REQUEST.value()
+ where: 'the following parameters are used'
+ scenario | datastoreInUrl | topicQueryParam
+ 'empty topic in url' | 'passthrough-operational' | '&topic=\"\"'
+ 'missing topic in url' | 'passthrough-operational' | '&topic='
+ 'blank topic value in url' | 'passthrough-operational' | '&topic=\" \"'
+ 'invalid non-empty topic value in url' | 'passthrough-operational' | '&topic=1_5_*_#'
+ 'empty topic in url' | 'passthrough-running' | '&topic=\"\"'
+ 'missing topic in url' | 'passthrough-running' | '&topic='
+ 'blank topic value in url' | 'passthrough-running' | '&topic=\" \"'
+ 'invalid non-empty topic value in url' | 'passthrough-running' | '&topic=1_5_*_#'
}
def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.'() {
response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}'
}
- def 'Get Cm Handle details by Cm Handle id.' () {
+ def 'Get Cm Handle details by Cm Handle id.'() {
given: 'an endpoint and a cm handle'
def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/some-cm-handle"
and: 'an existing ncmp service cm handle'
def cmHandleId = 'some-cm-handle'
def dmiProperties = [ prop:'some DMI property' ]
def publicProperties = [ "public prop":'some public property' ]
- def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties)
+ def compositeState = new CompositeState(cmhandleState: CmHandleState.ADVISED,
+ lockReason: LockReason.builder().reason('LOCKED_OTHER').details("lock-misbehaving-details").build(),
+ lastUpdateTime: formattedDateAndTime.toString(),
+ dataSyncEnabled: false,
+ dataStores: dataStores())
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState)
and: 'the service method is invoked with the cm handle id'
1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('some-cm-handle') >> ncmpServiceCmHandle
when: 'the cm handle details api is invoked'
def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response
then: 'the correct response is returned'
response.status == HttpStatus.OK.value()
- and: 'the response returns public properties and the correct properties'
+ and: 'the response returns public properties and the correct cm handle states'
response.contentAsString.contains('publicCmHandleProperties')
- response.contentAsString.contains('public prop')
- response.contentAsString.contains('some public property')
+ response.contentAsString.contains('LOCKED_OTHER')
+ response.contentAsString.contains('lock-misbehaving-details')
+ response.contentAsString.contains('ADVISED')
+ response.contentAsString.contains('NONE_REQUESTED')
+ response.contentAsString.contains('2022-12-31T20:30:40.000+0000')
and: 'the content does not contain dmi properties'
!response.contentAsString.contains("some DMI property")
}
':passthrough-running' | 'passthrough-running'
}
+ def dataStores() {
+ DataStores.builder()
+ .operationalDataStore(Operational.builder()
+ .syncState('NONE_REQUESTED')
+ .lastSyncTime(formattedDateAndTime.toString()).build())
+ .runningDataStore(Running.builder()
+ .syncState('NONE_REQUESTED')
+ .lastSyncTime(formattedDateAndTime.toString()).build())
+ .build()
+ }
+
}