Merge "Patch # 3: Data operation response event (NCMP → Client App) to comply with...
authorToine Siebelink <toine.siebelink@est.tech>
Wed, 21 Jun 2023 14:44:41 +0000 (14:44 +0000)
committerGerrit Code Review <gerrit@onap.org>
Wed, 21 Jun 2023 14:44:41 +0000 (14:44 +0000)
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy

index 18bdcbe..2ae1188 100644 (file)
@@ -23,7 +23,6 @@ package org.onap.cps.ncmp.api.impl.events.lcm;
 import java.util.Map;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
 import org.onap.cps.ncmp.api.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 
 /**
  * The implementation of it should handle the persisting of composite state and delegate the request to publish the
@@ -46,13 +45,4 @@ public interface LcmEventsCmHandleStateHandler {
      */
     void updateCmHandleStateBatch(final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle);
 
-    /**
-     * Publish LCM Event.
-     *
-     * @param targetNcmpServiceCmHandle  target NcmpServiceCmHandle
-     * @param currentNcmpServiceCmHandle current NcmpServiceCmHandle
-     */
-    void publishLcmEventAsynchronously(final NcmpServiceCmHandle targetNcmpServiceCmHandle,
-            final NcmpServiceCmHandle currentNcmpServiceCmHandle);
-
 }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerAsyncHelper.java
new file mode 100644 (file)
index 0000000..3742719
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.events.lcm;
+
+import java.util.Collection;
+import lombok.RequiredArgsConstructor;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
+import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class LcmEventsCmHandleStateHandlerAsyncHelper {
+
+    private final LcmEventsCreator lcmEventsCreator;
+    private final LcmEventsService lcmEventsService;
+
+    /**
+     * Publish LCM Event in asynchronous manner.
+     *
+     * @param targetNcmpServiceCmHandle  target NcmpServiceCmHandle
+     * @param currentNcmpServiceCmHandle current NcmpServiceCmHandle
+     */
+    @Async("notificationExecutor")
+    public void publishLcmEventAsynchronously(final NcmpServiceCmHandle targetNcmpServiceCmHandle,
+                                              final NcmpServiceCmHandle currentNcmpServiceCmHandle) {
+        publishLcmEvent(targetNcmpServiceCmHandle, currentNcmpServiceCmHandle);
+    }
+
+    /**
+     * Publish LcmEvent in batches and in asynchronous manner.
+     *
+     * @param cmHandleTransitionPairs Pair of existing and modified cm handle represented as YangModelCmHandle
+     */
+    @Async("notificationExecutor")
+    public void publishLcmEventBatchAsynchronously(
+            final Collection<LcmEventsCmHandleStateHandlerImpl.CmHandleTransitionPair> cmHandleTransitionPairs) {
+        cmHandleTransitionPairs.forEach(cmHandleTransitionPair -> publishLcmEvent(
+                toNcmpServiceCmHandle(cmHandleTransitionPair.getTargetYangModelCmHandle()),
+                toNcmpServiceCmHandle(cmHandleTransitionPair.getCurrentYangModelCmHandle())));
+    }
+
+    private void publishLcmEvent(final NcmpServiceCmHandle targetNcmpServiceCmHandle,
+                                 final NcmpServiceCmHandle existingNcmpServiceCmHandle) {
+        final String cmHandleId = targetNcmpServiceCmHandle.getCmHandleId();
+        final LcmEventHeader lcmEventHeader =
+                lcmEventsCreator.populateLcmEventHeader(cmHandleId, targetNcmpServiceCmHandle,
+                        existingNcmpServiceCmHandle);
+        final LcmEvent lcmEvent =
+                lcmEventsCreator.populateLcmEvent(cmHandleId, targetNcmpServiceCmHandle, existingNcmpServiceCmHandle);
+        lcmEventsService.publishLcmEvent(cmHandleId, lcmEvent, lcmEventHeader);
+    }
+
+    private static NcmpServiceCmHandle toNcmpServiceCmHandle(final YangModelCmHandle yangModelCmHandle) {
+        return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle);
+    }
+}
index f42cd39..2f77ec3 100644 (file)
@@ -43,9 +43,6 @@ import org.onap.cps.ncmp.api.inventory.CompositeState;
 import org.onap.cps.ncmp.api.inventory.CompositeStateUtils;
 import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
