Merge "Updating docker-compose version from 3.3 to 3.8"
diff --git a/INFO.yaml b/INFO.yaml
index 610fd0e..d1a6a49 100755
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (C) 2021 Nordix Foundation.
+# Copyright (C) 2021-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.
@@ -52,11 +52,6 @@
company: 'Ericsson Software Technology'
id: 'toinesiebelink'
timezone: 'Europe/Dublin'
- - name: 'Bruno Sakoto'
- email: 'bruno.sakoto@bell.ca'
- company: 'Bell Canada'
- id: 'brusak'
- timezone: 'America/Toronto'
- name: 'Aditya Puthuparambil'
email: 'aditya.puthuparambil@bell.ca'
company: 'Bell Canada'
diff --git a/cps-application/src/main/resources/application.yml b/cps-application/src/main/resources/application.yml
index d16e977..e0fb7ef 100644
--- a/cps-application/src/main/resources/application.yml
+++ b/cps-application/src/main/resources/application.yml
@@ -164,3 +164,7 @@
sleep-time-ms: 300000
cm-handle-data-sync:
sleep-time-ms: 30000
+
+data-sync:
+ cache:
+ enabled: false
\ No newline at end of file
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
index 0000000..7728b5f
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandler.java
@@ -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
index 0000000..26a1c5b
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImpl.java
@@ -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);
+ }
+}
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 7b5ceb5..5e02e0d 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
@@ -22,15 +22,12 @@
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 @@
@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 @@
* 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
index 0000000..506bd11
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java
@@ -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/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
index 0330991..f18d843 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
@@ -31,6 +31,7 @@
import org.onap.cps.ncmp.api.inventory.DataStoreSyncState;
import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.inventory.LockReasonCategory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -45,6 +46,9 @@
private final ModuleSyncService moduleSyncService;
+ @Value("${data-sync.cache.enabled:false}")
+ private boolean isGlobalDataSyncCacheEnabled;
+
/**
* Execute Cm Handle poll which changes the cm handle state from 'ADVISED' to 'READY'.
*/
@@ -96,11 +100,9 @@
private Consumer<CompositeState> setCompositeStateToReadyWithInitialDataStoreSyncState() {
return compositeState -> {
+ compositeState.setDataSyncEnabled(isGlobalDataSyncCacheEnabled);
compositeState.setCmHandleState(CmHandleState.READY);
- final CompositeState.Operational operational = CompositeState.Operational.builder()
- .dataStoreSyncState(DataStoreSyncState.UNSYNCHRONIZED)
- .lastSyncTime(CompositeState.nowInSyncTimeFormat())
- .build();
+ final CompositeState.Operational operational = getDataStoreSyncState(compositeState.getDataSyncEnabled());
final CompositeState.DataStores dataStores = CompositeState.DataStores.builder()
.operationalDataStore(operational)
.build();
@@ -116,4 +118,11 @@
.details(oldLockReasonDetails).build();
compositeState.setLockReason(lockReason);
}
+
+ private CompositeState.Operational getDataStoreSyncState(final boolean dataSyncEnabled) {
+ final DataStoreSyncState dataStoreSyncState = dataSyncEnabled
+ ? DataStoreSyncState.UNSYNCHRONIZED : DataStoreSyncState.NONE_REQUESTED;
+ return CompositeState.Operational.builder().dataStoreSyncState(dataStoreSyncState).build();
+ }
+
}
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
index 0000000..f2e730d
--- /dev/null
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImplSpec.groovy
@@ -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
+
+ }
+}
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 52806a8..8bf02c1 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
@@ -20,46 +20,30 @@
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
}
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CompositeStateBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CompositeStateBuilderSpec.groovy
index ad65763..fa43798 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CompositeStateBuilderSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/CompositeStateBuilderSpec.groovy
@@ -23,6 +23,7 @@
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
+import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
import spock.lang.Specification
import java.time.OffsetDateTime
@@ -63,4 +64,25 @@
assert compositeState.cmHandleState == CmHandleState.ADVISED
}
+ def 'CompositeStateBuilder build'() {
+ given: 'A CompositeStateBuilder with all private fields set'
+ def finalCompositeStateBuilder = new CompositeStateBuilder()
+ .withCmHandleState(CmHandleState.ADVISED)
+ .withLastUpdatedTime(formattedDateAndTime.toString())
+ .withLockReason(LockReasonCategory.LOCKED_MODULE_SYNC_FAILED, 'locked details')
+ .withOperationalDataStores(DataStoreSyncState.SYNCHRONIZED, formattedDateAndTime)
+ when: 'build is called'
+ def result = finalCompositeStateBuilder.build()
+ then: 'result is of the correct type'
+ assert result.class == CompositeState.class
+ and: 'built result should have correct values'
+ assert !result.getDataSyncEnabled()
+ assert result.getLastUpdateTime() == formattedDateAndTime
+ assert result.getLockReason().getLockReasonCategory() == LockReasonCategory.LOCKED_MODULE_SYNC_FAILED
+ assert result.getLockReason().getDetails() == 'locked details'
+ assert result.getCmHandleState() == CmHandleState.ADVISED
+ assert result.getDataStores().getOperationalDataStore().getDataStoreSyncState() == DataStoreSyncState.SYNCHRONIZED
+ assert result.getDataStores().getOperationalDataStore().getLastSyncTime() == formattedDateAndTime
+ }
+
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy
index 740a826..4b92be3 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy
@@ -24,6 +24,7 @@
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.DataStoreSyncState
import org.onap.cps.ncmp.api.inventory.InventoryPersistence
import org.onap.cps.ncmp.api.inventory.LockReasonCategory
import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder
@@ -41,12 +42,13 @@
def objectUnderTest = new ModuleSyncWatchdog(mockInventoryPersistence, mockSyncUtils, mockModuleSyncService)
- def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handles'() {
- given: 'cm handles in an advised state'
+ def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handles where #scenario'() {
+ given: 'cm handles in an advised state and a data sync state'
def compositeState1 = new CompositeState(cmHandleState: cmHandleState)
def compositeState2 = new CompositeState(cmHandleState: cmHandleState)
def yangModelCmHandle1 = new YangModelCmHandle(id: 'some-cm-handle', compositeState: compositeState1)
def yangModelCmHandle2 = new YangModelCmHandle(id: 'some-cm-handle-2', compositeState: compositeState2)
+ objectUnderTest.isGlobalDataSyncCacheEnabled = dataSyncCacheEnabled
and: 'sync utilities return a cm handle twice'
mockSyncUtils.getAnAdvisedCmHandle() >>> [yangModelCmHandle1, yangModelCmHandle2, null]
when: 'module sync poll is executed'
@@ -57,8 +59,10 @@
1 * mockModuleSyncService.deleteSchemaSetIfExists(yangModelCmHandle1)
and: 'module sync service syncs the first cm handle and creates a schema set'
1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle1)
- and: 'the composite state cm handle state is now READY'
+ then: 'the composite state cm handle state is now READY'
assert compositeState1.getCmHandleState() == CmHandleState.READY
+ and: 'the data store sync state returns the expected state'
+ compositeState1.getDataStores().operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState
and: 'the first cm handle state is updated'
1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle', compositeState1)
then: 'the inventory persistence cm handle returns a composite state for the second cm handle'
@@ -69,6 +73,10 @@
assert compositeState2.getCmHandleState() == CmHandleState.READY
and: 'the second cm handle state is updated'
1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-2', compositeState2)
+ where:
+ scenario | dataSyncCacheEnabled || expectedDataStoreSyncState
+ 'data sync cache enabled' | true || DataStoreSyncState.UNSYNCHRONIZED
+ 'data sync cache is not enabled' | false || DataStoreSyncState.NONE_REQUESTED
}
def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handle with failure'() {