Use attribute-axis in NCMP [#4] 92/140592/2
authoremaclee <lee.anjella.macabuhay@est.tech>
Mon, 24 Mar 2025 17:29:03 +0000 (17:29 +0000)
committeremaclee <lee.anjella.macabuhay@est.tech>
Tue, 25 Mar 2025 14:57:36 +0000 (14:57 +0000)
- introduce getCmHandleReferencesByCpsPath for queries by cps
  path in replacement for use of
  'queryCmHandleAncestorsByCpsPath'

Issue-ID: CPS-2666
Change-Id: I38b76e1f255ad1751b13f6a22dbcf540fed764bd
Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech>
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy

index d6b9476..15aa121 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2025 Nordix Foundation
+ *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -130,4 +130,13 @@ public interface CmHandleQueryService {
      */
     Collection<String> getAllCmHandleReferences(boolean outputAlternateId);
 
+    /**
+     * Retrieves all Cm handle references by cps path.
+     *
+     * @param cpsPath cps path for which the cmHandle is requested
+     * @param outputAlternateId If {@code true}, returns alternate ids; if {@code false}, returns standard cm handle ids
+     * @return collection of cm handle references. Returns an empty collection if no references are found.
+     */
+    Collection<String> getCmHandleReferencesByCpsPath(String cpsPath, boolean outputAlternateId);
+
 }
index 4a753bd..bdf3785 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2025 Nordix Foundation
+ *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
  *  Modifications Copyright (C) 2023 TechMahindra Ltd.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -152,6 +152,25 @@ public class CmHandleQueryServiceImpl implements CmHandleQueryService {
         return cpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, String.class);
     }
 
+    @Override
+    public Collection<String> getCmHandleReferencesByCpsPath(final String cpsPath, final boolean outputAlternateId) {
+        final String cpsPathInQuery;
+        final String cpsPathInQueryWithAttribute;
+        if (CpsPathUtil.getCpsPathQuery(cpsPath).getXpathPrefix().endsWith("/cm-handles")) {
+            cpsPathInQuery = cpsPath;
+        } else {
+            cpsPathInQuery = cpsPath + ANCESTOR_CM_HANDLES;
+        }
+
+        if (outputAlternateId) {
+            cpsPathInQueryWithAttribute = cpsPathInQuery + "/@alternate-id";
+        } else {
+            cpsPathInQueryWithAttribute = cpsPathInQuery + "/@id";
+        }
+        return cpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+                cpsPathInQueryWithAttribute, String.class);
+    }
+
     private Collection<String> getCmHandleReferencesByTrustLevel(final TrustLevel targetTrustLevel,
                                                                  final boolean outputAlternateId) {
         final Collection<String> selectedCmHandleReferences = new HashSet<>();
index 9ce0e04..84a4533 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2025 Nordix Foundation
+ *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
  *  ================================================================================
  *  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.ncmp.impl.inventory;
 
 import static org.onap.cps.api.parameters.FetchDescendantsOption.DIRECT_CHILDREN_ONLY;
-import static org.onap.cps.api.parameters.FetchDescendantsOption.OMIT_DESCENDANTS;
 import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateCpsPathConditionProperties;
 import static org.onap.cps.ncmp.impl.inventory.CmHandleQueryParametersValidator.validateModuleNameConditionProperties;
 import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
@@ -189,9 +188,8 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan
             return NO_QUERY_TO_EXECUTE;
         }
         try {
-            cpsPathQueryResult = collectCmHandleReferencesFromDataNodes(
-                    cmHandleQueryService.queryCmHandleAncestorsByCpsPath(cpsPathCondition.get("cpsPath"),
-                            OMIT_DESCENDANTS), outputAlternateId);
+            cpsPathQueryResult = cmHandleQueryService.getCmHandleReferencesByCpsPath(cpsPathCondition.get("cpsPath"),
+                    outputAlternateId);
         } catch (final PathParsingException pathParsingException) {
             throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(),
                     pathParsingException);
