diff options
Diffstat (limited to 'cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java')
-rw-r--r-- | cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java | 139 |
1 files changed, 124 insertions, 15 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java index 9a063d6df..d2b1237a4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java @@ -22,11 +22,18 @@ package org.onap.cps.ncmp.api.impl.subscriptions; import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP; +import java.io.Serializable; +import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsDataService; +import org.onap.cps.ncmp.api.impl.utils.DataNodeHelper; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; @@ -41,35 +48,86 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { private static final String SUBSCRIPTION_DATASPACE_NAME = "NCMP-Admin"; private static final String SUBSCRIPTION_ANCHOR_NAME = "AVC-Subscriptions"; private static final String SUBSCRIPTION_REGISTRY_PARENT = "/subscription-registry"; - private final JsonObjectMapper jsonObjectMapper; private final CpsDataService cpsDataService; @Override public void saveSubscriptionEvent(final YangModelSubscriptionEvent yangModelSubscriptionEvent) { - final String subscriptionEventJsonData = - createSubscriptionEventJsonData(jsonObjectMapper.asJsonString(yangModelSubscriptionEvent)); + final String clientId = yangModelSubscriptionEvent.getClientId(); + final String subscriptionName = yangModelSubscriptionEvent.getSubscriptionName(); + final Collection<DataNode> dataNodes = cpsDataService.getDataNodes(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, SUBSCRIPTION_REGISTRY_PARENT, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + + if (isSubscriptionRegistryEmptyOrNonExist(dataNodes, clientId, subscriptionName)) { + saveSubscriptionEventYangModel(createSubscriptionEventJsonData( + jsonObjectMapper.asJsonString(yangModelSubscriptionEvent))); + } else { + findDeltaCmHandlesAddOrUpdateInDatabase(yangModelSubscriptionEvent, clientId, subscriptionName, dataNodes); + } + } + + private void findDeltaCmHandlesAddOrUpdateInDatabase(final YangModelSubscriptionEvent yangModelSubscriptionEvent, + final String clientId, final String subscriptionName, + final Collection<DataNode> dataNodes) { + final Map<String, SubscriptionStatus> cmHandleIdsFromYangModel = + extractCmHandleFromYangModelAsMap(yangModelSubscriptionEvent); + final Map<String, SubscriptionStatus> cmHandleIdsFromDatabase = + extractCmHandleFromDbAsMap(dataNodes); + + final Map<String, SubscriptionStatus> newCmHandles = + mapDifference(cmHandleIdsFromYangModel, cmHandleIdsFromDatabase); + traverseCmHandleList(newCmHandles, clientId, subscriptionName, true); + + final Map<String, SubscriptionStatus> existingCmHandles = + mapDifference(cmHandleIdsFromYangModel, newCmHandles); + traverseCmHandleList(existingCmHandles, clientId, subscriptionName, false); + } + + private boolean isSubscriptionRegistryEmptyOrNonExist(final Collection<DataNode> dataNodes, + final String clientId, final String subscriptionName) { final Optional<DataNode> dataNodeFirst = dataNodes.stream().findFirst(); - final boolean isCreateOperation = - dataNodeFirst.isPresent() && dataNodeFirst.get().getChildDataNodes().isEmpty(); - saveOrUpdateSubscriptionEventYangModel(subscriptionEventJsonData, isCreateOperation); + return ((dataNodeFirst.isPresent() && dataNodeFirst.get().getChildDataNodes().isEmpty()) + || getCmHandlesForSubscriptionEvent(clientId, subscriptionName).isEmpty()); + } + + private void traverseCmHandleList(final Map<String, SubscriptionStatus> cmHandleMap, + final String clientId, + final String subscriptionName, + final boolean isAddListElementOperation) { + final List<YangModelSubscriptionEvent.TargetCmHandle> cmHandleList = + targetCmHandlesAsList(cmHandleMap); + for (final YangModelSubscriptionEvent.TargetCmHandle targetCmHandle : cmHandleList) { + final String targetCmHandleAsJson = + createTargetCmHandleJsonData(jsonObjectMapper.asJsonString(targetCmHandle)); + addOrReplaceCmHandlePredicateListElement(targetCmHandleAsJson, clientId, subscriptionName, + isAddListElementOperation); + } } - private void saveOrUpdateSubscriptionEventYangModel(final String subscriptionEventJsonData, - final boolean isCreateOperation) { - if (isCreateOperation) { - log.info("SubscriptionEventJsonData to be saved into DB {}", subscriptionEventJsonData); - cpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, - SUBSCRIPTION_REGISTRY_PARENT, subscriptionEventJsonData, NO_TIMESTAMP); + private void addOrReplaceCmHandlePredicateListElement(final String targetCmHandleAsJson, + final String clientId, + final String subscriptionName, + final boolean isAddListElementOperation) { + if (isAddListElementOperation) { + log.info("targetCmHandleAsJson to be added into DB {}", targetCmHandleAsJson); + cpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, + SUBSCRIPTION_ANCHOR_NAME, createCmHandleXpathPredicates(clientId, subscriptionName), + targetCmHandleAsJson, NO_TIMESTAMP); } else { - log.info("SubscriptionEventJsonData to be updated into DB {}", subscriptionEventJsonData); - cpsDataService.updateDataNodeAndDescendants(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, - SUBSCRIPTION_REGISTRY_PARENT, subscriptionEventJsonData, NO_TIMESTAMP); + log.info("targetCmHandleAsJson to be updated into DB {}", targetCmHandleAsJson); + cpsDataService.updateNodeLeaves(SUBSCRIPTION_DATASPACE_NAME, + SUBSCRIPTION_ANCHOR_NAME, createCmHandleXpathPredicates(clientId, subscriptionName), + targetCmHandleAsJson, NO_TIMESTAMP); } } + private void saveSubscriptionEventYangModel(final String subscriptionEventJsonData) { + log.info("SubscriptionEventJsonData to be saved into DB {}", subscriptionEventJsonData); + cpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + SUBSCRIPTION_REGISTRY_PARENT, subscriptionEventJsonData, NO_TIMESTAMP); + } + @Override public Collection<DataNode> getDataNodesForSubscriptionEvent() { return cpsDataService.getDataNodes(SUBSCRIPTION_DATASPACE_NAME, @@ -77,7 +135,58 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); } + @Override + public Collection<DataNode> getCmHandlesForSubscriptionEvent(final String clientId, final String subscriptionName) { + return cpsDataService.getDataNodesForMultipleXpaths(SUBSCRIPTION_DATASPACE_NAME, + SUBSCRIPTION_ANCHOR_NAME, Arrays.asList(createCmHandleXpath(clientId, subscriptionName)), + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + } + + private static Map<String, SubscriptionStatus> extractCmHandleFromDbAsMap(final Collection<DataNode> dataNodes) { + final List<Map<String, Serializable>> dataNodeLeaves = DataNodeHelper.getDataNodeLeaves(dataNodes); + final List<Collection<Serializable>> cmHandleIdToStatus = DataNodeHelper.getCmHandleIdToStatus(dataNodeLeaves); + return DataNodeHelper.getCmHandleIdToStatusMap(cmHandleIdToStatus); + } + + private static Map<String, SubscriptionStatus> extractCmHandleFromYangModelAsMap( + final YangModelSubscriptionEvent yangModelSubscriptionEvent) { + return yangModelSubscriptionEvent.getPredicates().getTargetCmHandles() + .stream().collect(Collectors.toMap( + YangModelSubscriptionEvent.TargetCmHandle::getCmHandleId, + YangModelSubscriptionEvent.TargetCmHandle::getStatus)); + } + + private static List<YangModelSubscriptionEvent.TargetCmHandle> targetCmHandlesAsList( + final Map<String, SubscriptionStatus> newCmHandles) { + return newCmHandles.entrySet().stream().map(entry -> + new YangModelSubscriptionEvent.TargetCmHandle(entry.getKey(), + entry.getValue())).collect(Collectors.toList()); + } + private static String createSubscriptionEventJsonData(final String yangModelSubscriptionAsJson) { return "{\"subscription\":[" + yangModelSubscriptionAsJson + "]}"; } + + private static String createTargetCmHandleJsonData(final String targetCmHandleAsJson) { + return "{\"targetCmHandles\":[" + targetCmHandleAsJson + "]}"; + } + + private static String createCmHandleXpathPredicates(final String clientId, final String subscriptionName) { + return "/subscription-registry/subscription[@clientID='" + clientId + + "' and @subscriptionName='" + subscriptionName + "']/predicates"; + } + + private static String createCmHandleXpath(final String clientId, final String subscriptionName) { + return "/subscription-registry/subscription[@clientID='" + clientId + + "' and @subscriptionName='" + subscriptionName + "']"; + } + + private static <K, V> Map<K, V> mapDifference(final Map<? extends K, ? extends V> left, + final Map<? extends K, ? extends V> right) { + final Map<K, V> difference = new HashMap<>(); + difference.putAll(left); + difference.putAll(right); + difference.entrySet().removeAll(right.entrySet()); + return difference; + } } |