CmHandleState Handler 08/129808/7
authormpriyank <priyank.maheshwari@est.tech>
Wed, 6 Jul 2022 20:56:47 +0000 (21:56 +0100)
committermpriyank <priyank.maheshwari@est.tech>
Fri, 8 Jul 2022 14:59:56 +0000 (15:59 +0100)
- State handler taking care of ADVISED, READY and LOCKED state
  transition at the moment.
- For now I have not removed the actual code but eventually state
  handler will take care of persisting the state and publishing of the
  events
- Rebased code to add the global parameter related to dataSyncCache
- UPCOMING : The classes will be prefixed/renamed with LCM once we have the
  LcmEvent created with new schema

Issue-ID: CPS-1118
Change-Id: Ic45d95169eb0c06cfb35c907d34380dbcbf2da11
Signed-off-by: mpriyank <priyank.maheshwari@est.tech>
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandler.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImpl.java [new file with mode: 0644]
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImplSpec.groovy [new file with mode: 0644]
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsServiceSpec.groovy

diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandler.java
new file mode 100644 (file)
index 0000000..7728b5f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.event;
+
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.CmHandleState;
+
+/**
+ * The implementation of it should handle the persisting of composite state and delegate the request to publish the
+ * corresponding ncmp event.
+ */
+public interface NcmpEventsCmHandleStateHandler {
+
+    /**
+     * Updates the composite state of cmHandle based on cmHandleState.
+     *
+     * @param yangModelCmHandle   cm handle represented as yang model
+     * @param targetCmHandleState target cm handle state
+     */
+    void updateCmHandleState(final YangModelCmHandle yangModelCmHandle, final CmHandleState targetCmHandleState);
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImpl.java
new file mode 100644 (file)
index 0000000..26a1c5b
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.event;
+
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED;
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.LOCKED;
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.READY;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.CmHandleState;
+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.utils.JsonObjectMapper;
+import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NcmpEventsCmHandleStateHandlerImpl implements NcmpEventsCmHandleStateHandler {
+
+    private final InventoryPersistence inventoryPersistence;
+    private final NcmpEventsCreator ncmpEventsCreator;
+    private final JsonObjectMapper jsonObjectMapper;
+    private final NcmpEventsService ncmpEventsService;
+
+    @Value("${data-sync.cache.enabled:false}")
+    private boolean isGlobalDataSyncCacheEnabled;
+
+
+    @Override
+    public void updateCmHandleState(final YangModelCmHandle yangModelCmHandle,
+            final CmHandleState targetCmHandleState) {
+
+        if (yangModelCmHandle.getCompositeState().getCmHandleState() == targetCmHandleState) {
+            log.debug("CmHandle with id : {} already in state : {}", yangModelCmHandle.getId(), targetCmHandleState);
+        } else {
+            updateToSpecifiedCmHandleState(yangModelCmHandle, targetCmHandleState);
+            publishNcmpEvent(yangModelCmHandle);
+        }
+
+    }
+
+    private void updateToSpecifiedCmHandleState(final YangModelCmHandle yangModelCmHandle,
+            final CmHandleState targetCmHandleState) {
+
+        if (READY == targetCmHandleState) {
+            CompositeStateUtils.setCompositeStateToReadyWithInitialDataStoreSyncState(isGlobalDataSyncCacheEnabled)
+                    .accept(yangModelCmHandle.getCompositeState());
+            inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState());
+        } else if (ADVISED == targetCmHandleState) {
+            if (yangModelCmHandle.getCompositeState().getCmHandleState() == LOCKED) {
+                retryCmHandle(yangModelCmHandle);
+            } else {
+                registerNewCmHandle(yangModelCmHandle);
+            }
+        } else {
+            CompositeStateUtils.setCompositeState(targetCmHandleState).accept(yangModelCmHandle.getCompositeState());
+            inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState());
+        }
+
+    }
+
+    private void retryCmHandle(final YangModelCmHandle yangModelCmHandle) {
+        CompositeStateUtils.setCompositeStateForRetry()
+                .accept(yangModelCmHandle.getCompositeState());
+        inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState());
+    }
+
+    private void registerNewCmHandle(final YangModelCmHandle yangModelCmHandle) {
+        CompositeStateUtils.setCompositeState(ADVISED).accept(yangModelCmHandle.getCompositeState());
+        inventoryPersistence.saveListElements(
+                String.format("{\"cm-handles\":[%s]}", jsonObjectMapper.asJsonString(yangModelCmHandle)));
+    }
+
+    private void publishNcmpEvent(final YangModelCmHandle yangModelCmHandle) {
+        final NcmpServiceCmHandle ncmpServiceCmHandle =
+                YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle);
+        final String cmHandleId = ncmpServiceCmHandle.getCmHandleId();
+        final NcmpEvent ncmpEvent = ncmpEventsCreator.populateNcmpEvent(cmHandleId, ncmpServiceCmHandle);
+        ncmpEventsService.publishNcmpEvent(cmHandleId, ncmpEvent);
+    }
+}
index 7b5ceb5..5e02e0d 100644 (file)
@@ -22,15 +22,12 @@ package org.onap.cps.ncmp.api.impl.event;
 
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
-import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
-import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
 import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 /**
- * NcmpEventService to map the event correctly and publish to the public topic.
+ * NcmpEventService to call the publisher and publish on the dedicated topic.
  */
 
 @Slf4j
