- 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>
<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>
.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());
}
}
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 {
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', _, _) >> {
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
}
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
@Autowired
ReadinessManager readinessManager
+ @Autowired
+ MeterRegistry meterRegistry
+
@Value('${ncmp.policy-executor.server.port:8080}')
private String policyServerPort;
Duration.between(eventTimeAsOffsetDateTime, ZonedDateTime.now()).seconds < 3
}
+ def clearPreviousInstrumentation() {
+ meterRegistry.clear()
+ }
+
}
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
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
def setup() {
objectUnderTest = networkCmProxyInventoryFacade
subscribeAndClearPreviousMessages('test-group', 'ncmp-events')
+ clearPreviousInstrumentation()
}
def cleanup() {
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.'() {
return true
}
+ def countLcmEventTimerInvocations() {
+ def totalCountForAllTagCombinations = 0
+ for (def timer : meterRegistry.get('cps.ncmp.lcm.events.send').timers()) {
+ totalCountForAllTagCombinations = totalCountForAllTagCombinations + timer.count()
+ }
+ return totalCountForAllTagCombinations
+ }
+
}
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'
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')
}
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) {
}
assert notificationMessages[0].event.cmHandleId.contains(cmHandleId)
assert notificationMessages[0].event.dataProducerIdentifier == 'my-data-producer-id'
-
cleanup: 'deregister CM handle'
deregisterCmHandle(DMI1_URL, cmHandleId)
}
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
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'
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)
}
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)
}
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
ModuleSyncWatchdog objectUnderTest
- @Autowired
- MeterRegistry meterRegistry
-
@Autowired
IMap<String, Integer> cmHandlesByState