Fix Null Pointer Exception during LCM Event Metric Recording 24/142724/2 master
authorToineSiebelink <toine.siebelink@est.tech>
Wed, 10 Dec 2025 15:34:36 +0000 (15:34 +0000)
committerToineSiebelink <toine.siebelink@est.tech>
Wed, 10 Dec 2025 15:55:08 +0000 (15:55 +0000)
- Add null check when recording metric for unknown states (initial create and delete use cases)
- Extend Create Integration test to verify the (number of) recording metrics
- Moved Instrumentation bean to integration testbase as it is now used in several test classes
- Update version of docker test container to latest (part of troubleshooting with Docker for windows integration)
- Clean up some legacy issues in related integration testware
  - unnecessary and distracting spacing
  - correct use of #testValue in descriptions

Issue-ID:CPS-3088

Change-Id: Ic1163e33606ee2fe2c4e136e63282708a4625f60
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
cps-dependencies/pom.xml
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventProducer.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/lcm/LcmEventProducerSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/base/CpsIntegrationSpecBase.groovy
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/CmHandleCreateSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/CmHandleUpdateSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/CmHandleUpgradeSpec.groovy
integration-test/src/test/groovy/org/onap/cps/integration/functional/ncmp/inventory/ModuleSyncWatchdogIntegrationSpec.groovy

index c4f0c36..751b45c 100644 (file)
@@ -39,7 +39,6 @@
         <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
         <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
         <sonar.skip>true</sonar.skip>
-        <testcontainers.version>1.18.3</testcontainers.version>
         <mapstruct.version>1.4.2.Final</mapstruct.version>
         <jetty-version>11.0.16</jetty-version>
         <version.opentelemetry-instrumentation-bom>2.1.0-alpha</version.opentelemetry-instrumentation-bom>
             <dependency>
                 <groupId>org.testcontainers</groupId>
                 <artifactId>testcontainers-bom</artifactId>
-                <version>1.18.3</version>
+                <version>1.20.4</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
index 85532b3..37ba176 100644 (file)
@@ -132,8 +132,11 @@ public class LcmEventProducer {
             .register(meterRegistry));
     }
 
-    private Tag createCmHandleStateTag(final String tageLabel, final Values values) {
-        return Tag.of(tageLabel, values.getCmHandleState().value());
+    private Tag createCmHandleStateTag(final String tagLabel, final Values values) {
+        if (values == null) {
+            return Tag.of(tagLabel, "N/A");
+        }
+        return Tag.of(tagLabel, values.getCmHandleState().value());
     }
 
 }
index bfcff01..be65e4a 100644 (file)
@@ -29,7 +29,6 @@ import org.springframework.kafka.KafkaException
 import spock.lang.Specification
 
 import static org.onap.cps.ncmp.api.inventory.models.CmHandleState.ADVISED