-import org.onap.cps.ncmp.events.lcm.v1.LcmEvent;
-import org.onap.cps.ncmp.events.lcm.v1.LcmEventHeader;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -54,8 +51,7 @@ import org.springframework.stereotype.Service;
 public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleStateHandler {
 
     private final InventoryPersistence inventoryPersistence;
-    private final LcmEventsCreator lcmEventsCreator;
-    private final LcmEventsService lcmEventsService;
+    private final LcmEventsCmHandleStateHandlerAsyncHelper lcmEventsCmHandleStateHandlerAsyncHelper;
 
     @Override
     public void updateCmHandleState(final YangModelCmHandle updatedYangModelCmHandle,
@@ -70,7 +66,8 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
             final YangModelCmHandle currentYangModelCmHandle = YangModelCmHandle.deepCopyOf(updatedYangModelCmHandle);
             updateToSpecifiedCmHandleState(updatedYangModelCmHandle, targetCmHandleState);
             persistCmHandle(updatedYangModelCmHandle, currentYangModelCmHandle);
-            publishLcmEventAsynchronously(toNcmpServiceCmHandle(updatedYangModelCmHandle),
+            lcmEventsCmHandleStateHandlerAsyncHelper.publishLcmEventAsynchronously(
+                    toNcmpServiceCmHandle(updatedYangModelCmHandle),
                     toNcmpServiceCmHandle(currentYangModelCmHandle));
         }
     }
@@ -82,37 +79,7 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState
         final Collection<CmHandleTransitionPair> cmHandleTransitionPairs =
                 prepareCmHandleTransitionBatch(cmHandleStatePerCmHandle);
         persistCmHandleBatch(cmHandleTransitionPairs);
-        publishLcmEventBatchAsynchronously(cmHandleTransitionPairs);
-    }
-
-    @Async("notificationExecutor")
-    @Override
-    public void publishLcmEventAsynchronously(final NcmpServiceCmHandle targetNcmpServiceCmHandle,
-            final NcmpServiceCmHandle currentNcmpServiceCmHandle) {
-        publishLcmEvent(targetNcmpServiceCmHandle, currentNcmpServiceCmHandle);
-    }
-
-    /**
-     * Publish LcmEvent in batches and in asynchronous manner.
-     *
-     * @param cmHandleTransitionPairs Pair of existing and modified cm handle represented as YangModelCmHandle
-     */
-    @Async("notificationExecutor")
-    public void publishLcmEventBatchAsynchronously(final Collection<CmHandleTransitionPair> cmHandleTransitionPairs) {
-        cmHandleTransitionPairs.forEach(cmHandleTransitionPair -> publishLcmEvent(
-                toNcmpServiceCmHandle(cmHandleTransitionPair.getTargetYangModelCmHandle()),
-                toNcmpServiceCmHandle(cmHandleTransitionPair.getCurrentYangModelCmHandle())));
-    }
-
-    private void publishLcmEvent(final NcmpServiceCmHandle targetNcmpServiceCmHandle,
-            final NcmpServiceCmHandle existingNcmpServiceCmHandle) {
-        final String cmHandleId = targetNcmpServiceCmHandle.getCmHandleId();
-        final LcmEventHeader lcmEventHeader =
-                lcmEventsCreator.populateLcmEventHeader(cmHandleId, targetNcmpServiceCmHandle,
-                        existingNcmpServiceCmHandle);
-        final LcmEvent lcmEvent =
-                lcmEventsCreator.populateLcmEvent(cmHandleId, targetNcmpServiceCmHandle, existingNcmpServiceCmHandle);
-        lcmEventsService.publishLcmEvent(cmHandleId, lcmEvent, lcmEventHeader);
+        lcmEventsCmHandleStateHandlerAsyncHelper.publishLcmEventBatchAsynchronously(cmHandleTransitionPairs);
     }
 
     private Collection<CmHandleTransitionPair> prepareCmHandleTransitionBatch(
index e449d65..bfebc44 100644 (file)
@@ -39,7 +39,8 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification {
     def mockLcmEventsCreator = Mock(LcmEventsCreator)
     def mockLcmEventsService = Mock(LcmEventsService)
 
-    def objectUnderTest = new LcmEventsCmHandleStateHandlerImpl(mockInventoryPersistence, mockLcmEventsCreator, mockLcmEventsService)
+    def lcmEventsCmHandleStateHandlerAsyncHelper = new LcmEventsCmHandleStateHandlerAsyncHelper(mockLcmEventsCreator, mockLcmEventsService)
+    def objectUnderTest = new LcmEventsCmHandleStateHandlerImpl(mockInventoryPersistence, lcmEventsCmHandleStateHandlerAsyncHelper)
 
     def cmHandleId = 'cmhandle-id-1'
     def compositeState
index a02d21c..b3c8841 100644 (file)
@@ -27,6 +27,7 @@ import org.onap.cps.integration.performance.base.CpsPerfTestBase
 class UpdatePerfTest extends CpsPerfTestBase {
 
     CpsDataService objectUnderTest
+    def now = OffsetDateTime.now()
 
     def setup() { objectUnderTest = cpsDataService }
 
@@ -36,7 +37,7 @@ class UpdatePerfTest extends CpsPerfTestBase {
             def jsonData = readResourceDataFile('openroadm/innerNode.json').replace('NODE_ID_HERE', '10')
         when: 'the fragment entities are updated by the data nodes'
             stopWatch.start()
-            objectUnderTest.updateDataNodeAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm1', parentNodeXpath, jsonData, OffsetDateTime.now())
+            objectUnderTest.updateDataNodeAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm1', parentNodeXpath, jsonData, now)
             stopWatch.stop()
             def updateDurationInMillis = stopWatch.getTotalTimeMillis()
         then: 'update duration is under 1000 milliseconds'
@@ -52,11 +53,39 @@ class UpdatePerfTest extends CpsPerfTestBase {
             ]}
         when: 'the fragment entities are updated by the data nodes'
             stopWatch.start()
-            objectUnderTest.updateDataNodesAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm2', nodesJsonData, OffsetDateTime.now())
+            objectUnderTest.updateDataNodesAndDescendants(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm2', nodesJsonData, now)
             stopWatch.stop()
             def updateDurationInMillis = stopWatch.getTotalTimeMillis()
         then: 'update duration is under 5000 milliseconds'
             recordAndAssertPerformance('Update 10 data nodes', 4000, updateDurationInMillis)
     }
 
+    def 'Update leaves for 1 data node'() {
+        given: 'Updated json for openroadm data'
+            def jsonDataUpdated  = "{'openroadm-device':{'device-id':'C201-7-1A-10','status':'fail','ne-state':'jeopardy'}}"
+            def jsonDataOriginal = "{'openroadm-device':{'device-id':'C201-7-1A-10','status':'success','ne-state':'inservice'}}"
+        when: 'update is performed for leaves'
+            stopWatch.start()
+            objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm3', "/openroadm-devices", jsonDataUpdated, now)
+            objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm3', "/openroadm-devices", jsonDataOriginal, now)
+            stopWatch.stop()
+            def updateDurationInMillis = stopWatch.getTotalTimeMillis()
+        then: 'update duration is under 750 milliseconds'
+            recordAndAssertPerformance('Update leaves for 1 data node', 750, updateDurationInMillis)
+    }
+
+    def 'Batch update leaves for 50 data nodes'() {
+        given: 'Updated json for openroadm data'
+            def jsonDataUpdated  = "{'openroadm-device':[" + (1..50).collect { "{'device-id':'C201-7-1A-" + it + "','status':'fail','ne-state':'jeopardy'}" }.join(",") + "]}"
+            def jsonDataOriginal = "{'openroadm-device':[" + (1..50).collect { "{'device-id':'C201-7-1A-" + it + "','status':'success','ne-state':'inservice'}" }.join(",") + "]}"
+        when: 'update is performed for leaves'
+            stopWatch.start()
+            objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm4', "/openroadm-devices", jsonDataUpdated, now)
+            objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm4', "/openroadm-devices", jsonDataOriginal, now)
+            stopWatch.stop()
+            def updateDurationInMillis = stopWatch.getTotalTimeMillis()
+        then: 'update duration is under 3500 milliseconds'
+            recordAndAssertPerformance('Batch update leaves for 50 data nodes', 3500, updateDurationInMillis)
+    }
+
 }