index 57210c5..e978121 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2025 Nordix Foundation
+ *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
  *  Modifications Copyright (C) 2023 TechMahindra Ltd.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -234,6 +234,20 @@ class CmHandleQueryServiceImplSpec extends Specification {
             'output is cm handle ids'   | false             || ['PNFDemo', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4', 'PNFDemo5']
     }
 
+    def 'Get all cm handle references by cps path'() {
+        when: 'the all cm handle references is retrieved via cps path'
+            objectUnderTest.getCmHandleReferencesByCpsPath(sampleCpsPath, outputAlternateId)
+        then: 'query service to query data leaf is called once with the correct cps path as parameter'
+            1 * mockCpsQueryService.queryDataLeaf(_, _, expectedCpsPathForQuery,_)
+        where:
+            scenario                                                     | sampleCpsPath                     | outputAlternateId || expectedCpsPathForQuery
+            'cps path suffixes with cm-handles and outputs alternateId'   | '/some/path/ending/in/cm-handles'  | true            || '/some/path/ending/in/cm-handles/@alternate-id'
+            'cps path suffixes without cm-handles and outputs alternateId'| '/some/path/NotEnding/incmhandles'| true             || '/some/path/NotEnding/incmhandles/ancestor::cm-handles/@alternate-id'
+            'cps path suffixes with cm-handles and outputs cmHandleId'    | '/some/path/ending/in/cm-handles'  | false           || '/some/path/ending/in/cm-handles/@id'
+            'cps path suffixes without cm-handles and outputs cmhandleId' | '/some/path/NotEnding/incmhandles'| false            || '/some/path/NotEnding/incmhandles/ancestor::cm-handles/@id'
+
+    }
+
     void mockResponses() {
 
         mockCpsQueryService.queryDataLeaf(_, _, '//public-properties[@name=\'Contact\' and @value=\'newemailforstore@bookstore.com\']/ancestor::cm-handles/@id', _) >> [pnfDemo.getLeaves().get('id'), pnfDemo2.getLeaves().get('id'), pnfDemo4.getLeaves().get('id')]
@@ -261,6 +275,7 @@ class CmHandleQueryServiceImplSpec extends Specification {
         mockCpsQueryService.queryDataLeaf(_, _, '/dmi-registry/cm-handles/@alternate-id', _) >> getAllCmHandleReferences(true)
         mockCpsQueryService.queryDataLeaf(_, _, '/dmi-registry/cm-handles/@id', _) >> getAllCmHandleReferences(false)
 
+
     }
 
     def static createDataNode(dataNodeId) {
index 8bb4551..4541576 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2025 Nordix Foundation
+ *  Copyright (C) 2022-2025 OpenInfra Foundation Europe. All rights reserved.
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -49,16 +49,16 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification {
             def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
             def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']])
             cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
-        and: 'the query get the cm handle datanodes excluding all descendants returns a datanode'
-            cmHandleQueries.queryCmHandleAncestorsByCpsPath('/some/cps/path', FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode(leaves: ['id':'some-cmhandle-id', 'alternate-id':'some-alternate-id'])]
+        and: 'the query get the cm handle references'
+            cmHandleQueries.getCmHandleReferencesByCpsPath('/some/cps/path', outputAlternateId) >> cmHandleReferences.asCollection()
         when: 'the query is executed for cm handle ids'
             def result = objectUnderTest.queryCmHandleReferenceIds(cmHandleQueryParameters, outputAlternateId)
         then: 'the correct expected cm handles ids are returned'
             assert result == expectedCmhandleReference
         where: 'the following data is used'
-            senario                   | outputAlternateId || expectedCmhandleReference
-            'output CmHandle Ids'     | false             || ['some-cmhandle-id'] as Set
-            'output Alternate Ids'    | true              || ['some-alternate-id'] as Set
+            senario                   | outputAlternateId | cmHandleReferences           || expectedCmhandleReference
+            'output CmHandle Ids'     | false             | ['some-cmhandle-id'] as Set  || ['some-cmhandle-id'] as Set
+            'output Alternate Ids'    | true              | ['some-alternate-id'] as Set || ['some-alternate-id'] as Set
     }
 
     def 'Query cm handle where  cps path itself is ancestor axis.'() {
@@ -66,16 +66,16 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification {
             def cmHandleQueryParameters = new CmHandleQueryServiceParameters()
             def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']])
             cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
-        and: 'the query get the cm handle data nodes excluding all descendants returns a datanode'
-            cmHandleQueries.queryCmHandleAncestorsByCpsPath('/some/cps/path', FetchDescendantsOption.OMIT_DESCENDANTS) >> [new DataNode(leaves: ['id':'some-cmhandle-id', 'alternate-id':'some-alternate-id'])]
+        and: 'the query get the cm handle references'
+            cmHandleQueries.getCmHandleReferencesByCpsPath('/some/cps/path', outputAlternateId) >> cmHandleReferences.asCollection()
         when: 'the query is executed for cm handle ids'
             def result = objectUnderTest.queryCmHandleIdsForInventory(cmHandleQueryParameters, outputAlternateId)
         then: 'the correct expected cm handles ids are returned'
             assert result == expectedCmhandleReference
         where: 'the following data is used'
-            senario                    | outputAlternateId || expectedCmhandleReference
-            'outputAlternate is false' | false             || ['some-cmhandle-id'] as Set
-            'outputAlternate is true'  | true              || ['some-alternate-id'] as Set
+            senario                    | outputAlternateId | cmHandleReferences          || expectedCmhandleReference
+            'outputAlternate is false' | false             | ['some-cmhandle-id'] as Set || ['some-cmhandle-id'] as Set
+            'outputAlternate is true'  | true              | ['some-alternate-id'] as Set|| ['some-alternate-id'] as Set
     }
 
     def 'Cm handle ids query with error: #scenario.'() {
@@ -84,7 +84,7 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification {
             def conditionProperties = createConditionProperties('cmHandleWithCpsPath', [['cpsPath' : '/some/cps/path']])
             cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties])
         and: 'cmHandleQueries throws a path parsing exception'
-            cmHandleQueries.queryCmHandleAncestorsByCpsPath('/some/cps/path', FetchDescendantsOption.OMIT_DESCENDANTS) >> { throw thrownException }
+            cmHandleQueries.getCmHandleReferencesByCpsPath('/some/cps/path', _) >> { throw thrownException }
         when: 'the query is executed for cm handle ids'
             objectUnderTest.queryCmHandleReferenceIds(cmHandleQueryParameters, false)
         then: 'a data validation exception is thrown'