From 0f6f416f45d5ad0e9bba67d459858995196f7a73 Mon Sep 17 00:00:00 2001 From: leventecsanyi Date: Thu, 11 Jan 2024 12:53:26 +0100 Subject: Introduce Hazelcast for alternateId-cmHandle relation - added new Hazelcast config - added cache initialization in CmHandleIdMapper - added unit tests - updated deployment.rst - refactored cache updating Issue-ID: CPS-1988 Change-Id: Iea6f884e584bf8cea8612ddbced4329e783c60a5 Signed-off-by: leventecsanyi --- .../api/NetworkCmProxyCmHandleQueryService.java | 9 ++- .../NetworkCmProxyCmHandleQueryServiceImpl.java | 13 ++-- .../api/impl/NetworkCmProxyDataServiceImpl.java | 21 ++++- .../NetworkCmProxyDataServicePropertyHandler.java | 17 ++--- .../embeddedcache/AlternateIdCacheConfig.java | 59 ++++++++++++++ .../cps/ncmp/api/impl/utils/CmHandleIdMapper.java | 89 ++++++++++++++++++++++ 6 files changed, 190 insertions(+), 18 deletions(-) create mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/AlternateIdCacheConfig.java create mode 100644 cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java (limited to 'cps-ncmp-service/src/main/java/org') diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java index f29fd687b..06522f80c 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyCmHandleQueryService.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation + * Copyright (C) 2022-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,4 +61,11 @@ public interface NetworkCmProxyCmHandleQueryService { * @return collection of cm handles */ Collection queryCmHandles(CmHandleQueryServiceParameters cmHandleQueryServiceParameters); + + /** + * Query and return all cm handle objects. + * + * @return collection of cm handles + */ + Collection getAllCmHandles(); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java index 1f6c94869..6f92a9efe 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation + * Copyright (C) 2022-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,6 +97,12 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH return getNcmpServiceCmHandles(cmHandleIds); } + @Override + public Collection getAllCmHandles() { + final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next(); + return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet()); + } + private Collection queryCmHandlesByDmiPlugin( final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) { final Map dmiPropertyQueryPairs = @@ -216,11 +222,6 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH return Collections.emptyList(); } - private Collection getAllCmHandles() { - final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next(); - return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet()); - } - private Collection getAllCmHandleIds() { final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY) .iterator().next(); 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 469d75ab9..3fa050454 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 highstreet technologies GmbH - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada * Modifications Copyright (C) 2023 TechMahindra Ltd. @@ -48,6 +48,7 @@ import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.onap.cps.api.CpsDataService; import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService; @@ -65,6 +66,7 @@ import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations; import org.onap.cps.ncmp.api.impl.operations.OperationType; import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel; import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager; +import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper; import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions; import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions; import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; @@ -104,10 +106,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private final IMap moduleSyncStartedOnCmHandles; private final Map trustLevelPerDmiPlugin; private final TrustLevelManager trustLevelManager; + private final CmHandleIdMapper cmHandleIdMapper; @Override public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule( final DmiPluginRegistration dmiPluginRegistration) { + cacheAlternateIds(dmiPluginRegistration.getCreatedCmHandles()); dmiPluginRegistration.validateDmiPluginRegistration(); final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse(); @@ -367,10 +371,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId())); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED); + removeEntriesFromAlternateIdCache(yangModelCmHandles); return cmHandleRegistrationResponses; } + private void removeEntriesFromAlternateIdCache(final Collection yangModelCmHandles) { + for (final YangModelCmHandle yangModelCmHandle : yangModelCmHandles) { + cmHandleIdMapper.removeMapping(yangModelCmHandle.getId()); + } + } + protected List parseAndProcessUpgradedCmHandlesInRegistration( final DmiPluginRegistration dmiPluginRegistration) { @@ -527,4 +538,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } } + private void cacheAlternateIds(final Collection ncmpServiceCmHandles) { + for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) { + if (!StringUtils.isEmpty(ncmpServiceCmHandle.getAlternateId())) { + cmHandleIdMapper.addMapping(ncmpServiceCmHandle.getCmHandleId(), ncmpServiceCmHandle.getAlternateId()); + } + } + } + } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java index 15209328f..13b3fcafb 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java @@ -43,9 +43,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.onap.cps.api.CpsDataService; import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.impl.utils.CmHandleIdMapper; import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse; @@ -67,6 +67,7 @@ public class NetworkCmProxyDataServicePropertyHandler { private final InventoryPersistence inventoryPersistence; private final CpsDataService cpsDataService; private final JsonObjectMapper jsonObjectMapper; + private final CmHandleIdMapper cmHandleIdMapper; /** * Iterates over incoming ncmpServiceCmHandles and update the dataNodes based on the updated attributes. @@ -105,19 +106,15 @@ public class NetworkCmProxyDataServicePropertyHandler { private void updateAlternateId(final DataNode existingCmHandleDataNode, final NcmpServiceCmHandle ncmpServiceCmHandle) { final String newAlternateId = ncmpServiceCmHandle.getAlternateId(); - if (!StringUtils.isEmpty(newAlternateId)) { - final String existingAlternateId = (String) existingCmHandleDataNode.getLeaves().get("alternate-id"); - if (StringUtils.isEmpty(existingAlternateId)) { + if (cmHandleIdMapper.addMapping(ncmpServiceCmHandle.getCmHandleId(), newAlternateId)) { + try { final YangModelCmHandle yangModelCmHandle = YangDataConverter.convertCmHandleToYangModel(existingCmHandleDataNode, ncmpServiceCmHandle.getCmHandleId()); setAndUpdateAlternateId(yangModelCmHandle, newAlternateId); - } else { - if (!newAlternateId.equals(existingAlternateId)) { - log.warn("Unable to update alternateId for cmHandle {}. " - + "Value for alternateId has been set previously.", - ncmpServiceCmHandle.getCmHandleId()); - } + } catch (final Exception e) { + cmHandleIdMapper.removeMapping(ncmpServiceCmHandle.getCmHandleId()); + throw e; } } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/AlternateIdCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/AlternateIdCacheConfig.java new file mode 100644 index 000000000..a69d14476 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/AlternateIdCacheConfig.java @@ -0,0 +1,59 @@ +/* + * ============LICENSE_START======================================================== + * Copyright (C) 2024 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.config.embeddedcache; + +import com.hazelcast.config.MapConfig; +import java.util.Map; +import org.onap.cps.cache.HazelcastCacheConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AlternateIdCacheConfig extends HazelcastCacheConfig { + + private static final MapConfig alternateIdPerCmHandleIdMapConfig = + createMapConfig("alternateIdPerCmHandleIdMapConfig"); + + private static final MapConfig cmHandleIdPerAlternateIdMapConfig = + createMapConfig("cmHandleIdPerAlternateIdMapConfig"); + + /** + * Distributed instance of alternate id cache containing the alternate id per cm handle id. + * + * @return the cached map. + */ + @Bean + public Map alternateIdPerCmHandleId() { + return createHazelcastInstance("hazelcastInstanceAlternateIdPerCmHandleIdMap", + alternateIdPerCmHandleIdMapConfig).getMap("alternateIdPerCmHandleId"); + } + + /** + * Distributed instance of alternate id cache containing the cm handle id per alternate id. + * + * @return the cached map. + */ + @Bean + public Map cmHandleIdPerAlternateId() { + return createHazelcastInstance("hazelcastInstanceCmHandleIdPerAlternateIdMap", + cmHandleIdPerAlternateIdMapConfig).getMap("cmHandleIdPerAlternateId"); + } +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java new file mode 100644 index 000000000..8175fb5e7 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/CmHandleIdMapper.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================== + * Copyright (c) 2024 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.utils; + +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +@RequiredArgsConstructor +public class CmHandleIdMapper { + + private final Map alternateIdPerCmHandleId; + private final Map cmHandleIdPerAlternateId; + private final NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService; + + private boolean cacheIsInitialized = false; + + public String cmHandleIdToAlternateId(final String cmHandleId) { + initializeCache(); + return alternateIdPerCmHandleId.get(cmHandleId); + } + + public String alternateIdToCmHandleId(final String alternateId) { + initializeCache(); + return cmHandleIdPerAlternateId.get(alternateId); + } + + public boolean addMapping(final String cmHandleId, final String alternateId) { + initializeCache(); + return addMappingWithValidation(cmHandleId, alternateId); + } + + + private boolean addMappingWithValidation(final String cmHandleId, final String alternateId) { + if (alternateIdPerCmHandleId.containsKey(cmHandleId)) { + final String originalAlternateId = alternateIdPerCmHandleId.get(cmHandleId); + if (!originalAlternateId.equals(alternateId)) { + log.warn("Alternate id update ignored, cannot update cm handle {}, already has an alternate id of {}", + cmHandleId, originalAlternateId); + } + return false; + } + if (StringUtils.isBlank(alternateId)) { + return false; + } + alternateIdPerCmHandleId.put(cmHandleId, alternateId); + cmHandleIdPerAlternateId.put(alternateId, cmHandleId); + return true; + } + + public void removeMapping(final String cmHandleId) { + final String alternateId = alternateIdPerCmHandleId.remove(cmHandleId); + cmHandleIdPerAlternateId.remove(alternateId); + } + + private void initializeCache() { + if (!cacheIsInitialized) { + networkCmProxyCmHandleQueryService.getAllCmHandles().forEach(cmHandle -> + addMappingWithValidation(cmHandle.getCmHandleId(), cmHandle.getAlternateId()) + ); + log.info("Alternate ID cache initialized from DB with {} cm handle/alternate id pairs ", + alternateIdPerCmHandleId.size()); + cacheIsInitialized = true; + } + } +} -- cgit 1.2.3-korg