diff options
Diffstat (limited to 'cps-ncmp-service')
7 files changed, 113 insertions, 17 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java index ce850cc82f..1ad61e6a6d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java @@ -28,6 +28,7 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum import java.util.Collection; import java.util.Map; import java.util.Set; +import org.onap.cps.ncmp.api.inventory.CompositeState; import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; import org.onap.cps.ncmp.api.models.DmiPluginRegistration; import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse; @@ -122,6 +123,14 @@ public interface NetworkCmProxyDataService { Map<String, String> getCmHandlePublicProperties(String cmHandleId); /** + * Get cm handle composite state by cm handle id. + * + * @param cmHandleId cm handle identifier + * @return a cm handle composite state + */ + CompositeState getCmHandleCompositeState(String cmHandleId); + + /** * Query and return cm handles that match the given query parameters. * * @param cmHandleQueryApiParameters the cm handle query parameters diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index f44c28c713..bfc740786e 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -222,6 +222,18 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } /** + * Get cm handle composite state for a given cm handle id. + * + * @param cmHandleId cm handle identifier + * @return cm handle state + */ + @Override + public CompositeState getCmHandleCompositeState(final String cmHandleId) { + CpsValidator.validateNameCharacters(cmHandleId); + return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState(); + } + + /** * THis method registers a cm handle and initiates modules sync. * * @param dmiPluginRegistration dmi plugin registration information. diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java index 4e5c57ba57..a9e7164fd7 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java @@ -24,6 +24,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent; import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @@ -33,6 +34,7 @@ import org.springframework.stereotype.Component; @Component @Slf4j @RequiredArgsConstructor +@ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true) public class NcmpAsyncRequestResponseEventConsumer { private final NcmpAsyncRequestResponseEventProducer ncmpAsyncRequestResponseEventProducer; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java index 6804ac0f0b..7b5ceb57a4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java @@ -47,17 +47,23 @@ public class NcmpEventsService { @Value("${app.ncmp.events.topic:ncmp-events}") private String topicName; + @Value("${notification.enabled:true}") + private boolean notificationsEnabled; + /** * Publish the NcmpEvent to the public topic. * * @param cmHandleId Cm Handle Id */ public void publishNcmpEvent(final String cmHandleId) { - - final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle( - inventoryPersistence.getYangModelCmHandle(cmHandleId)); - final NcmpEvent ncmpEvent = ncmpEventsCreator.populateNcmpEvent(cmHandleId, ncmpServiceCmHandle); - ncmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent); - + if (notificationsEnabled) { + final NcmpServiceCmHandle ncmpServiceCmHandle = + YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle( + inventoryPersistence.getYangModelCmHandle(cmHandleId)); + final NcmpEvent ncmpEvent = ncmpEventsCreator.populateNcmpEvent(cmHandleId, ncmpServiceCmHandle); + ncmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent); + } else { + log.debug("Notifications disabled."); + } } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 1d4312c682..92183f927a 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -27,6 +27,8 @@ import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState import org.onap.cps.ncmp.api.inventory.InventoryPersistence +import org.onap.cps.ncmp.api.inventory.LockReasonCategory +import org.onap.cps.ncmp.api.inventory.SyncState import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters import org.onap.cps.ncmp.api.models.ConditionApiProperties import org.onap.cps.ncmp.api.models.DmiPluginRegistration @@ -169,19 +171,29 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def 'Get a cm handle.'() { given: 'the system returns a yang modelled cm handle' def dmiServiceName = 'some service name' + def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, + lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.LOCKED_MISBEHAVING).details("lock misbehaving details").build(), + lastUpdateTime: 'some-timestamp', + dataSyncEnabled: false, + dataStores: dataStores()) def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')] def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')] - def compositeState = new CompositeState(cmHandleState: 'ADVISED') def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState) 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle when: 'getting cm handle details for a given cm handle id from ncmp service' def result = objectUnderTest.getNcmpServiceCmHandle('some-cm-handle') - then: 'the result returns the correct data' + then: 'the result is a ncmpServiceCmHandle' + result.class == NcmpServiceCmHandle.class + and: 'the cm handle contains the cm handle id' result.cmHandleId == 'some-cm-handle' + and: 'the cm handle contains the DMI Properties' result.dmiProperties ==[ Book:'Romance Novel' ] + and: 'the cm handle contains the public Properties' result.publicProperties == [ "Public Book":'Public Romance Novel' ] - result.compositeState.cmHandleState == CmHandleState.ADVISED + and: 'the cm handle contains the cm handle composite state' + result.compositeState == compositeState + } def 'Get a cm handle with an invalid id.'() { @@ -207,7 +219,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { } def 'Get cm handle public properties with an invalid id.'() { - when: 'getting cm handle details for a given cm handle id with an invalid name' + when: 'getting cm handle public properties for a given cm handle id with an invalid name' objectUnderTest.getCmHandlePublicProperties('invalid cm handle with spaces') then: 'an exception is thrown' thrown(DataValidationException) @@ -215,6 +227,33 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 0 * mockInventoryPersistence.getYangModelCmHandle(*_) } + def 'Get cm handle composite state'() { + given: 'a yang modelled cm handle' + def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, + lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.LOCKED_MISBEHAVING).details("lock misbehaving details").build(), + lastUpdateTime: 'some-timestamp', + dataSyncEnabled: false, + dataStores: dataStores()) + def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] + def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')] + def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState) + and: 'the system returns this yang modelled cm handle' + 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle + when: 'getting cm handle composite state for a given cm handle id from ncmp service' + def result = objectUnderTest.getCmHandleCompositeState('some-cm-handle') + then: 'the result returns the correct data' + result == compositeState + } + + def 'Get cm handle composite state with an invalid id.'() { + when: 'getting cm handle composite state for a given cm handle id with an invalid name' + objectUnderTest.getCmHandleCompositeState('invalid cm handle with spaces') + then: 'an exception is thrown' + thrown(DataValidationException) + and: 'the yang model cm handle retriever is not invoked' + 0 * mockInventoryPersistence.getYangModelCmHandle(_) + } + def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() { given: 'cpsDataService returns valid datanode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', @@ -265,4 +304,11 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'result is the same collection as returned by the CPS Data Service' assert result == ['cm-handle-id-1'] as Set } + + def dataStores() { + CompositeState.DataStores.builder() + .operationalDataStore(CompositeState.Operational.builder() + .syncState(SyncState.NONE_REQUESTED) + .lastSyncTime('some-timestamp').build()).build() + } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy index e265fef054..52806a8673 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy @@ -30,17 +30,25 @@ class NcmpEventsServiceSpec extends Specification { def mockInventoryPersistence = Mock(InventoryPersistence) def mockNcmpEventsPublisher = Mock(NcmpEventsPublisher) - def mockNcmpEventsMapper = Mock(NcmpEventsCreator) + def mockNcmpEventsCreator = Mock(NcmpEventsCreator) - def objectUnderTest = new NcmpEventsService(mockInventoryPersistence, mockNcmpEventsPublisher, mockNcmpEventsMapper) + def objectUnderTest = new NcmpEventsService(mockInventoryPersistence, mockNcmpEventsPublisher, mockNcmpEventsCreator) - def 'Create and Publish event for #operation'() { + def 'Create and Publish ncmp event where events are #scenario'() { given: 'a cm handle id and operation and responses are mocked' mockResponses('test-cm-handle-id', 'test-topic') + and: 'notifications enabled is #notificationsEnabled' + objectUnderTest.notificationsEnabled = notificationsEnabled when: 'service is called to publish ncmp event' objectUnderTest.publishNcmpEvent('test-cm-handle-id') - then: 'no exception is thrown' - noExceptionThrown() + then: 'creator is called #expectedTimesMethodCalled times' + expectedTimesMethodCalled * mockNcmpEventsCreator.populateNcmpEvent('test-cm-handle-id', _) + and: 'publisher is called #expectedTimesMethodCalled times' + expectedTimesMethodCalled * mockNcmpEventsPublisher.publishEvent(*_) + where: 'the following values are used' + scenario | notificationsEnabled|| expectedTimesMethodCalled + 'enabled' | true || 1 + 'disabled' | false || 0 } def mockResponses(cmHandleId, topicName) { @@ -50,9 +58,8 @@ class NcmpEventsServiceSpec extends Specification { def ncmpServiceCmhandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle) mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle - mockNcmpEventsMapper.populateNcmpEvent(cmHandleId, ncmpServiceCmhandle) >> ncmpEvent + mockNcmpEventsCreator.populateNcmpEvent(cmHandleId, ncmpServiceCmhandle) >> ncmpEvent mockNcmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent) >> {} } - } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy index 438ebed8f6..cf9c6bbcfa 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/YangModelCmHandleSpec.groovy @@ -21,6 +21,10 @@ package org.onap.cps.ncmp.api.models import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.inventory.CmHandleState +import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder +import org.onap.cps.ncmp.api.inventory.LockReasonCategory +import org.onap.cps.ncmp.api.inventory.SyncState import spock.lang.Specification import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA @@ -34,6 +38,13 @@ class YangModelCmHandleSpec extends Specification { ncmpServiceCmHandle.cmHandleId = 'cm-handle-id01' ncmpServiceCmHandle.dmiProperties = [myDmiProperty:'value1'] ncmpServiceCmHandle.publicProperties = [myPublicProperty:'value2'] + and: 'with a composite state' + def compositeState = new CompositeStateBuilder() + .withCmHandleState(CmHandleState.LOCKED) + .withLastUpdatedTime('some-update-time') + .withLockReason(LockReasonCategory.LOCKED_MISBEHAVING, 'locked other details') + .withOperationalDataStores(SyncState.SYNCHRONIZED, 'some-sync-time').build() + ncmpServiceCmHandle.setCompositeState(compositeState) when: 'it is converted to a yang model cm handle' def objectUnderTest = YangModelCmHandle.toYangModelCmHandle('', '', '', ncmpServiceCmHandle) then: 'the result has the right size' @@ -44,6 +55,9 @@ class YangModelCmHandleSpec extends Specification { and: 'the public property in the result has the correct name and value' assert objectUnderTest.publicProperties[0].name == 'myPublicProperty' assert objectUnderTest.publicProperties[0].value == 'value2' + and: 'the composite state matches the composite state of the ncmpServiceCmHandle' + objectUnderTest.getCompositeState().cmHandleState == CmHandleState.LOCKED + objectUnderTest.getCompositeState() == ncmpServiceCmHandle.getCompositeState() } def 'Resolve DMI service name: #scenario and #requiredService service require.'() { |