@@ -38,12 +35,8 @@ import org.springframework.stereotype.Service;
 @RequiredArgsConstructor
 public class NcmpEventsService {
 
-    private final InventoryPersistence inventoryPersistence;
-
     private final NcmpEventsPublisher ncmpEventsPublisher;
 
-    private final NcmpEventsCreator ncmpEventsCreator;
-
     @Value("${app.ncmp.events.topic:ncmp-events}")
     private String topicName;
 
@@ -54,13 +47,10 @@ public class NcmpEventsService {
      * Publish the NcmpEvent to the public topic.
      *
      * @param cmHandleId Cm Handle Id
+     * @param ncmpEvent  Ncmp Event
      */
-    public void publishNcmpEvent(final String cmHandleId) {
+    public void publishNcmpEvent(final String cmHandleId, final NcmpEvent 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/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java
new file mode 100644 (file)
index 0000000..506bd11
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.inventory;
+
+import java.util.function.Consumer;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * It will have all the utility method responsible for handling the composite state.
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class CompositeStateUtils {
+
+    /**
+     * Sets the cmHandleState to the provided state and updates the timestamp.
+     *
+     * @return Updated CompositeState
+     */
+    public static Consumer<CompositeState> setCompositeState(final CmHandleState cmHandleState) {
+        return compositeState -> {
+            compositeState.setCmHandleState(cmHandleState);
+            compositeState.setLastUpdateTimeNow();
+        };
+    }
+
+    /**
+     * Sets the cmHandleState to READY and operational datastore sync state based on the global flag.
+     *
+     * @return Updated CompositeState
+     */
+    public static Consumer<CompositeState> setCompositeStateToReadyWithInitialDataStoreSyncState(
+            final boolean isGlobalDataSyncCacheEnabled) {
+        return compositeState -> {
+            compositeState.setDataSyncEnabled(isGlobalDataSyncCacheEnabled);
+            compositeState.setCmHandleState(CmHandleState.READY);
+            final CompositeState.Operational operational =
+                    getInitialDataStoreSyncState(compositeState.getDataSyncEnabled());
+            final CompositeState.DataStores dataStores =
+                    CompositeState.DataStores.builder().operationalDataStore(operational).build();
+            compositeState.setDataStores(dataStores);
+        };
+    }
+
+    private static CompositeState.Operational getInitialDataStoreSyncState(final boolean dataSyncEnabled) {
+        final DataStoreSyncState dataStoreSyncState =
+                dataSyncEnabled ? DataStoreSyncState.UNSYNCHRONIZED : DataStoreSyncState.NONE_REQUESTED;
+        return CompositeState.Operational.builder().dataStoreSyncState(dataStoreSyncState).build();
+    }
+
+    /**
+     * Sets the cmHandleState to ADVISED and retain the lock details. Used in retry scenarios.
+     *
+     * @return Updated CompositeState
+     */
+    public static Consumer<CompositeState> setCompositeStateForRetry() {
+        return compositeState -> {
+            compositeState.setCmHandleState(CmHandleState.ADVISED);
+            compositeState.setLastUpdateTimeNow();
+            final String oldLockReasonDetails = compositeState.getLockReason().getDetails();
+            final CompositeState.LockReason lockReason =
+                    CompositeState.LockReason.builder().details(oldLockReasonDetails).build();
+            compositeState.setLockReason(lockReason);
+        };
+    }
+}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImplSpec.groovy
new file mode 100644 (file)
index 0000000..f2e730d
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.event
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
+import org.onap.cps.ncmp.api.inventory.CompositeState
+import org.onap.cps.ncmp.api.inventory.DataStoreSyncState
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence
+import org.onap.cps.utils.JsonObjectMapper
+import spock.lang.Specification
+
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.LOCKED
+import static org.onap.cps.ncmp.api.inventory.CmHandleState.READY
+import static org.onap.cps.ncmp.api.inventory.LockReasonCategory.LOCKED_MODULE_SYNC_FAILED
+
+class NcmpEventsCmHandleStateHandlerImplSpec extends Specification {
+
+    def mockInventoryPersistence = Mock(InventoryPersistence)
+    def mockNcmpEventsCreator = Mock(NcmpEventsCreator)
+    def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
+    def mockNcmpEventsService = Mock(NcmpEventsService)
+
+    def objectUnderTest = new NcmpEventsCmHandleStateHandlerImpl(mockInventoryPersistence, mockNcmpEventsCreator, spiedJsonObjectMapper, mockNcmpEventsService)
+
+    def 'Update and Publish Events on State Change #stateChange'() {
+        given: 'Cm Handle represented as YangModelCmHandle'
+            def cmHandleId = 'cmhandle-id-1'
+            def compositeState = new CompositeState(cmHandleState: fromCmHandleState)
+            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        when: 'update state is invoked'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, toCmHandleState)
+        then: 'state is saved using inventory persistence'
+            expectedCallsToInventoryPersistence * mockInventoryPersistence.saveCmHandleState(cmHandleId, _)
+        and: 'event service is called to publish event'
+            expectedCallsToEventService * mockNcmpEventsService.publishNcmpEvent(cmHandleId, _)
+        where: 'state change parameters are provided'
+            stateChange          | fromCmHandleState | toCmHandleState || expectedCallsToInventoryPersistence | expectedCallsToEventService
+            'ADVISED to READY'   | ADVISED           | READY           || 1                                   | 1
+            'READY to LOCKED'    | READY             | LOCKED          || 1                                   | 1
+            'ADVISED to ADVISED' | ADVISED           | ADVISED         || 0                                   | 0
+            'READY to READY'     | READY             | READY           || 0                                   | 0
+            'LOCKED to LOCKED'   | LOCKED            | LOCKED          || 0                                   | 0
+
+    }
+
+    def 'Update and Publish Events on State Change from NO_EXISTING state to ADVISED'() {
+        given: 'Cm Handle represented as YangModelCmHandle in READY state'
+            def cmHandleId = 'cmhandle-id-1'
+            def compositeState = new CompositeState()
+            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        when: 'update state is invoked'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, ADVISED)
+        then: 'state is saved using inventory persistence'
+            1 * mockInventoryPersistence.saveListElements(_)
+        and: 'event service is called to publish event'
+            1 * mockNcmpEventsService.publishNcmpEvent(cmHandleId, _)
+    }
+
+    def 'Update and Publish Events on State Change from LOCKED to ADVISED'() {
+        given: 'Cm Handle represented as YangModelCmHandle in LOCKED state'
+            def cmHandleId = 'cmhandle-id-1'
+            def compositeState = new CompositeState(cmHandleState: LOCKED,
+                lockReason: CompositeState.LockReason.builder().lockReasonCategory(LOCKED_MODULE_SYNC_FAILED).details('some lock details').build())
+            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        when: 'update state is invoked'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, ADVISED)
+        then: 'state is saved using inventory persistence and old lock reason details are retained'
+            1 * mockInventoryPersistence.saveCmHandleState(cmHandleId, _) >> {
+                args -> {
+                        assert (args[1] as CompositeState).lockReason.details == 'some lock details'
+                    }
+            }
+        and: 'event service is called to publish event'
+            1 * mockNcmpEventsService.publishNcmpEvent(cmHandleId, _)
+    }
+
+    def 'Update and Publish Events on State Change to READY with #scenario'() {
+        given: 'Cm Handle represented as YangModelCmHandle'
+            def cmHandleId = 'cmhandle-id-1'
+            def compositeState = new CompositeState(cmHandleState: ADVISED)
+            def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState)
+        and: 'global sync flag is set'
+            objectUnderTest.isGlobalDataSyncCacheEnabled = dataSyncCacheEnabled
+        when: 'update cmhandle state is invoked'
+            objectUnderTest.updateCmHandleState(yangModelCmHandle, READY)
+        then: 'state is saved using inventory persistence with expected dataSyncState'
+            1 * mockInventoryPersistence.saveCmHandleState(cmHandleId, _) >> {
+                args-> {
+                    assert (args[1] as CompositeState).dataSyncEnabled == dataSyncCacheEnabled
+                    assert (args[1] as CompositeState).dataStores.operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState
+
+                }
+            }
+        and: 'event service is called to publish event'
+            1 * mockNcmpEventsService.publishNcmpEvent(cmHandleId, _)
+        where:
+            scenario                         | dataSyncCacheEnabled || expectedDataStoreSyncState
+            'data sync cache enabled'        | true                 || DataStoreSyncState.UNSYNCHRONIZED
+            'data sync cache is not enabled' | false                || DataStoreSyncState.NONE_REQUESTED
+
+    }
+}
index 52806a8..8bf02c1 100644 (file)
 
 package org.onap.cps.ncmp.api.impl.event
 
