diff options
13 files changed, 70 insertions, 63 deletions
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 3e2bdd928b..449a4344dd 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 @@ -219,8 +219,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { final List<ConditionProperties> conditionProperties = conditions.getConditions().stream().collect(Collectors.toList()); final CmHandles cmHandles = new CmHandles(); - final Collection<String> cmHandleIdentifiers = processConditions(conditionProperties); - cmHandleIdentifiers.forEach(cmHandle -> cmHandles.setCmHandles(toCmHandleProperties(cmHandle))); + cmHandles.setCmHandles(toCmHandleProperties(processConditions(conditionProperties))); return ResponseEntity.ok(cmHandles); } @@ -256,11 +255,13 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { return moduleNames; } - private CmHandleProperties toCmHandleProperties(final String cmHandleId) { + private CmHandleProperties toCmHandleProperties(final Collection<String> cmHandleIdentifiers) { final CmHandleProperties cmHandleProperties = new CmHandleProperties(); - final CmHandleProperty cmHandleProperty = new CmHandleProperty(); - cmHandleProperty.setCmHandleId(cmHandleId); - cmHandleProperties.add(cmHandleProperty); + for (final String cmHandleIdentifier : cmHandleIdentifiers) { + final CmHandleProperty cmHandleProperty = new CmHandleProperty(); + cmHandleProperty.setCmHandleId(cmHandleIdentifier); + cmHandleProperties.add(cmHandleProperty); + } return cmHandleProperties; } 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 cb3dc6f738..e96b27df8d 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 @@ -258,8 +258,8 @@ class NetworkCmProxyControllerSpec extends Specification { given: 'an endpoint and json data' def searchesEndpoint = "$ncmpBasePathV1/ch/searches" String jsonData = TestUtils.getResourceFileContent('cmhandle-search.json') - and: 'the service method is invoked with module names and returns a cm handle id' - mockNetworkCmProxyDataService.executeCmHandleHasAllModulesSearch(['module1', 'module2']) >> ['some-cmhandle-id'] + and: 'the service method is invoked with module names and returns two cm handle ids' + mockNetworkCmProxyDataService.executeCmHandleHasAllModulesSearch(['module1', 'module2']) >> ['some-cmhandle-id1', 'some-cmhandle-id2'] when: 'the searches api is invoked' def response = mvc.perform(post(searchesEndpoint) .contentType(MediaType.APPLICATION_JSON) @@ -267,7 +267,7 @@ class NetworkCmProxyControllerSpec extends Specification { then: 'response status returns OK' response.status == HttpStatus.OK.value() and: 'the expected response content is returned' - response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id"}]}' + response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}' } def 'Call execute cm handle searches with unrecognized condition name.'() { @@ -279,7 +279,7 @@ class NetworkCmProxyControllerSpec extends Specification { .contentType(MediaType.APPLICATION_JSON) .content(jsonData)).andReturn().response then: 'an empty cm handle identifier is returned' - response.contentAsString == '{"cmHandles":null}' + response.contentAsString == '{"cmHandles":[]}' } def 'Update resource data from passthrough running.' () { diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java index cd3c30b97b..b1bd03c255 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsAdminPersistenceServiceImpl.java @@ -30,6 +30,7 @@ import javax.transaction.Transactional; import org.onap.cps.spi.CpsAdminPersistenceService; import org.onap.cps.spi.entities.AnchorEntity; import org.onap.cps.spi.entities.DataspaceEntity; +import org.onap.cps.spi.entities.YangResourceModuleReference; import org.onap.cps.spi.exceptions.AlreadyDefinedException; import org.onap.cps.spi.exceptions.ModuleNamesNotFoundException; import org.onap.cps.spi.model.Anchor; @@ -96,8 +97,9 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic @Override public Collection<Anchor> queryAnchors(final String dataspaceName, final Collection<String> inputModuleNames) { validateDataspaceAndModuleNames(dataspaceName, inputModuleNames); - final Collection<AnchorEntity> anchorEntities = - anchorRepository.getAnchorsByDataspaceNameAndModuleNames(dataspaceName, inputModuleNames); + final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName); + final Collection<AnchorEntity> anchorEntities = anchorRepository + .getAnchorsByDataspaceIdAndModuleNames(dataspaceEntity.getId(), inputModuleNames, inputModuleNames.size()); return anchorEntities.stream().map(CpsAdminPersistenceServiceImpl::toAnchor).collect(Collectors.toSet()); } @@ -131,7 +133,7 @@ public class CpsAdminPersistenceServiceImpl implements CpsAdminPersistenceServic final Collection<String> inputModuleNames) { final Collection<String> retrievedModuleNames = yangResourceRepository.findAllModuleReferences(dataspaceName, inputModuleNames) - .stream().map(module -> module.getModuleName()) + .stream().map(YangResourceModuleReference::getModuleName) .collect(Collectors.toList()); if (retrievedModuleNames.isEmpty()) { dataspaceRepository.getByName(dataspaceName); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java index 8dc6c2f69c..c616c8face 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java @@ -91,7 +91,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService private static final Gson GSON = new GsonBuilder().create(); private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@[\\s\\S]+?]){0,1})"; - private static final String REG_EX_FOR_LIST_ELEMENT_KEY_PREDICATE = "\\[(\\@([^/]*?)){0,99}( and)*\\]$"; + private static final Pattern REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE = + Pattern.compile("\\[(\\@([^\\/]{0,9999}))\\]$"); @Override public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentXpath, @@ -361,8 +362,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final String parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/')); final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/')); - final boolean isListElement = Pattern.compile(REG_EX_FOR_LIST_ELEMENT_KEY_PREDICATE) - .matcher(lastXpathElement).find(); + final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find(); boolean targetExist; if (isListElement) { targetExist = deleteDataNode(parentFragmentEntity, targetXpath); diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java index 6d4cb3c716..5870fd9e9b 100755 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/AnchorRepository.java @@ -45,16 +45,13 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Integer> { Collection<AnchorEntity> findAllBySchemaSet(@NotNull SchemaSetEntity schemaSetEntity); - @Query(value = "SELECT DISTINCT\n" - + "anchor.*\n" - + "FROM\n" - + "yang_resource\n" - + "JOIN schema_set_yang_resources ON " - + "schema_set_yang_resources.yang_resource_id = yang_resource.id\n" + @Query(value = "SELECT anchor.* FROM yang_resource\n" + + "JOIN schema_set_yang_resources ON schema_set_yang_resources.yang_resource_id = yang_resource.id\n" + "JOIN schema_set ON schema_set.id = schema_set_yang_resources.schema_set_id\n" + "JOIN anchor ON anchor.schema_set_id = schema_set.id\n" - + "JOIN dataspace ON dataspace.id = anchor.dataspace_id AND dataspace.name = :dataspaceName\n" - + "WHERE yang_resource.module_Name IN (:moduleNames)", nativeQuery = true) - Collection<AnchorEntity> getAnchorsByDataspaceNameAndModuleNames(@Param("dataspaceName") String dataspaceName, - @Param("moduleNames") Collection<String> moduleNames); + + "WHERE schema_set.dataspace_id = :dataspaceId AND module_name IN (:moduleNames)\n" + + "GROUP BY anchor.id, anchor.name, anchor.dataspace_id, anchor.schema_set_id\n" + + "HAVING COUNT(DISTINCT module_name) = :sizeOfModuleNames", nativeQuery = true) + Collection<AnchorEntity> getAnchorsByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId, + @Param("moduleNames") Collection<String> moduleNames, @Param("sizeOfModuleNames") int sizeOfModuleNames); }
\ No newline at end of file diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy index af199be035..a0df2b169d 100644 --- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy +++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsAdminPersistenceServiceSpec.groovy @@ -146,16 +146,15 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase { @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES]) def 'Query anchors that have #scenario.'() { when: 'all anchor are retrieved for the given dataspace name and module names' - def anchors = objectUnderTest.queryAnchors('DATASPACE-001', inputModuleNames) + def anchors = objectUnderTest.queryAnchors('dataspace-1', inputModuleNames) then: 'the expected anchors are returned' anchors.size() == expectedAnchors.size() anchors.containsAll(expectedAnchors) where: 'the following data is used' - scenario | inputModuleNames || expectedAnchors - 'one module' | ['MODULE-NAME-001'] || [buildAnchor('ANCHOR1', 'DATASPACE-001', 'SCHEMA-SET-001')] - 'two modules' | ['MODULE-NAME-001', 'MODULE-NAME-002'] || [buildAnchor('ANCHOR1', 'DATASPACE-001', 'SCHEMA-SET-001'), buildAnchor('ANCHOR2', 'DATASPACE-001', 'SCHEMA-SET-002'), buildAnchor('ANCHOR3', 'DATASPACE-001', 'SCHEMA-SET-004')] - 'a module attached to multiple anchors' | ['MODULE-NAME-003'] || [buildAnchor('ANCHOR1', 'DATASPACE-001', 'SCHEMA-SET-001'), buildAnchor('ANCHOR2', 'DATASPACE-001', 'SCHEMA-SET-002')] - 'same module with different revisions' | ['MODULE-NAME-002'] || [buildAnchor('ANCHOR2', 'DATASPACE-001', 'SCHEMA-SET-002'), buildAnchor('ANCHOR3', 'DATASPACE-001', 'SCHEMA-SET-004')] + scenario | inputModuleNames || expectedAnchors + 'one module' | ['module-name-1'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] + 'two modules' | ['module-name-1', 'module-name-2'] || [buildAnchor('anchor-2', 'dataspace-1', 'schema-set-2'), buildAnchor('anchor-1', 'dataspace-1', 'schema-set-1')] + 'no anchors for all three modules' | ['module-name-1', 'module-name-2', 'module-name-3'] || [] } @Sql([CLEAR_DATA, SAMPLE_DATA_FOR_ANCHORS_WITH_MODULES]) @@ -166,10 +165,9 @@ class CpsAdminPersistenceServiceSpec extends CpsPersistenceSpecBase { def thrownException = thrown(expectedException) thrownException.details.contains(expectedMessageDetails) where: 'the following data is used' - scenario | dataspaceName | moduleNames || expectedException | expectedMessageDetails - 'existing module in an unknown dataspace' | 'db-does-not-exist' | ['does-not-matter'] || DataspaceNotFoundException | 'db-does-not-exist' - 'unknown module in an existing dataspace' | 'DATASPACE-001' | ['module-does-not-exist'] || ModuleNamesNotFoundException | 'module-does-not-exist' - 'unknown module and known module in an existing dataspace' | 'DATASPACE-001' | ['MODULE-NAME-001', 'module-does-not-exist'] || ModuleNamesNotFoundException | 'module-does-not-exist' + scenario | dataspaceName | moduleNames || expectedException | expectedMessageDetails | messageDoesNotContain + 'unknown dataspace' | 'db-does-not-exist' | ['does-not-matter'] || DataspaceNotFoundException | 'db-does-not-exist' | 'does-not-matter' + 'unknown module and known module' | 'dataspace-1' | ['module-name-1', 'module-does-not-exist'] || ModuleNamesNotFoundException | 'module-does-not-exist' | 'module-name-1' } def buildAnchor(def anchorName, def dataspaceName, def SchemaSetName) { diff --git a/cps-ri/src/test/resources/data/anchors-schemaset-modules.sql b/cps-ri/src/test/resources/data/anchors-schemaset-modules.sql index d2b67f5aea..45119dec0f 100644 --- a/cps-ri/src/test/resources/data/anchors-schemaset-modules.sql +++ b/cps-ri/src/test/resources/data/anchors-schemaset-modules.sql @@ -19,27 +19,31 @@ */ INSERT INTO DATASPACE (ID, NAME) VALUES - (1001, 'DATASPACE-001'), (1002, 'DATASPACE-002'); + (1001, 'dataspace-1'), (1002, 'dataspace-2'); INSERT INTO SCHEMA_SET (ID, NAME, DATASPACE_ID) VALUES - (2001, 'SCHEMA-SET-001', 1001), - (2002, 'SCHEMA-SET-002', 1002), - (2003, 'SCHEMA-SET-003', 1001), - (2004, 'SCHEMA-SET-004', 1001); + (2001, 'schema-set-1', 1001), + (2002, 'schema-set-2', 1001), + (2003, 'schema-set-3', 1001), + (2004, 'schema-set-4', 1002); INSERT INTO YANG_RESOURCE (ID, NAME, CONTENT, CHECKSUM, MODULE_NAME, REVISION) VALUES - (3001, 'module1@2020-02-02.yang', 'CONTENT-001', 'checksum1','MODULE-NAME-001',null), - (3002, 'module2@2020-02-02.yang', 'CONTENT-002', 'checksum2','MODULE-NAME-002','REVISION-002'), - (3003, 'module3@2020-02-02.yang', 'CONTENT-003', 'checksum3','MODULE-NAME-003','REVISION-003'), - (3004, 'module4@2020-02-02.yang', 'CONTENT-004', 'checksum4','MODULE-NAME-004','REVISION-004'), - (3005, 'module5@2020-03-02.yang', 'CONTENT-005', 'checksum5','MODULE-NAME-002','REVISION-003'); + (3001, 'module1@revA.yang', 'some-content', 'checksum1','module-name-1','revA'), + (3002, 'module2@revA.yang', 'some-content', 'checksum2','module-name-2','revA'), + (3003, 'module2@revB.yang', 'some-content', 'checksum3','module-name-2','revB'), + (3004, 'module3@revA.yang', 'some-content', 'checksum4','module-name-3','revA'); INSERT INTO SCHEMA_SET_YANG_RESOURCES (SCHEMA_SET_ID, YANG_RESOURCE_ID) VALUES - (2001, 3001), (2002, 3002), - (2001, 3003), (2002, 3003), - (2003, 3004), (2004, 3005); + (2001, 3001), --schema-set-1(anchor-1) has modules module1@revA, module2@revA + (2001, 3002), + (2002, 3001), --schema-set-2(anchor-2) has modules module1@revA, module2@revB + (2002, 3003), + (2003, 3002), --schema-set-3(anchor-3) has modules module2@revA, module2@revB + (2003, 3003), + (2004, 3001); --schema-set-4(anchor-4) has module module1@revA but in other dataspace INSERT INTO ANCHOR (ID, NAME, DATASPACE_ID, SCHEMA_SET_ID) VALUES - (6001, 'ANCHOR1', 1001, 2001), - (6002, 'ANCHOR2', 1001, 2002), - (6003, 'ANCHOR3', 1001, 2004); + (6001, 'anchor-1', 1001, 2001), + (6002, 'anchor-2', 1001, 2002), + (6003, 'anchor-3', 1001, 2003), + (6005, 'anchor-4', 1002, 2004); diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java index 4640a0fb31..faff7b611b 100755 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java @@ -64,6 +64,6 @@ public class CpsAdminServiceImpl implements CpsAdminService { @Override public Collection<String> queryAnchorNames(final String dataspaceName, final Collection<String> moduleNames) { final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors(dataspaceName, moduleNames); - return anchors.stream().map(anchor -> anchor.getName()).collect(Collectors.toList()); + return anchors.stream().map(Anchor::getName).collect(Collectors.toList()); } } diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundException.java index b717a2b183..db10c88b92 100755 --- a/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundException.java +++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/DataNodeNotFoundException.java @@ -27,7 +27,7 @@ package org.onap.cps.spi.exceptions; public class DataNodeNotFoundException extends DataValidationException { private static final long serialVersionUID = 7786740001662205407L; - + private static final String DATANODE_NOT_FOUND = "DataNode not found"; /** * Constructor. * @@ -36,9 +36,10 @@ public class DataNodeNotFoundException extends DataValidationException { * @param xpath datanode xpath * @param additionalInformation additional information */ + public DataNodeNotFoundException(final String dataspaceName, final String anchorName, final String xpath, final String additionalInformation) { - super("DataNode not found", String + super(DATANODE_NOT_FOUND, String .format("DataNode with xpath %s was not found for anchor %s and dataspace %s, %s.", xpath, anchorName, dataspaceName, additionalInformation)); } @@ -51,7 +52,7 @@ public class DataNodeNotFoundException extends DataValidationException { * @param xpath datanode xpath */ public DataNodeNotFoundException(final String dataspaceName, final String anchorName, final String xpath) { - super("DataNode not found", String + super(DATANODE_NOT_FOUND, String .format("DataNode with xpath %s was not found for anchor %s and dataspace %s.", xpath, anchorName, dataspaceName)); } @@ -63,7 +64,7 @@ public class DataNodeNotFoundException extends DataValidationException { * @param anchorName the anchor name */ public DataNodeNotFoundException(final String dataspaceName, final String anchorName) { - super("DataNode not found", String.format( + super(DATANODE_NOT_FOUND, String.format( "DataNode not found for anchor %s and dataspace %s.", anchorName, dataspaceName)); } } diff --git a/docs/cps-path.rst b/docs/cps-path.rst index 5834d68e1e..bc46681d1c 100644 --- a/docs/cps-path.rst +++ b/docs/cps-path.rst @@ -113,7 +113,7 @@ leaf-conditions - ``/shops/bookstore/categories[@numberOfBooks=1]`` - ``//categories[@name="Kids"]`` - ``//categories[@name='Kids']`` - - ``//categories[@code=1]/book[@title='Dune' and price=5]`` + - ``//categories[@code=1]/books/book[@title='Dune' and @price=5]`` **Limitations** - Only the last list or container can be queried leaf values. Any ancestor list will have to be referenced by its key name-value pair(s). diff --git a/docs/deployment.rst b/docs/deployment.rst index b1839cbb88..2f68a64ee1 100644 --- a/docs/deployment.rst +++ b/docs/deployment.rst @@ -177,7 +177,7 @@ exhaustive. | | | | | | If not defined, the password is generated when deploying the application. | | | | | | -| | See also :ref:`credentials_retrieval`. | | +| | See also :ref:`cps_common_credentials_retrieval`. | | +---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+ | config.dmiPluginUserName | User name used by cps-core to authenticate themselves for using ncmp-dmi-plugin service. | ``dmiuser`` | +---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+ @@ -185,7 +185,7 @@ exhaustive. | | | | | | If not defined, the password is generated when deploying the application. | | | | | | -| | See also :ref:`credentials_retrieval`. | | +| | See also :ref:`cps_common_credentials_retrieval`. | | +---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+ | postgres.config.pgUserName | Internal user name used by cps-core to connect to its own database. | ``cps`` | +---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+ @@ -193,7 +193,7 @@ exhaustive. | | | | | | If not defined, the password is generated when deploying the application. | | | | | | -| | See also :ref:`credentials_retrieval`. | | +| | See also :ref:`cps_common_credentials_retrieval`. | | +---------------------------------------+---------------------------------------------------------------------------------------------------------+-------------------------------+ | postgres.config.pgDatabase | Database name used by cps-core | ``cpsdb`` | | | | | diff --git a/docs/design.rst b/docs/design.rst index 02836c5f37..eb5f6b6e07 100755 --- a/docs/design.rst +++ b/docs/design.rst @@ -64,7 +64,7 @@ CPS Core uses API's from the following ONAP components * DMI-Plugin: REST based interface which is used to provide integration and allow the DMI registry API's have access to the corresponding NCMP API's within CPS Core. - More information on the DMI-Plugins offered APIs can be found on the `DMI-Plugin's Design Page <https://docs.onap.org/projects/onap-cps-ncmp-dmi-plugin/en/latest/design.html>`_. + More information on the DMI-Plugins offered APIs can be found on the :ref:`DMI-Plugin's Design Page <onap-cps-ncmp-dmi-plugin:design>`. CPS Path ======== diff --git a/docs/modeling.rst b/docs/modeling.rst index 5504bf322e..b750c6d5b3 100644 --- a/docs/modeling.rst +++ b/docs/modeling.rst @@ -54,7 +54,11 @@ Data Querying -- **CPS Path** is used to query data nodes. The CPS Path is described in detail in :doc:`cps-path`. +- **CPS Path** is used to query data nodes. +.. toctree:: + :maxdepth: 1 + + cps-path.rst .. Below Label is used by documentation for other CPS components to link here, do not remove even if it gives a warning .. _cps_ncmp_modelling: |