Prioritize cm handle ids over alternate ids in data operations 07/139507/2
authorToineSiebelink <toine.siebelink@est.tech>
Thu, 21 Nov 2024 15:08:39 +0000 (15:08 +0000)
committerToineSiebelink <toine.siebelink@est.tech>
Thu, 21 Nov 2024 15:08:59 +0000 (15:08 +0000)
Issue-ID: CPS-2510
Change-Id: I7068d0de45cc2c2e5d8815f0e78c260369f3551e
Signed-off-by: seanbeirne <sean.beirne@est.tech>
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/dmi/DmiOperationsBaseSpec.groovy

index 98a343b..24a9b21 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.onap.cps.ncmp.api.data.models;
 
-import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.onap.cps.ncmp.config.CpsApplicationContext;
@@ -31,11 +30,11 @@ import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher;
 public class CmResourceAddress {
 
     private final String datastoreName;
-    @Getter(AccessLevel.NONE)
     private final String cmHandleReference;
     private final String resourceIdentifier;
 
-    public String getResolvedCmHandleId() {
-        return CpsApplicationContext.getCpsBean(AlternateIdMatcher.class).getCmHandleId(cmHandleReference);
+    public String resolveCmHandleReferenceToId() {
+        final AlternateIdMatcher alternateIdMatcher = CpsApplicationContext.getCpsBean(AlternateIdMatcher.class);
+        return alternateIdMatcher.getCmHandleId(cmHandleReference);
     }
 }
index c4bdc1c..41348ae 100644 (file)
@@ -52,6 +52,7 @@ import org.onap.cps.ncmp.impl.models.DmiRequestBody;
 import org.onap.cps.ncmp.impl.utils.http.RestServiceUrlTemplateBuilder;
 import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters;
 import org.onap.cps.spi.exceptions.CpsException;
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
 import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
@@ -93,7 +94,7 @@ public class DmiDataOperations {
                                                                final String topic,
                                                                final String requestId,
                                                                final String authorization) {
-        final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId());
+        final YangModelCmHandle yangModelCmHandle = resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress);
         final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState();
         validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState);
         final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle);
@@ -173,7 +174,8 @@ public class DmiDataOperations {
         final CmResourceAddress cmResourceAddress =
                 new CmResourceAddress(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleId, resourceId);
 
-        final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId());
+        final YangModelCmHandle yangModelCmHandle =
+            getYangModelCmHandle(cmResourceAddress.resolveCmHandleReferenceToId());
 
         policyExecutor.checkPermission(yangModelCmHandle, operationType, authorization, resourceId, requestData);
 
@@ -279,6 +281,16 @@ public class DmiDataOperations {
                 }).subscribe();
     }
 
+    private YangModelCmHandle resolveYangModelCmHandleFromCmHandleReference(final CmResourceAddress cmResourceAddress) {
+        String cmHandleId = cmResourceAddress.getCmHandleReference();
+        try {
+            return getYangModelCmHandle(cmHandleId);
+        } catch (final DataNodeNotFoundException ignored) {
+            cmHandleId = cmResourceAddress.resolveCmHandleReferenceToId();
+            return getYangModelCmHandle(cmHandleId);
+        }
+    }
+
     private String createDmiDataOperationRequestAsJsonString(
             final List<DmiDataOperation> dmiDataOperationRequestBodies) {
         final DmiDataOperationRequest dmiDataOperationRequest = DmiDataOperationRequest.builder()
index 01022cc..c14b928 100644 (file)
@@ -62,7 +62,7 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle
         final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants);
 
         final DataNode dataNode = cpsDataService.getDataNodes(cmResourceAddress.getDatastoreName(),
-            cmResourceAddress.getResolvedCmHandleId(),
+            cmResourceAddress.resolveCmHandleReferenceToId(),
             cmResourceAddress.getResourceIdentifier(),
             fetchDescendantsOption).iterator().next();
         return Mono.justOrEmpty(dataNode);
index b046c12..71054dc 100644 (file)
@@ -35,6 +35,7 @@ import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
 import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher
 import org.onap.cps.ncmp.impl.utils.http.UrlTemplateParameters
 import org.onap.cps.ncmp.utils.TestUtils
+import org.onap.cps.spi.exceptions.DataNodeNotFoundException
 import org.onap.cps.utils.JsonObjectMapper
 import org.spockframework.spring.SpringBean
 import org.springframework.beans.factory.annotation.Autowired
@@ -92,7 +93,6 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
             mockDmiRestClient.asynchronousPostOperationWithJsonData(DATA, expectedUrlTemplateWithVariables, expectedJson, READ, NO_AUTH_HEADER) >> responseFromDmi
         when: 'get resource data is invoked'
             def cmResourceAddress = new CmResourceAddress(expectedDataStore.datastoreName, cmHandleId, resourceIdentifier)
-            alternateIdMatcher.getCmHandleId(cmHandleId) >> cmHandleId
             def result = objectUnderTest.getResourceDataFromDmi(cmResourceAddress, expectedOptions, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER).block()
         then: 'the result is the response from the DMI service'
             assert result.body == '{some-key:some-value}'
@@ -205,6 +205,29 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
             CmHandleState.ADVISED || true
     }
 
+    def 'Resolving cm handle references with cm handle id.'() {
+        given: 'a resource address with a cm handle id'
+            def cmResourceAddress = new CmResourceAddress('some store', 'cm-handle-id', 'some resource')
+        and: 'the given cm handle id is available in the inventory'
+            mockInventoryPersistence.getYangModelCmHandle('cm-handle-id') >> yangModelCmHandle
+        expect: 'resolving the cm handle id returns the cm handle'
+            assert objectUnderTest.resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress) == yangModelCmHandle
+    }
+
+    def 'Resolving cm handle references with alternate id.'() {
+        given: 'a resource with a alternate id'
+            def cmResourceAddress = new CmResourceAddress('some store', 'alternate-id', 'some resource')
+        and: 'the alternate id cannot be found in the inventory directly and that results in a data node not found exception'
+            mockInventoryPersistence.getYangModelCmHandle('alternate-id') >>  { throw new DataNodeNotFoundException('','') }
+        and: 'the alternate id can be matched to a cm handle id'
+            alternateIdMatcher.getCmHandleId('alternate-id') >> 'cm-handle-id'
+        and: 'that cm handle id is available in the inventory'
+            mockInventoryPersistence.getYangModelCmHandle('cm-handle-id') >> yangModelCmHandle
+        expect: 'resolving that cm handle id returns the cm handle'
+            assert objectUnderTest.resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress) == yangModelCmHandle
+    }
+
+
     def extractDataValue(actualDataOperationCloudEvent) {
         return toTargetEvent(actualDataOperationCloudEvent, DataOperationEvent).data.responses[0]
     }
index d00d3ab..e479fff 100644 (file)
@@ -44,6 +44,7 @@ abstract class DmiOperationsBaseSpec extends Specification {
     ObjectMapper spyObjectMapper = Spy()
 
     def yangModelCmHandle = new YangModelCmHandle()
+    def otherYangModelCmHandle = new YangModelCmHandle()
     def static dmiServiceName = 'myServiceName'
     def static cmHandleId = 'some-cm-handle'
     def static alternateId = 'alt-id-' + cmHandleId