-import org.onap.cps.ncmp.api.impl.utils.YangDataConverter
-import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle
-import org.onap.cps.ncmp.api.inventory.InventoryPersistence
+
 import org.onap.ncmp.cmhandle.lcm.event.NcmpEvent
 import spock.lang.Specification
 
 class NcmpEventsServiceSpec extends Specification {
 
-    def mockInventoryPersistence = Mock(InventoryPersistence)
     def mockNcmpEventsPublisher = Mock(NcmpEventsPublisher)
-    def mockNcmpEventsCreator = Mock(NcmpEventsCreator)
 
-    def objectUnderTest = new NcmpEventsService(mockInventoryPersistence, mockNcmpEventsPublisher, mockNcmpEventsCreator)
+    def objectUnderTest = new NcmpEventsService(mockNcmpEventsPublisher)
 
     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')
+        given: 'a cm handle id and Ncmp Event'
+            def cmHandleId = 'test-cm-handle-id'
+            def ncmpEvent = new NcmpEvent(eventId: UUID.randomUUID().toString(), eventCorrelationId: cmHandleId)
         and: 'notifications enabled is #notificationsEnabled'
             objectUnderTest.notificationsEnabled = notificationsEnabled
         when: 'service is called to publish ncmp event'
-            objectUnderTest.publishNcmpEvent('test-cm-handle-id')
-        then: 'creator is called #expectedTimesMethodCalled times'
-            expectedTimesMethodCalled * mockNcmpEventsCreator.populateNcmpEvent('test-cm-handle-id', _)
-        and: 'publisher is called #expectedTimesMethodCalled times'
-            expectedTimesMethodCalled * mockNcmpEventsPublisher.publishEvent(*_)
+            objectUnderTest.publishNcmpEvent('test-cm-handle-id', ncmpEvent)
+        then: 'publisher is called #expectedTimesMethodCalled times'
+            expectedTimesMethodCalled * mockNcmpEventsPublisher.publishEvent(_, cmHandleId, ncmpEvent)
         where: 'the following values are used'
-            scenario   | notificationsEnabled|| expectedTimesMethodCalled
-            'enabled'  | true                || 1
-            'disabled' | false               || 0
-    }
-
-    def mockResponses(cmHandleId, topicName) {
-
-        def yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, publicProperties: [new YangModelCmHandle.Property('publicProperty1', 'value1')], dmiProperties: [])
-        def ncmpEvent = new NcmpEvent(eventId: UUID.randomUUID().toString(), eventCorrelationId: cmHandleId)
-        def ncmpServiceCmhandle = YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(yangModelCmHandle)
-
-        mockInventoryPersistence.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle
-        mockNcmpEventsCreator.populateNcmpEvent(cmHandleId, ncmpServiceCmhandle) >> ncmpEvent
-        mockNcmpEventsPublisher.publishEvent(topicName, cmHandleId, ncmpEvent) >> {}
+            scenario   | notificationsEnabled || expectedTimesMethodCalled
+            'enabled'  | true                 || 1
+            'disabled' | false                || 0
     }
 
 }