Merge "Further TTL increase"
[cps.git] / cps-ri / src / main / java / org / onap / cps / spi / impl / CpsDataPersistenceServiceImpl.java
index 3bd2994..06ee8ec 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2022 Nordix Foundation
+ *  Copyright (C) 2021-2023 Nordix Foundation
  *  Modifications Copyright (C) 2021 Pantheon.tech
  *  Modifications Copyright (C) 2020-2022 Bell Canada.
  *  Modifications Copyright (C) 2022 TechMahindra Ltd.
@@ -256,6 +256,27 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
         return toDataNode(fragmentEntity, fetchDescendantsOption);
     }
 
+    @Override
+    public Collection<DataNode> getDataNodes(final String dataspaceName, final String anchorName,
+                                             final Collection<String> xpaths,
+                                             final FetchDescendantsOption fetchDescendantsOption) {
+        final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+        final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
+
+        final Set<String> normalizedXpaths = new HashSet<>(xpaths.size());
+        for (final String xpath : xpaths) {
+            try {
+                normalizedXpaths.add(CpsPathUtil.getNormalizedXpath(xpath));
+            } catch (final PathParsingException e) {
+                log.warn("Error parsing xpath \"{}\" in getDataNodes: {}", xpath, e.getMessage());
+            }
+        }
+
+        final List<FragmentEntity> fragmentEntities =
+                fragmentRepository.findByAnchorAndMultipleCpsPaths(anchorEntity.getId(), normalizedXpaths);
+        return toDataNodes(fragmentEntities, fetchDescendantsOption);
+    }
+
     private FragmentEntity getFragmentWithoutDescendantsByXpath(final String dataspaceName,
                                                                 final String anchorName,
                                                                 final String xpath) {
@@ -317,7 +338,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
         }
         fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity.getId(), cpsPathQuery);
         if (cpsPathQuery.hasAncestorAxis()) {
-            fragmentEntities = getAncestorFragmentEntities(anchorEntity, cpsPathQuery, fragmentEntities);
+            fragmentEntities = getAncestorFragmentEntities(anchorEntity.getId(), cpsPathQuery, fragmentEntities);
         }
         return createDataNodesFromProxiedFragmentEntities(fetchDescendantsOption, anchorEntity, fragmentEntities);
     }
@@ -338,18 +359,17 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
             fragmentRepository.quickFindWithDescendants(anchorEntity.getId(), xpathRegex);
         fragmentEntities = FragmentEntityArranger.toFragmentEntityTrees(anchorEntity, fragmentExtracts);
         if (cpsPathQuery.hasAncestorAxis()) {
-            fragmentEntities = getAncestorFragmentEntities(anchorEntity, cpsPathQuery, fragmentEntities);
+            fragmentEntities = getAncestorFragmentEntities(anchorEntity.getId(), cpsPathQuery, fragmentEntities);
         }
         return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
     }
 
-    private Collection<FragmentEntity> getAncestorFragmentEntities(final AnchorEntity anchorEntity,
+    private Collection<FragmentEntity> getAncestorFragmentEntities(final int anchorId,
                                                                    final CpsPathQuery cpsPathQuery,
-                                                                   Collection<FragmentEntity> fragmentEntities) {
-        final Set<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery);
-        fragmentEntities = ancestorXpaths.isEmpty() ? Collections.emptyList()
-            : fragmentRepository.findAllByAnchorAndXpathIn(anchorEntity, ancestorXpaths);
-        return fragmentEntities;
+                                                                   final Collection<FragmentEntity> fragmentEntities) {
+        final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery);
+        return ancestorXpaths.isEmpty() ? Collections.emptyList()
+            : fragmentRepository.findByAnchorAndMultipleCpsPaths(anchorId, ancestorXpaths);
     }
 
     private List<DataNode> createDataNodesFromProxiedFragmentEntities(
@@ -435,6 +455,15 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
                 .withChildDataNodes(childDataNodes).build();
     }
 
+    private Collection<DataNode> toDataNodes(final Collection<FragmentEntity> fragmentEntities,
+                                             final FetchDescendantsOption fetchDescendantsOption) {
+        final Collection<DataNode> dataNodes = new ArrayList<>(fragmentEntities.size());
+        for (final FragmentEntity fragmentEntity : fragmentEntities) {
+            dataNodes.add(toDataNode(fragmentEntity, fetchDescendantsOption));
+        }
+        return dataNodes;
+    }
+
     private List<DataNode> getChildDataNodes(final FragmentEntity fragmentEntity,
                                              final FetchDescendantsOption fetchDescendantsOption) {
         if (fetchDescendantsOption.hasNext()) {
@@ -447,9 +476,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
 
     @Override
     public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath,
-                                 final Map<String, Serializable> leaves) {
+                                 final Map<String, Serializable> updateLeaves) {
         final FragmentEntity fragmentEntity = getFragmentWithoutDescendantsByXpath(dataspaceName, anchorName, xpath);
-        fragmentEntity.setAttributes(jsonObjectMapper.asJsonString(leaves));
+        final String currentLeavesAsString = fragmentEntity.getAttributes();
+        final String mergedLeaves = mergeLeaves(updateLeaves, currentLeavesAsString);
+        fragmentEntity.setAttributes(mergedLeaves);
         fragmentRepository.save(fragmentEntity);
     }
 
@@ -694,4 +725,14 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
     private static boolean isRootXpath(final String xpath) {
         return "/".equals(xpath) || "".equals(xpath);
     }
+
+    private String mergeLeaves(final Map<String, Serializable> updateLeaves, final String currentLeavesAsString) {
+        final Map<String, Serializable> currentLeavesAsMap = currentLeavesAsString.isEmpty()
+            ? new HashMap<>() : jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class);
+        currentLeavesAsMap.putAll(updateLeaves);
+        if (currentLeavesAsMap.isEmpty()) {
+            return "";
+        }
+        return jsonObjectMapper.asJsonString(currentLeavesAsMap);
+    }
 }