diff options
author | halil.cakal <halil.cakal@est.tech> | 2024-01-23 10:05:36 +0000 |
---|---|---|
committer | halil.cakal <halil.cakal@est.tech> | 2024-02-01 16:41:39 +0000 |
commit | 04280e2f93bbf30e8654c411bb1e107d275c22bb (patch) | |
tree | faf4ac9ae4d80617f6b11cb0d78174e0c12452db /cps-ncmp-rest | |
parent | 0f6a966b363e5347de2d44b1527d19b4cf2825a6 (diff) |
Extend API: Get Module Definitions
- add query parameters: module-name and revision to OpenAPI
- extend the controller method to hande the new parameters
- add the new method stack to the service layer
- extend the SQL query to support the new parameters
- add unit and integration testwares
Issue-ID: CPS-1135
Change-Id: I089ad2ad71effb58ac0ba809e9f441d6cdb59c4f
Signed-off-by: halil.cakal <halil.cakal@est.tech>
Diffstat (limited to 'cps-ncmp-rest')
5 files changed, 126 insertions, 45 deletions
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml index 3bee633900..6b53292af7 100644 --- a/cps-ncmp-rest/docs/openapi/components.yaml +++ b/cps-ncmp-rest/docs/openapi/components.yaml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2021-2023 Nordix Foundation +# Copyright (C) 2021-2024 Nordix Foundation # Modifications Copyright (C) 2021 Pantheon.tech # Modifications Copyright (C) 2022 Bell Canada # ================================================================================ @@ -492,6 +492,22 @@ components: schema: type: string example: my-cm-handle + moduleNameInQuery: + name: module-name + in: query + description: Filter for a module name.This is an optional parameter + required: false + schema: + type: string + example: my-module + revisionInQuery: + name: revision + in: query + description: Filter for a module revision.This is an optional parameter and ignored when no module name is supplied + required: false + schema: + type: string + example: 2024-01-22 dataSyncEnabled: name: dataSyncEnabled in: query diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml index 95ca6ccdc7..2f90155cbd 100755 --- a/cps-ncmp-rest/docs/openapi/ncmp.yml +++ b/cps-ncmp-rest/docs/openapi/ncmp.yml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2021-2023 Nordix Foundation +# Copyright (C) 2021-2024 Nordix Foundation # Modifications Copyright (C) 2021 Pantheon.tech # Modifications Copyright (C) 2021-2022 Bell Canada # ================================================================================ @@ -289,15 +289,17 @@ fetchModuleReferencesByCmHandle: 500: $ref: 'components.yaml#/components/responses/InternalServerError' -fetchModuleDefinitionsByCmHandle: +getModuleDefinitions: get: - description: Fetch all module definitions (name, revision, yang resource) for a given cm handle tags: - network-cm-proxy - summary: Fetch all module definitions (name, revision, yang resource) for a given cm handle - operationId: getModuleDefinitionsByCmHandleId + summary: Get module definitions + description: Get module definitions (module name, revision, yang resource) with options to filter on module name and revision + operationId: getModuleDefinitions parameters: - $ref: 'components.yaml#/components/parameters/cmHandleInPath' + - $ref: 'components.yaml#/components/parameters/moduleNameInQuery' + - $ref: 'components.yaml#/components/parameters/revisionInQuery' responses: 200: description: OK diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml index 7ceb4fe70a..dd6d7c8baa 100755 --- a/cps-ncmp-rest/docs/openapi/openapi.yml +++ b/cps-ncmp-rest/docs/openapi/openapi.yml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2021-2023 Nordix Foundation +# Copyright (C) 2021-2024 Nordix Foundation # Modifications Copyright (C) 2021 Pantheon.tech # Modifications Copyright (C) 2021 Bell Canada # ================================================================================ @@ -44,7 +44,7 @@ paths: $ref: 'ncmp.yml#/fetchModuleReferencesByCmHandle' /v1/ch/{cm-handle}/modules/definitions: - $ref: 'ncmp.yml#/fetchModuleDefinitionsByCmHandle' + $ref: 'ncmp.yml#/getModuleDefinitions' /v1/ch/searches: $ref: 'ncmp.yml#/searchCmHandles' 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 be33c6a010..6ec24448d7 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021 highstreet technologies GmbH * Modifications Copyright (C) 2021-2022 Bell Canada * ================================================================================ @@ -31,6 +31,7 @@ import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH; import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE; import io.micrometer.core.annotation.Timed; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -59,9 +60,11 @@ 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.spi.model.ModuleDefinition; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -317,18 +320,32 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } /** - * Return module definitions for a cm handle. + * Return module definitions. * - * @param cmHandleId cm-handle identifier + * @param cmHandleId cm-handle identifier + * @param moduleName module name + * @param revision the revision of the module * @return list of module definitions (module name, revision, yang resource content) */ @Override - public ResponseEntity<List<RestModuleDefinition>> getModuleDefinitionsByCmHandleId(final String cmHandleId) { - final List<RestModuleDefinition> restModuleDefinitions = - networkCmProxyDataService.getModuleDefinitionsByCmHandleId(cmHandleId).stream() - .map(ncmpRestInputMapper::toRestModuleDefinition) - .collect(Collectors.toList()); - return new ResponseEntity<>(restModuleDefinitions, HttpStatus.OK); + public ResponseEntity<List<RestModuleDefinition>> getModuleDefinitions(final String cmHandleId, + final String moduleName, + final String revision) { + final Collection<ModuleDefinition> moduleDefinitions; + if (StringUtils.hasText(moduleName)) { + moduleDefinitions = + networkCmProxyDataService.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, revision); + } else { + moduleDefinitions = networkCmProxyDataService.getModuleDefinitionsByCmHandleId(cmHandleId); + if (StringUtils.hasText(revision)) { + log.warn("Ignoring revision filter as no module name is provided"); + } + } + final List<RestModuleDefinition> response = new ArrayList<>(); + for (final ModuleDefinition moduleDefinition: moduleDefinitions) { + response.add(ncmpRestInputMapper.toRestModuleDefinition(moduleDefinition)); + } + return new ResponseEntity<>(response, HttpStatus.OK); } /** 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 314a0b221d..983f2438c0 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021 highstreet technologies GmbH - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021-2022 Bell Canada. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,26 +23,14 @@ package org.onap.cps.ncmp.rest.controller -import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores -import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete -import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE -import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE -import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH -import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS - +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.read.ListAppender import com.fasterxml.jackson.databind.ObjectMapper import org.mapstruct.factory.Mappers import org.onap.cps.TestUtils +import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.NetworkCmProxyDataService import org.onap.cps.ncmp.api.NetworkCmProxyQueryService import org.onap.cps.ncmp.api.impl.inventory.CmHandleState @@ -50,19 +38,20 @@ import org.onap.cps.ncmp.api.impl.inventory.CompositeState import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel -import org.onap.cps.ncmp.rest.model.DataOperationRequest -import org.onap.cps.ncmp.rest.model.DataOperationDefinition import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper +import org.onap.cps.ncmp.rest.model.DataOperationDefinition +import org.onap.cps.ncmp.rest.model.DataOperationRequest import org.onap.cps.ncmp.rest.util.DeprecationHelper import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.model.ModuleDefinition import org.onap.cps.spi.model.ModuleReference import org.onap.cps.utils.JsonObjectMapper +import org.slf4j.LoggerFactory import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -72,10 +61,28 @@ import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc import spock.lang.Shared import spock.lang.Specification + import java.time.OffsetDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter +import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores +import static org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE +import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE +import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH +import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS +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 +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put + @WebMvcTest(NetworkCmProxyController) class NetworkCmProxyControllerSpec extends Specification { @@ -130,11 +137,18 @@ class NetworkCmProxyControllerSpec extends Specification { def NO_REQUEST_ID = null def TIMOUT_FOR_TEST = 1234 + def logger = Spy(ListAppender<ILoggingEvent>) + def setup() { ncmpCachedResourceRequestHandler.notificationFeatureEnabled = true ncmpCachedResourceRequestHandler.timeOutInMilliSeconds = TIMOUT_FOR_TEST ncmpPassthroughResourceRequestHandler.notificationFeatureEnabled = true ncmpPassthroughResourceRequestHandler.timeOutInMilliSeconds = TIMOUT_FOR_TEST + setupLogger() + } + + def cleanup() { + ((Logger) LoggerFactory.getLogger(EventsPublisher.class)).detachAndStopAllAppenders() } def 'Get Resource Data from pass-through operational.'() { @@ -516,21 +530,46 @@ class NetworkCmProxyControllerSpec extends Specification { ':passthrough-running' | 'passthrough-running' } - def 'Get module definitions based on cmHandleId.'() { - when: 'get module definition request is performed' + def 'Getting module definitions for a module'() { + when: 'get module definition request is performed with module name' def response = mvc.perform( - get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions")) - .andReturn().response - then: 'ncmp service method to get module definitions is called' - mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleId('some-cmhandle') - >> [new ModuleDefinition('sampleModuleName', '2021-10-03', - 'module sampleModuleName{ sample module content }')] + get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions?module-name=sampleModuleName")) + .andReturn().response + then: 'ncmp service method is invoked with correct parameters' + mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleAndModule('some-cmhandle', 'sampleModuleName', _) + >> [new ModuleDefinition('sampleModuleName', '2021-10-03', + 'module sampleModuleName{ sample module content }')] and: 'response contains an array with the module name, revision and content' response.getContentAsString() == '[{"moduleName":"sampleModuleName","revision":"2021-10-03","content":"module sampleModuleName{ sample module content }"}]' and: 'response returns an OK http code' response.status == HttpStatus.OK.value() } + def 'Getting module definitions filtering on #scenario'() { + when: 'get module definition request is performed' + def response = mvc.perform( + get("$ncmpBasePathV1/ch/some-cmhandle/modules/definitions?module-name=" + moduleName + "&revision=" + revision)) + .andReturn().response + then: 'ncmp service method to get definitions by cm handle is invoked when needed' + numberOfCallsToByCmHandleId * mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleId('some-cmhandle') >> [] + and: 'ncmp service method to get definitions by module is invoked when needed' + numberOfCallsToByModule * mockNetworkCmProxyDataService.getModuleDefinitionsByCmHandleAndModule('some-cmhandle', moduleName, revision) >> [] + and: 'response returns an OK http code' + response.status == HttpStatus.OK.value() + and: 'the correct message is logged when needed' + if (expectLogWarning) { + def lastLoggingEvent = logger.list[0] + assert lastLoggingEvent.level == Level.WARN + assert lastLoggingEvent.formattedMessage.contains('Ignoring revision') + } + where: 'following parameters are used' + scenario | moduleName | revision || numberOfCallsToByCmHandleId | numberOfCallsToByModule | expectLogWarning + 'module name' | 'some-module' | '' || 0 | 1 | false + 'module name and revision' | 'some-module' | 'some-revision' || 0 | 1 | false + 'no filtering' | '' | '' || 1 | 0 | false + 'only revision' | '' | 'some-revision' || 1 | 0 | true + } + def 'Set the data sync enabled based on the cm handle id and the data sync flag is #scenario'() { when: 'the set data sync enabled request is invoked' def response = mvc.perform( @@ -667,5 +706,12 @@ class NetworkCmProxyControllerSpec extends Specification { return dataOperationDefinition } + def setupLogger() { + def setupLogger = ((Logger) LoggerFactory.getLogger(NetworkCmProxyController.class)) + setupLogger.setLevel(Level.DEBUG) + setupLogger.addAppender(logger) + logger.start() + } + } |