-import static org.onap.cps.ncmp.api.inventory.models.CmHandleState.READY
 
 class LcmEventProducerSpec extends Specification {
 
@@ -40,14 +39,14 @@ class LcmEventProducerSpec extends Specification {
     def objectUnderTest = new LcmEventProducer(mockEventProducer, lcmEventObjectCreator, meterRegistry)
 
     def cmHandleTransitionPair = new CmHandleTransitionPair(
-        new YangModelCmHandle(id: 'ch-1', compositeState: new CompositeState(cmHandleState: ADVISED), additionalProperties: [], publicProperties: []),
-        new YangModelCmHandle(id: 'ch-1', compositeState: new CompositeState(cmHandleState: READY), additionalProperties: [], publicProperties: [])
+        new YangModelCmHandle(id: 'ch-1',  additionalProperties: [], publicProperties: []),
+        new YangModelCmHandle(id: 'ch-1', compositeState: new CompositeState(cmHandleState: ADVISED), additionalProperties: [], publicProperties: [])
     )
 
     def 'Create and send lcm event where notifications are #scenario.'() {
         given: 'notificationsEnabled is #notificationsEnabled'
             objectUnderTest.notificationsEnabled = notificationsEnabled
-        when: 'service is called to send a batch of lcm events'
+        when: 'event send for (batch of) 1 cm handle transition pair (new cm handle going to READY)'
             objectUnderTest.sendLcmEventBatchAsynchronously([cmHandleTransitionPair])
         then: 'producer is called #expectedTimesMethodCalled times with correct identifiers'
             expectedTimesMethodCalled * mockEventProducer.sendLegacyEvent(_, 'ch-1', _, _) >> {
@@ -61,7 +60,7 @@ class LcmEventProducerSpec extends Specification {
             def timer = meterRegistry.find('cps.ncmp.lcm.events.send').timer()
             if (notificationsEnabled) {
                 assert timer.count() == 1
-                assert timer.id.tags.containsAll(Tag.of('oldCmHandleState', 'ADVISED'), Tag.of('newCmHandleState', 'READY'))
+                assert timer.id.tags.containsAll(Tag.of('oldCmHandleState', 'N/A'), Tag.of('newCmHandleState', 'ADVISED'))
             } else {
                 assert timer == null
             }
index e71511a..c8bc0b2 100644 (file)
@@ -22,6 +22,7 @@
 package org.onap.cps.integration.base
 
 import com.hazelcast.map.IMap
+import io.micrometer.core.instrument.MeterRegistry
 import okhttp3.mockwebserver.MockWebServer
 import org.onap.cps.api.CpsAnchorService
 import org.onap.cps.api.CpsDataService
@@ -163,6 +164,9 @@ abstract class CpsIntegrationSpecBase extends Specification {
     @Autowired
     ReadinessManager readinessManager
 
+    @Autowired
+    MeterRegistry meterRegistry
+
     @Value('${ncmp.policy-executor.server.port:8080}')
     private String policyServerPort;
 
@@ -356,4 +360,8 @@ abstract class CpsIntegrationSpecBase extends Specification {
         Duration.between(eventTimeAsOffsetDateTime, ZonedDateTime.now()).seconds < 3
     }
 
+    def clearPreviousInstrumentation() {
+        meterRegistry.clear()
+    }
+
 }
index 08c2160..3bb87b2 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.onap.cps.integration.functional.ncmp.inventory
 
+
 import org.apache.kafka.clients.consumer.KafkaConsumer
 import org.onap.cps.events.LegacyEvent
 import org.onap.cps.integration.KafkaTestContainer
@@ -32,6 +33,7 @@ import org.onap.cps.ncmp.api.inventory.models.LockReasonCategory
 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
 import org.onap.cps.ncmp.events.lcm.v1.LcmEvent
 import org.onap.cps.ncmp.impl.NetworkCmProxyInventoryFacadeImpl
+import spock.util.concurrent.PollingConditions
 
 import java.time.Duration
 
@@ -45,6 +47,7 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
     def setup() {
         objectUnderTest = networkCmProxyInventoryFacade
         subscribeAndClearPreviousMessages('test-group', 'ncmp-events')
+        clearPreviousInstrumentation()
     }
 
     def cleanup() {
@@ -110,8 +113,16 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
             assert messages[1].event.newValues.dataSyncEnabled == false
         and: 'there are no more messages to be read'
             assert getLatestConsumerRecordsWithMaxPollOf1Second(kafkaConsumer, 1).size() == 0
-        cleanup: 'deregister CM handle'
+        and: 'instrumentation has recorded 2 events (null > ADVISED, ADVISED > READY)'
+            new PollingConditions().within(5) {
+                assert countLcmEventTimerInvocations() == 2
+            }
+        then: 'deregister CM handle'
             deregisterCmHandle(DMI1_URL, uniqueId)
+        and: 'instrumentation has recorded 2 more events (READY > DELETING, DELETING > null)'
+            new PollingConditions().within(5) {
+                assert countLcmEventTimerInvocations() == 2 + 2
+            }
     }
 
     def 'CM Handle registration with DMI error during module sync.'() {
@@ -246,4 +257,12 @@ class CmHandleCreateSpec extends CpsIntegrationSpecBase {
         return true
     }
 
+    def countLcmEventTimerInvocations() {
+        def totalCountForAllTagCombinations = 0
+        for (def timer : meterRegistry.get('cps.ncmp.lcm.events.send').timers()) {
+            totalCountForAllTagCombinations = totalCountForAllTagCombinations + timer.count()
+        }
+        return totalCountForAllTagCombinations
+    }
+
 }
index 1bb7ee2..d497af7 100644 (file)
@@ -53,24 +53,19 @@ class CmHandleUpdateSpec extends CpsIntegrationSpecBase {
     def 'Update of CM-handle with new or unchanged alternate ID succeeds.'() {
         given: 'DMI will return modules when requested'
             dmiDispatcher1.moduleNamesPerCmHandleId = ['ch-1': ['M1', 'M2']]
-        and: "existing CM-handle with alternate ID: $oldAlternateId"
+        and: 'existing CM-handle with alternate ID: #oldAlternateId'
             registerCmHandle(DMI1_URL, 'ch-1', NO_MODULE_SET_TAG, oldAlternateId)
-
-        when: "CM-handle is registered for update with new alternate ID: $newAlternateId"
+        when: 'CM-handle is registered for update with new alternate ID: #newAlternateId'
             def cmHandleToUpdate = new NcmpServiceCmHandle(cmHandleId: 'ch-1', alternateId: newAlternateId)
             def dmiPluginRegistrationResponse =
                     objectUnderTest.updateDmiRegistration(new DmiPluginRegistration(dmiPlugin: DMI1_URL, updatedCmHandles: [cmHandleToUpdate]))
-
         then: 'registration gives successful response'
             assert dmiPluginRegistrationResponse.updatedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse('ch-1')]
-
         and: 'the CM-handle has expected alternate ID'
             assert objectUnderTest.getNcmpServiceCmHandle('ch-1').alternateId == expectedAlternateId
-
         cleanup: 'deregister CM handles'
             deregisterCmHandle(DMI1_URL, 'ch-1')
-
-        where:
+        where: 'following alternate ids are used'
             oldAlternateId | newAlternateId || expectedAlternateId
             ''             | ''             || ''
             ''             | 'new'          || 'new'
@@ -85,18 +80,14 @@ class CmHandleUpdateSpec extends CpsIntegrationSpecBase {
             dmiDispatcher1.moduleNamesPerCmHandleId = ['ch-1': ['M1', 'M2']]
         and: 'existing CM-handle with alternate ID'
             registerCmHandle(DMI1_URL, 'ch-1', NO_MODULE_SET_TAG, 'original')
-
         when: 'a CM-handle is registered for update with new alternate ID'
             def cmHandleToUpdate = new NcmpServiceCmHandle(cmHandleId: 'ch-1', alternateId: 'new')
             def dmiPluginRegistrationResponse =
                     objectUnderTest.updateDmiRegistration(new DmiPluginRegistration(dmiPlugin: DMI1_URL, updatedCmHandles: [cmHandleToUpdate]))
-
         then: 'registration gives failure response, due to cm-handle already existing'
             assert dmiPluginRegistrationResponse.updatedCmHandles == [CmHandleRegistrationResponse.createFailureResponse('ch-1', NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST)]
-
         and: 'the CM-handle still has the old alternate ID'
             assert objectUnderTest.getNcmpServiceCmHandle('ch-1').alternateId == 'original'
-
         cleanup: 'deregister CM handles'
             deregisterCmHandle(DMI1_URL, 'ch-1')
     }
@@ -105,33 +96,24 @@ class CmHandleUpdateSpec extends CpsIntegrationSpecBase {
         given: 'DMI will return modules when requested'
             def cmHandleId = 'ch-id-for-update'
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
-
         when: 'a CM-handle is registered for creation'
-
             def cmHandleToCreate = new NcmpServiceCmHandle(cmHandleId: cmHandleId)
             def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: DMI1_URL, createdCmHandles: [cmHandleToCreate])
             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(dmiPluginRegistration)
-
         then: 'registration gives successful response'
             assert dmiPluginRegistrationResponse.createdCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
-
         then: 'the module sync watchdog is triggered'
             moduleSyncWatchdog.moduleSyncAdvisedCmHandles()
-
-        and: 'flush the latest cm handle registration events( state transition from NONE to ADVISED and ADVISED to READY)'
-            getLatestConsumerRecordsWithMaxPollOf1Second(kafkaConsumer, 2)
-
+        and: 'flush and check there are 2 cm handle registration events (state transition from NONE to ADVISED and ADVISED to READY)'
+            assert getLatestConsumerRecordsWithMaxPollOf1Second(kafkaConsumer, 2).size() == 2
         and: 'cm handle updated with the data producer identifier'
             def cmHandleToUpdate = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dataProducerIdentifier: 'my-data-producer-id')
             def dmiPluginRegistrationForUpdate = new DmiPluginRegistration(dmiPlugin: DMI1_URL, updatedCmHandles: [cmHandleToUpdate])
             def dmiPluginRegistrationResponseForUpdate = objectUnderTest.updateDmiRegistration(dmiPluginRegistrationForUpdate)
-
         then: 'registration gives successful response'
             assert dmiPluginRegistrationResponseForUpdate.updatedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
-
         and: 'get the latest message'
             def consumerRecords = getLatestConsumerRecordsWithMaxPollOf1Second(kafkaConsumer, 1)
-
         and: 'the message has the updated data producer identifier'
             def notificationMessages = []
             for (def consumerRecord : consumerRecords) {
@@ -139,7 +121,6 @@ class CmHandleUpdateSpec extends CpsIntegrationSpecBase {
             }
             assert notificationMessages[0].event.cmHandleId.contains(cmHandleId)
             assert notificationMessages[0].event.dataProducerIdentifier == 'my-data-producer-id'
-
         cleanup: 'deregister CM handle'
             deregisterCmHandle(DMI1_URL, cmHandleId)
     }
index 62ea22b..fb82d69 100644 (file)
@@ -44,39 +44,29 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
             registerCmHandle(DMI1_URL, cmHandleId, initialModuleSetTag)
             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
-        when: "the CM-handle is upgraded with given moduleSetTag '${updatedModuleSetTag}'"
+        when: 'the CM-handle is upgraded with given moduleSetTag #updatedModuleSetTag'
             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: updatedModuleSetTag)
             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(
                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
-
         then: 'registration gives successful response'
             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
-
         and: 'CM-handle is in LOCKED state due to MODULE_UPGRADE'
             def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
             assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
             assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE
             assert cmHandleCompositeState.lockReason.details == "Upgrade to ModuleSetTag: ${updatedModuleSetTag}"
-
         when: 'DMI will return different modules for upgrade: M1 and M3'
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M3']
-
         and: 'the module sync watchdog is triggered twice'
             2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
-
         then: 'CM-handle goes to READY state'
             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
-
         and: 'the CM-handle has expected moduleSetTag'
             assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
-
         and: 'CM-handle has expected updated modules: M1 and M3'
             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
         cleanup: 'deregister CM-handle and remove all associated module resources'
             deregisterCmHandle(DMI1_URL, cmHandleId)
-
         where: 'following module set tags are used'
             initialModuleSetTag | updatedModuleSetTag
             NO_MODULE_SET_TAG   | NO_MODULE_SET_TAG
@@ -89,36 +79,28 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
         given: 'DMI will return modules for registration'
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleIdWithExistingModuleSetTag] = ['M1', 'M3']
-        and: "an existing CM-handle handle with moduleSetTag '${updatedModuleSetTag}'"
+        and: 'an existing CM-handle handle with moduleSetTag #updatedModuleSetTag'
             registerCmHandle(DMI1_URL, cmHandleIdWithExistingModuleSetTag, updatedModuleSetTag)
             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleIdWithExistingModuleSetTag).moduleName.sort()
-        and: "a CM-handle with moduleSetTag '${initialModuleSetTag}' which will be upgraded"
+        and: 'a CM-handle with moduleSetTag #initialModuleSetTag which will be upgraded'
             registerCmHandle(DMI1_URL, cmHandleId, initialModuleSetTag)
             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
-        when: "CM-handle is upgraded to moduleSetTag '${updatedModuleSetTag}'"
+        when: 'CM-handle is upgraded to moduleSetTag #updatedModuleSetTag'
             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: updatedModuleSetTag)
             def dmiPluginRegistrationResponse = objectUnderTest.updateDmiRegistration(
                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
-
         then: 'registration gives successful response'
             assert dmiPluginRegistrationResponse.upgradedCmHandles == [CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)]
-
         and: 'the module sync watchdog is triggered twice'
             2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
-
         and: 'CM-handle goes to READY state'
             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
-
         and: 'the CM-handle has expected moduleSetTag'
             assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == updatedModuleSetTag
-
         and: 'CM-handle has expected updated modules: M1 and M3'
             assert ['M1', 'M3'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
         cleanup: 'deregister CM-handle'
             deregisterCmHandles(DMI1_URL, [cmHandleId, cmHandleIdWithExistingModuleSetTag])
-
         where:
             initialModuleSetTag | updatedModuleSetTag
             NO_MODULE_SET_TAG   | 'module@Set2'
@@ -130,21 +112,16 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
             dmiDispatcher1.moduleNamesPerCmHandleId[cmHandleId] = ['M1', 'M2']
             registerCmHandle(DMI1_URL, cmHandleId, 'same')
             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
         when: 'CM-handle is upgraded with the same moduleSetTag'
             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: 'same')
             objectUnderTest.updateDmiRegistration(
                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
-
         then: 'CM-handle remains in READY state'
             assert CmHandleState.READY == objectUnderTest.getCmHandleCompositeState(cmHandleId).cmHandleState
-
         and: 'the CM-handle has same moduleSetTag as before'
             assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == 'same'
-
         then: 'CM-handle has same modules as before: M1 and M2'
             assert ['M1', 'M2'] == objectUnderTest.getYangResourcesModuleReferences(cmHandleId).moduleName.sort()
-
         cleanup: 'deregister CM-handle'
             deregisterCmHandle(DMI1_URL, cmHandleId)
     }
@@ -155,23 +132,18 @@ class CmHandleUpgradeSpec extends CpsIntegrationSpecBase {
             registerCmHandle(DMI1_URL, cmHandleId, 'oldTag')
         and: 'DMI is not available for upgrade'
             dmiDispatcher1.isAvailable = false
-
         when: 'the CM-handle is upgraded'
             def cmHandlesToUpgrade = new UpgradedCmHandles(cmHandles: [cmHandleId], moduleSetTag: 'newTag')
             objectUnderTest.updateDmiRegistration(
                     new DmiPluginRegistration(dmiPlugin: DMI1_URL, upgradedCmHandles: cmHandlesToUpgrade))
-
         and: 'the module sync watchdog is triggered twice'
             2.times { moduleSyncWatchdog.moduleSyncAdvisedCmHandles() }
-
         then: 'CM-handle goes to LOCKED state with reason MODULE_UPGRADE_FAILED'
             def cmHandleCompositeState = objectUnderTest.getCmHandleCompositeState(cmHandleId)
             assert cmHandleCompositeState.cmHandleState == CmHandleState.LOCKED
             assert cmHandleCompositeState.lockReason.lockReasonCategory == LockReasonCategory.MODULE_UPGRADE_FAILED
-
         and: 'the CM-handle has same moduleSetTag as before'
             assert objectUnderTest.getNcmpServiceCmHandle(cmHandleId).moduleSetTag == 'oldTag'
-
         cleanup: 'deregister CM-handle'
             deregisterCmHandle(DMI1_URL, cmHandleId)
     }
index b73aa73..11b37b9 100644 (file)
@@ -21,7 +21,6 @@
 package org.onap.cps.integration.functional.ncmp.inventory
 
 import com.hazelcast.map.IMap
-import io.micrometer.core.instrument.MeterRegistry
 import org.onap.cps.integration.base.CpsIntegrationSpecBase
 import org.onap.cps.ncmp.impl.inventory.sync.ModuleSyncWatchdog
 import org.springframework.beans.factory.annotation.Autowired
@@ -36,9 +35,6 @@ class ModuleSyncWatchdogIntegrationSpec extends CpsIntegrationSpecBase {
 
     ModuleSyncWatchdog objectUnderTest
 
-    @Autowired
-    MeterRegistry meterRegistry
-
     @Autowired
     IMap<String, Integer> cmHandlesByState