From 85ad508f2c4500667fcfbc451f22032e508eedac Mon Sep 17 00:00:00 2001 From: mpriyank Date: Wed, 6 Jul 2022 21:56:47 +0100 Subject: CmHandleState Handler - 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 --- .../impl/event/NcmpEventsCmHandleStateHandler.java | 39 ++++++++ .../event/NcmpEventsCmHandleStateHandlerImpl.java | 106 +++++++++++++++++++++ .../cps/ncmp/api/impl/event/NcmpEventsService.java | 16 +--- .../ncmp/api/inventory/CompositeStateUtils.java | 86 +++++++++++++++++ 4 files changed, 234 insertions(+), 13 deletions(-) create mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandler.java create mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/NcmpEventsCmHandleStateHandlerImpl.java create mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java (limited to 'cps-ncmp-service/src/main') 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 000000000..7728b5f92 --- /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 000000000..26a1c5bab --- /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 7b5ceb57a..5e02e0d94 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 @@ 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 index 000000000..506bd1162 --- /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 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 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 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); + }; + } +} -- cgit 1.2.3-korg