diff options
author | lukegleeson <luke.gleeson@est.tech> | 2022-06-02 10:56:43 +0100 |
---|---|---|
committer | lukegleeson <luke.gleeson@est.tech> | 2022-06-29 12:03:30 +0100 |
commit | 78062a1c3f4e303714103dfcb7d9552a0b081eb0 (patch) | |
tree | 5cb2bb77ea3ffa2c440a108b13401e2dc3a53b38 /cps-ncmp-rest | |
parent | 529f92c549a16ecd9ead36cc00d6f74f775ca638 (diff) |
Get cm-handle state endpoint
Added new get cm-handle state endpoint
Refactored RestOutputCmHandleState to CmHandleCompositeState
Created new RestOutputCmHandleCompositeState OpenApi object
^This is done so that we get '"state: {" at the start of JSON response
Refactored RestOutputCmHandleStateMapper to CmHandleStateMapper
Added more detailed composite state to get cmHandleDetails endpoint tests
Rebased code
Code rebased on top of 129658: Unable to change state from LOCKED to ADVISED | https://gerrit.onap.org/r/c/cps/+/129658 which fixes output error
Issue-ID: CPS-1019
Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
Signed-off-by: lukegleeson <luke.gleeson@est.tech>
Change-Id: I361117c98c256a4aa578c13d21926bc6d7876a15
Diffstat (limited to 'cps-ncmp-rest')
-rw-r--r-- | cps-ncmp-rest/docs/openapi/components.yaml | 10 | ||||
-rwxr-xr-x | cps-ncmp-rest/docs/openapi/ncmp.yml | 33 | ||||
-rwxr-xr-x | cps-ncmp-rest/docs/openapi/openapi.yml | 3 | ||||
-rwxr-xr-x | cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java | 25 | ||||
-rw-r--r-- | cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java (renamed from cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapper.java) | 6 | ||||
-rw-r--r-- | cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy | 85 | ||||
-rw-r--r-- | cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy | 4 | ||||
-rw-r--r-- | cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy (renamed from cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapperTest.groovy) | 10 |
8 files changed, 146 insertions, 30 deletions
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml index 248b1daa61..cf254e511e 100644 --- a/cps-ncmp-rest/docs/openapi/components.yaml +++ b/cps-ncmp-rest/docs/openapi/components.yaml @@ -209,7 +209,7 @@ components: publicCmHandleProperties: $ref: '#/components/schemas/CmHandlePublicProperties' state: - $ref: '#/components/schemas/RestOutputCmHandleState' + $ref: '#/components/schemas/CmHandleCompositeState' CmHandlePublicProperties: type: array items: @@ -217,7 +217,7 @@ components: additionalProperties: type: string example: Book Type - RestOutputCmHandleState: + CmHandleCompositeState: type: object properties: cmHandleState: @@ -268,6 +268,12 @@ components: publicCmHandleProperties: $ref: '#/components/schemas/CmHandlePublicProperties' + RestOutputCmHandleCompositeState: + type: object + properties: + state: + $ref: '#/components/schemas/CmHandleCompositeState' + examples: dataSampleRequest: summary: Sample request diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml index 3259032f28..8bdaa82d8c 100755 --- a/cps-ncmp-rest/docs/openapi/ncmp.yml +++ b/cps-ncmp-rest/docs/openapi/ncmp.yml @@ -293,6 +293,10 @@ retrieveCmHandleDetailsById: application/json: schema: $ref: 'components.yaml#/components/schemas/RestOutputCmHandle' + 400: + $ref: 'components.yaml#/components/responses/BadRequest' + 401: + $ref: 'components.yaml#/components/responses/Unauthorized' 404: $ref: 'components.yaml#/components/responses/NotFound' 500: @@ -314,6 +318,35 @@ getCmHandlePropertiesById: application/json: schema: $ref: 'components.yaml#/components/schemas/RestOutputCmHandlePublicProperties' + 400: + $ref: 'components.yaml#/components/responses/BadRequest' + 401: + $ref: 'components.yaml#/components/responses/Unauthorized' + 404: + $ref: 'components.yaml#/components/responses/NotFound' + 500: + $ref: 'components.yaml#/components/responses/InternalServerError' + +getCmHandleStateById: + get: + description: Get CM handle state by cm handle id + tags: + - network-cm-proxy + summary: Get CM handle state + operationId: getCmHandleStateByCmHandleId + parameters: + - $ref: 'components.yaml#/components/parameters/cmHandleInPath' + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: 'components.yaml#/components/schemas/RestOutputCmHandleCompositeState' + 400: + $ref: 'components.yaml#/components/responses/BadRequest' + 401: + $ref: 'components.yaml#/components/responses/Unauthorized' 404: $ref: 'components.yaml#/components/responses/NotFound' 500: diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml index 81ebf05edd..ad7dd1d4f7 100755 --- a/cps-ncmp-rest/docs/openapi/openapi.yml +++ b/cps-ncmp-rest/docs/openapi/openapi.yml @@ -46,3 +46,6 @@ paths: /v1/ch/id-searches: $ref: 'ncmp.yml#/searchCmHandleIds' + + /v1/ch/{cm-handle}/state: + $ref: 'ncmp.yml#/getCmHandleStateById' diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java index fb234ef71a..7abefe6791 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java @@ -40,15 +40,17 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; import org.onap.cps.ncmp.api.impl.exception.InvalidTopicException; +import org.onap.cps.ncmp.api.inventory.CompositeState; import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor; -import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper; +import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper; import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters; import org.onap.cps.ncmp.rest.model.RestModuleReference; import org.onap.cps.ncmp.rest.model.RestOutputCmHandle; +import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState; import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties; import org.onap.cps.ncmp.rest.util.DeprecationHelper; import org.onap.cps.utils.CpsValidator; @@ -73,7 +75,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { private final DeprecationHelper deprecationHelper; private final NcmpRestInputMapper ncmpRestInputMapper; - private final RestOutputCmHandleStateMapper restOutputCmHandleStateMapper; + private final CmHandleStateMapper cmHandleStateMapper; private final CpsNcmpTaskExecutor cpsNcmpTaskExecutor; @Value("${notification.async.executor.time-out-value-in-ms:2000}") @@ -253,7 +255,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { /** * Get Cm Handle Properties by Cm Handle Id. * @param cmHandleId cm-handle identifier - * @return cm handle and its properties + * @return cm handle properties */ @Override public ResponseEntity<RestOutputCmHandlePublicProperties> getCmHandlePublicPropertiesByCmHandleId( @@ -267,6 +269,21 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } /** + * Get Cm Handle State by Cm Handle Id. + * @param cmHandleId cm-handle identifier + * @return cm handle state + */ + @Override + public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId( + final String cmHandleId) { + final CompositeState cmHandleState = networkCmProxyDataService.getCmHandleCompositeState(cmHandleId); + final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState = + new RestOutputCmHandleCompositeState(); + restOutputCmHandleCompositeState.setState(cmHandleStateMapper.toCmHandleCompositeState(cmHandleState)); + return ResponseEntity.ok(restOutputCmHandleCompositeState); + } + + /** * Return module references for a cm handle. * * @param cmHandle the cm handle @@ -286,7 +303,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleId()); cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties()); restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties); - restOutputCmHandle.setState(restOutputCmHandleStateMapper.toRestOutputCmHandleState( + restOutputCmHandle.setState(cmHandleStateMapper.toCmHandleCompositeState( ncmpServiceCmHandle.getCompositeState())); return restOutputCmHandle; } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java index afad1098c7..933ca88c9e 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapper.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapper.java @@ -26,17 +26,17 @@ import org.mapstruct.Named; import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.onap.cps.ncmp.api.inventory.CompositeState; +import org.onap.cps.ncmp.rest.model.CmHandleCompositeState; import org.onap.cps.ncmp.rest.model.DataStores; -import org.onap.cps.ncmp.rest.model.RestOutputCmHandleState; import org.onap.cps.ncmp.rest.model.SyncState; @Mapper(componentModel = "spring", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) -public interface RestOutputCmHandleStateMapper { +public interface CmHandleStateMapper { @Mapping(target = "dataSyncState", source = "dataStores", qualifiedByName = "dataStoreToDataSyncState") @Mapping(target = "lockReason.reason", source = "lockReason.lockReasonCategory") - RestOutputCmHandleState toRestOutputCmHandleState(CompositeState compositeState); + CmHandleCompositeState toCmHandleCompositeState(CompositeState compositeState); /** * Convert from CompositeState datastore to RestOutput Datastores. diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy index 71258102ed..93d8358fe7 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy @@ -27,8 +27,9 @@ 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.inventory.SyncState +import org.onap.cps.ncmp.api.inventory.LockReasonCategory import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle -import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper +import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor import org.onap.cps.ncmp.rest.util.DeprecationHelper import spock.lang.Shared @@ -40,7 +41,6 @@ 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.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 @@ -83,7 +83,7 @@ class NetworkCmProxyControllerSpec extends Specification { NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper) @SpringBean - RestOutputCmHandleStateMapper restOutputCmHandleStateMapper = Mappers.getMapper(RestOutputCmHandleStateMapper) + CmHandleStateMapper cmHandleStateMapper = Mappers.getMapper(CmHandleStateMapper) @SpringBean CpsNcmpTaskExecutor spiedCpsTaskExecutor = Spy() @@ -262,24 +262,27 @@ class NetworkCmProxyControllerSpec extends Specification { response.contentAsString == '[{"cmHandle":"some-cmhandle-id1","publicCmHandleProperties":[{"color":"yellow"}],"state":null},{"cmHandle":"some-cmhandle-id2","publicCmHandleProperties":[{"color":"green"}],"state":null}]' } - def 'Get Cm Handle details by Cm Handle id.'() { + def 'Get complete 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 compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, - lastUpdateTime: formattedDateAndTime.toString(), - dataStores: dataStores()) - def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle', compositeState: compositeState) + def cmHandleId = 'some-cm-handle' + def dmiProperties = [ prop:'some DMI property' ] + def publicProperties = [ "public prop":'some public property' ] + def compositeState = compositeStateTestObject() + 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 the correct state and timestamp' - response.contentAsString.contains('some-cm-handle') - response.contentAsString.contains('ADVISED') - response.contentAsString.contains('2022-12-31T20:30:40.000+0000') + and: 'the response contains the public properties' + assertContainsPublicProperties(response) + and: 'the response contains the cm handle state' + assertContainsState(response) + and: 'the content does not contain dmi properties' + !response.contentAsString.contains("some DMI property") } def 'Get Cm Handle public properties by Cm Handle id.' () { @@ -293,8 +296,23 @@ class NetworkCmProxyControllerSpec extends Specification { def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response then: 'the correct response is returned' response.status == HttpStatus.OK.value() - and: 'the response returns public properties and the correct properties' - response.contentAsString.equals('{"publicCmHandleProperties":[{"public prop":"some public property"}]}') + and: 'the response contains the public properties' + assertContainsPublicProperties(response) + } + + def 'Get Cm Handle composite state by Cm Handle id.' () { + given: 'a cm handle state endpoint' + def cmHandlePropertiesEndpoint = "$ncmpBasePathV1/ch/some-cm-handle/state" + and: 'some cm handle composite state' + def compositeState = compositeStateTestObject() + and: 'the service method is invoked with the cm handle id returning the cm handle composite state' + 1 * mockNetworkCmProxyDataService.getCmHandleCompositeState('some-cm-handle') >> compositeState + when: 'the cm handle state api is invoked' + def response = mvc.perform(get(cmHandlePropertiesEndpoint)).andReturn().response + then: 'the correct response is returned' + response.status == HttpStatus.OK.value() + and: 'the response contains the cm handle state' + assertContainsState(response) } def 'Call execute cm handle searches with unrecognized condition name.'() { @@ -397,5 +415,44 @@ class NetworkCmProxyControllerSpec extends Specification { .lastSyncTime(formattedDateAndTime.toString()).build()).build() } + def compositeStateTestObject() { + new CompositeState(cmHandleState: CmHandleState.ADVISED, + lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.LOCKED_MISBEHAVING).details("lock misbehaving details").build(), + lastUpdateTime: formattedDateAndTime.toString(), + dataSyncEnabled: false, + dataStores: dataStores()) + } + + def assertContainsAll(response, assertContent) { + assertContent.forEach( string -> { assert(response.contentAsString.contains(string)) }) + return void + } + + def assertContainsState(response) { + def expectedContent = [ + '"state":', + '"cmHandleState":"ADVISED"', + '"reason":"LOCKED_MISBEHAVING"', + '"details":"lock misbehaving details"', + '"lastUpdateTime":"2022-12-31T20:30:40.000+0000"', + '"dataSyncEnabled":false', + '"dataSyncState":', + '"operational":', + '"state":"NONE_REQUESTED"', + '"lastSyncTime":"2022-12-31T20:30:40.000+0000"', + '"running":null' + ] + return assertContainsAll(response, expectedContent) + } + + def assertContainsPublicProperties(response) { + def expectedContent = [ + '"publicCmHandleProperties":' , + '"public prop"' , + '"some public property"' + ] + return assertContainsAll(response, expectedContent) + } + } diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy index 1563c75b3f..ce908e7547 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy @@ -29,7 +29,7 @@ import org.onap.cps.ncmp.api.impl.exception.DmiRequestException import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper -import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper +import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor import org.onap.cps.ncmp.rest.util.DeprecationHelper import org.onap.cps.spi.exceptions.CpsException @@ -70,7 +70,7 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { NcmpRestInputMapper ncmpRestInputMapper = Mappers.getMapper(NcmpRestInputMapper) @SpringBean - RestOutputCmHandleStateMapper restOutputCmHandleStateMapper = Mappers.getMapper(RestOutputCmHandleStateMapper) + CmHandleStateMapper cmHandleStateMapper = Mappers.getMapper(CmHandleStateMapper) @SpringBean CpsNcmpTaskExecutor stubbedCpsTaskExecutor = Stub() diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapperTest.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy index 695ca5ad67..a6c1278d96 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/RestOutputCmHandleStateMapperTest.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/mapper/CmHandleStateMapperTest.groovy @@ -25,18 +25,18 @@ import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder import org.onap.cps.ncmp.api.inventory.LockReasonCategory import org.onap.cps.ncmp.api.inventory.SyncState -import org.onap.cps.ncmp.rest.model.RestOutputCmHandleState +import org.onap.cps.ncmp.rest.model.CmHandleCompositeState import spock.lang.Specification import java.time.OffsetDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter -class RestOutputCmHandleStateMapperTest extends Specification { +class CmHandleStateMapperTest extends Specification { 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 objectUnderTest = Mappers.getMapper(RestOutputCmHandleStateMapper) + def objectUnderTest = Mappers.getMapper(CmHandleStateMapper) def 'Composite State to Rest Output CmHandleState'() { given: 'a composite state model' @@ -47,9 +47,9 @@ class RestOutputCmHandleStateMapperTest extends Specification { .withOperationalDataStores(SyncState.SYNCHRONIZED, formattedDateAndTime).build() compositeState.setDataSyncEnabled(false) when: 'mapper is called' - def result = objectUnderTest.toRestOutputCmHandleState(compositeState) + def result = objectUnderTest.toCmHandleCompositeState(compositeState) then: 'result is of the correct type' - assert result.class == RestOutputCmHandleState.class + assert result.class == CmHandleCompositeState.class and: 'mapped result should have correct values' assert !result.dataSyncEnabled assert result.lastUpdateTime == formattedDateAndTime |