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>
diff --git a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
index e33af45..0e4f7f9 100644
--- a/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
+++ b/cps-ncmp-rest-stub/cps-ncmp-rest-stub-service/src/main/java/org/onap/cps/ncmp/rest/stub/controller/NetworkCmProxyStubController.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Bell Canada
- * Modifications Copyright (c) 2022-2023 Nordix Foundation
+ * Modifications Copyright (c) 2022-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -167,7 +167,9 @@
}
@Override
- public ResponseEntity<List<RestModuleDefinition>> getModuleDefinitionsByCmHandleId(final String cmHandle) {
+ public ResponseEntity<List<RestModuleDefinition>> getModuleDefinitions(final String cmHandleId,
+ final String moduleName,
+ final String revision) {
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml
index 3bee633..6b53292 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 @@
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 95ca6cc..2f90155 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 @@
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 7ceb4fe..dd6d7c8 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 @@
$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 be33c6a..6ec2444 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.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.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 @@
}
/**
- * 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 314a0b2..983f243 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.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.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 @@
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 @@
':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 @@
return dataOperationDefinition
}
+ def setupLogger() {
+ def setupLogger = ((Logger) LoggerFactory.getLogger(NetworkCmProxyController.class))
+ setupLogger.setLevel(Level.DEBUG)
+ setupLogger.addAppender(logger)
+ logger.start()
+ }
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
index 0c12875..0c847483 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021-2023 Nordix Foundation
+ * Modifications Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
@@ -126,6 +126,18 @@
Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(String cmHandleId);
/**
+ * Get module definitions for the given parameters.
+ *
+ * @param cmHandleId cm-handle identifier
+ * @param moduleName module name
+ * @param moduleRevision the revision of the module
+ * @return list of module definitions (module name, revision, yang resource content)
+ */
+ Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(String cmHandleId,
+ String moduleName,
+ String moduleRevision);
+
+ /**
* Query cm handle details by cm handle's name.
*
* @param cmHandleId cm handle identifier
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 469d75a..1e7edd4 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021-2023 Nordix Foundation
+ * Modifications Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021-2022 Bell Canada
* Modifications Copyright (C) 2023 TechMahindra Ltd.
@@ -188,6 +188,13 @@
return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
}
+ @Override
+ public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
+ final String moduleName,
+ final String moduleRevision) {
+ return inventoryPersistence.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, moduleRevision);
+ }
+
/**
* Retrieve cm handles with details for the given query parameters.
*
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java
index 9024eac..dcd0368 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistence.java
@@ -80,6 +80,18 @@
Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(String cmHandleId);
/**
+ * Method to return module definitions for the given parameters.
+ *
+ * @param cmHandleId cm-handle identifier
+ * @param moduleName module name
+ * @param moduleRevision the revision of the module
+ * @return list of module definitions (module name, revision, yang resource content)
+ */
+ Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(String cmHandleId,
+ String moduleName,
+ String moduleRevision);
+
+ /**
* Method to return module references by cmHandleId.
*
* @param cmHandleId cm handle ID
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java
index 33d6e9a..3b70786 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImpl.java
@@ -128,6 +128,15 @@
}
@Override
+ public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
+ final String moduleName,
+ final String moduleRevision) {
+ cpsValidator.validateNameCharacters(cmHandleId, moduleName);
+ return cpsModuleService.getModuleDefinitionsByAnchorAndModule(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+ cmHandleId, moduleName, moduleRevision);
+ }
+
+ @Override
public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
cpsValidator.validateNameCharacters(cmHandleId);
return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 4f7b726..4c8b2bb 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============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
* Modifications Copyright (C) 2023 TechMahindra Ltd.
@@ -292,10 +292,17 @@
assert result == ['cm-handle-id-1']
}
- def 'Getting module definitions.'() {
- when: 'get module definitions method is called with a valid cm handle ID'
+ def 'Getting module definitions by module'() {
+ when: 'get module definitions is performed with module name'
+ objectUnderTest.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04')
+ then: 'ncmp inventory persistence service is invoked once with correct parameters'
+ 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04')
+ }
+
+ def 'Getting module definitions by cm handle id'() {
+ when: 'get module definitions is performed with cm handle id'
objectUnderTest.getModuleDefinitionsByCmHandleId('some-cm-handle')
- then: 'CPS module services is invoked once'
+ then: 'ncmp inventory persistence service is invoked once with correct parameter'
1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleId('some-cm-handle')
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy
index cb2f3fd..a3b923f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy
@@ -184,11 +184,23 @@
'DELETING' | CmHandleState.DELETING || ['/dmi-registry/cm-handles[@id=\'Some-Cm-Handle1\']':'{"state":{"cm-handle-state":"DELETING","last-update-time":"2022-12-31T20:30:40.000+0000"}}', '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle2\']':'{"state":{"cm-handle-state":"DELETING","last-update-time":"2022-12-31T20:30:40.000+0000"}}']
}
- def 'Get module definitions'() {
- given: 'cps module service returns a collection of module definitions'
+ def 'Getting module definitions by module'() {
+ given: 'cps module service returns module definition for module name'
+ def moduleDefinitions = [new ModuleDefinition('moduleName','revision','content')]
+ mockCpsModuleService.getModuleDefinitionsByAnchorAndModule(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,'some-cmHandle-Id', 'some-module', '2024-01-25') >> moduleDefinitions
+ when: 'get module definitions is invoked with module name'
+ def result = objectUnderTest.getModuleDefinitionsByCmHandleAndModule('some-cmHandle-Id', 'some-module', '2024-01-25')
+ then: 'returned result are the same module definitions as returned from module service'
+ assert result == moduleDefinitions
+ and: 'cm handle id and module name validated'
+ 1 * mockCpsValidator.validateNameCharacters('some-cmHandle-Id', 'some-module')
+ }
+
+ def 'Getting module definitions with cm handle id'() {
+ given: 'cps module service returns module definitions for cm handle id'
def moduleDefinitions = [new ModuleDefinition('moduleName','revision','content')]
mockCpsModuleService.getModuleDefinitionsByAnchorName(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,'some-cmHandle-Id') >> moduleDefinitions
- when: 'get module definitions by cmHandle is invoked'
+ when: 'get module definitions is invoked with cm handle id'
def result = objectUnderTest.getModuleDefinitionsByCmHandleId('some-cmHandle-Id')
then: 'the returned result are the same module definitions as returned from the module service'
assert result == moduleDefinitions
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
index b115f9a..1e42702 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2024 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -32,6 +32,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -79,6 +80,8 @@
public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService {
private static final String YANG_RESOURCE_CHECKSUM_CONSTRAINT_NAME = "yang_resource_checksum_key";
+ private static final String NO_MODULE_NAME_FILTER = null;
+ private static final String NO_MODULE_REVISION = null;
private static final Pattern CHECKSUM_EXCEPTION_PATTERN = Pattern.compile(".*\\(checksum\\)=\\((\\w+)\\).*");
private static final Pattern RFC6020_RECOMMENDED_FILENAME_PATTERN = Pattern
.compile("([\\w-]+)@(\\d{4}-\\d{2}-\\d{2})(?:\\.yang)?", Pattern.CASE_INSENSITIVE);
@@ -122,10 +125,29 @@
public Collection<ModuleDefinition> getYangResourceDefinitions(final String dataspaceName,
final String anchorName) {
final Set<YangResourceEntity> yangResourceEntities =
- yangResourceRepository
- .findAllModuleDefinitionsByDataspaceAndAnchor(dataspaceName, anchorName);
- return yangResourceEntities.stream().map(CpsModulePersistenceServiceImpl::toModuleDefinition)
- .collect(Collectors.toList());
+ yangResourceRepository.findAllModuleDefinitionsByDataspaceAndAnchorAndModule(dataspaceName, anchorName,
+ NO_MODULE_NAME_FILTER, NO_MODULE_REVISION);
+ return convertYangResourceEntityToModuleDefinition(yangResourceEntities);
+ }
+
+ @Override
+ public Collection<ModuleDefinition> getYangResourceDefinitionsByAnchorAndModule(final String dataspaceName,
+ final String anchorName,
+ final String moduleName,
+ final String moduleRevision) {
+ final Set<YangResourceEntity> yangResourceEntities =
+ yangResourceRepository.findAllModuleDefinitionsByDataspaceAndAnchorAndModule(dataspaceName, anchorName,
+ moduleName, moduleRevision);
+ return convertYangResourceEntityToModuleDefinition(yangResourceEntities);
+ }
+
+ private List<ModuleDefinition> convertYangResourceEntityToModuleDefinition(final Set<YangResourceEntity>
+ yangResourceEntities) {
+ final List<ModuleDefinition> resultModuleDefinitions = new ArrayList<>(yangResourceEntities.size());
+ for (final YangResourceEntity yangResourceEntity: yangResourceEntities) {
+ resultModuleDefinitions.add(toModuleDefinition(yangResourceEntity));
+ }
+ return resultModuleDefinitions;
}
@Override
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
index 3fec462..b37f635 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Pantheon.tech
- * Modifications Copyright (C) 2021-2023 Nordix Foundation
+ * Modifications Copyright (C) 2021-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,9 +84,12 @@
WHERE
dataspace.name = :dataspaceName
AND anchor.name = :anchorName
+ AND (:moduleName IS NULL OR yang_resource.module_name = :moduleName)
+ AND (:revision IS NULL OR yang_resource.revision = :revision)
""", nativeQuery = true)
- Set<YangResourceEntity> findAllModuleDefinitionsByDataspaceAndAnchor(
- @Param("dataspaceName") String dataspaceName, @Param("anchorName") String anchorName);
+ Set<YangResourceEntity> findAllModuleDefinitionsByDataspaceAndAnchorAndModule(
+ @Param("dataspaceName") String dataspaceName, @Param("anchorName") String anchorName,
+ @Param("moduleName") String moduleName, @Param("revision") String revision);
@Query(value = """
SELECT DISTINCT
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
index 2928464..bdd3614 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2024 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2022 TechMahindra Ltd.
* ================================================================================
@@ -134,6 +134,18 @@
Collection<ModuleDefinition> getModuleDefinitionsByAnchorName(String dataspaceName, String anchorName);
/**
+ * Retrieve module definitions for the given parameters.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @param moduleName module name
+ * @param moduleRevision the revision of the module
+ * @return a collection of module definitions (moduleName, revision, yang resource content)
+ */
+ Collection<ModuleDefinition> getModuleDefinitionsByAnchorAndModule(String dataspaceName, String anchorName,
+ String moduleName, String moduleRevision);
+
+ /**
* Identify previously unknown Yang Resource module references.
* The system will ignore the namespace of all module references.
*
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index 61a4e62..0f9eb3c 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2024 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2022 Bell Canada
* Modifications Copyright (C) 2022 TechMahindra Ltd
@@ -156,6 +156,15 @@
}
@Override
+ public Collection<ModuleDefinition> getModuleDefinitionsByAnchorAndModule(final String dataspaceName,
+ final String anchorName,
+ final String moduleName,
+ final String moduleRevision) {
+ return cpsModulePersistenceService.getYangResourceDefinitionsByAnchorAndModule(dataspaceName, anchorName,
+ moduleName, moduleRevision);
+ }
+
+ @Override
public Collection<ModuleReference> identifyNewModuleReferences(
final Collection<ModuleReference> moduleReferencesToCheck) {
return cpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck);
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
index aaca2ee..eeaaa47 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsModulePersistenceService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2024 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2022 TechMahindra Ltd.
* ================================================================================
@@ -126,6 +126,18 @@
Collection<ModuleDefinition> getYangResourceDefinitions(String dataspaceName, String anchorName);
/**
+ * Get YANG resource definitions for the given parameters.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @param moduleName module name
+ * @param moduleRevision the revision of the module
+ * @return a collection of module definitions (moduleName, revision and yang resource content)
+ */
+ Collection<ModuleDefinition> getYangResourceDefinitionsByAnchorAndModule(String dataspaceName, String anchorName,
+ String moduleName, String moduleRevision);
+
+ /**
* Remove unused Yang Resource Modules.
*/
void deleteUnusedYangResourceModules();
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
index d909e27..0bad0de 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsModuleServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2023 Nordix Foundation
+ * Copyright (C) 2020-2024 Nordix Foundation
* Modifications Copyright (C) 2020-2021 Pantheon.tech
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -238,15 +238,25 @@
1 * mockCpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck)
}
- def 'Getting module definitions.'() {
- given: 'the module persistence service returns a collection of module definitions'
+ def 'Getting module definitions with module name'() {
+ given: 'module persistence service returns module definitions for module name'
+ def moduleDefinitionsFromPersistenceService = [ new ModuleDefinition('name', 'revision', 'content' ) ]
+ mockCpsModulePersistenceService.getYangResourceDefinitionsByAnchorAndModule('some-dataspace-name', 'some-anchor-name', 'some-module', '2024-01-01') >> moduleDefinitionsFromPersistenceService
+ when: 'get module definitions method is called with anchor and module name'
+ def result = objectUnderTest.getModuleDefinitionsByAnchorAndModule('some-dataspace-name', 'some-anchor-name', 'some-module', '2024-01-01')
+ then: 'the result is the same collection returned by the persistence service'
+ assert result == moduleDefinitionsFromPersistenceService
+ }
+
+ def 'Getting module definitions with anchor name'() {
+ given: 'the module persistence service returns module definitions for cm handle id'
def moduleDefinitionsFromPersistenceService = [ new ModuleDefinition('name', 'revision', 'content' ) ]
mockCpsModulePersistenceService.getYangResourceDefinitions('some-dataspace-name', 'some-anchor-name') >> moduleDefinitionsFromPersistenceService
when: 'get module definitions method is called with a valid dataspace and anchor name'
def result = objectUnderTest.getModuleDefinitionsByAnchorName('some-dataspace-name', 'some-anchor-name')
then: 'the result is the same collection returned by the persistence service'
assert result == moduleDefinitionsFromPersistenceService
- and: 'the CpsValidator is called on the dataspaceName and schemaSetName'
+ and: 'cps validator is called on the dataspace and anchor name'
1 * mockCpsValidator.validateNameCharacters('some-dataspace-name', 'some-anchor-name')
}
diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
index cf0e0b5..8029ae0 100644
--- a/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
+++ b/integration-test/src/test/groovy/org/onap/cps/integration/functional/CpsModuleServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation
+ * Copyright (C) 2023-2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
package org.onap.cps.integration.functional
import org.onap.cps.api.CpsModuleService
-import org.onap.cps.api.impl.CpsModuleServiceImpl
import org.onap.cps.integration.base.FunctionalSpecBase
import org.onap.cps.spi.CascadeDeleteAllowed
import org.onap.cps.spi.exceptions.AlreadyDefinedException
@@ -153,6 +152,17 @@
result == [new ModuleDefinition('stores','2020-09-15','')]
}
+ def 'Retrieving module definitions: #scenarios'() {
+ when: 'module definitions for module name are retrieved'
+ def result = objectUnderTest.getModuleDefinitionsByAnchorAndModule(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, moduleName, moduleRevision)
+ then: 'the correct module definitions are returned'
+ result == [new ModuleDefinition('stores','2020-09-15','')]
+ where: 'following parameters are used'
+ scenarios | moduleName | moduleRevision
+ 'both specified' | 'stores' | '2020-09-15'
+ 'module name specified' | 'stores' | null
+ }
+
def 'Retrieving yang resource module references by anchor.'() {
when: 'the yang resource module references for an anchor are retrieved'
def result = objectUnderTest.getYangResourcesModuleReferences(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1)