aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ri
diff options
context:
space:
mode:
authorDylanB95EST <dylan.byrne@est.tech>2022-02-11 12:46:27 +0000
committerDylan Byrne <dylan.byrne@est.tech>2022-02-15 14:49:57 +0000
commitc76392f0491e357b444b3458cc26649f7dc1e7fb (patch)
treed4253a441edfe3e1e46a417c36a29e26566d0666 /cps-ri
parentf7cb11a5d53d4964c236a6ecb2e2f4264f2437fd (diff)
Fragment handling decreasing performance for large number of cmHandles
- allow fragmentEntity to set parent id (needed for optimization) - updated addListAlement and addChildDataNode to use new common optimized metghod to add to exsiting children - ensure methods are transactional - Refactored test around adding list elements to clearly define test checking the presence of grandchild element Issue-ID: CPS-886 Change-Id: Ic4381f0f7170ebd666d5bc8aa6ef2c4548d81766 Signed-off-by: DylanB95EST <dylan.byrne@est.tech>
Diffstat (limited to 'cps-ri')
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java3
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java56
-rwxr-xr-xcps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy20
3 files changed, 34 insertions, 45 deletions
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java
index 00d1d98df..2fdfa0528 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/entities/FragmentEntity.java
@@ -70,6 +70,9 @@ public class FragmentEntity implements Serializable {
@Column(columnDefinition = "text")
private String xpath;
+ @Column(name = "parent_id")
+ private Long parentId;
+
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private String attributes;
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
index ed414fc30..04804726c 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
@@ -73,41 +73,38 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
private final JsonObjectMapper jsonObjectMapper;
-
private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@[\\s\\S]+?]){0,1})";
private static final Pattern REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE =
Pattern.compile("\\[(\\@([^\\/]{0,9999}))\\]$");
@Override
- public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentXpath,
- final DataNode dataNode) {
- final FragmentEntity parentFragment = getFragmentByXpath(dataspaceName, anchorName, parentXpath);
- final FragmentEntity fragmentEntity =
- toFragmentEntity(parentFragment.getDataspace(), parentFragment.getAnchor(), dataNode);
- parentFragment.getChildFragments().add(fragmentEntity);
- try {
- fragmentRepository.save(parentFragment);
- } catch (final DataIntegrityViolationException exception) {
- throw AlreadyDefinedException.forDataNode(dataNode.getXpath(), anchorName, exception);
- }
+ @Transactional
+ public void addChildDataNode(final String dataspaceName, final String anchorName, final String parentNodeXpath,
+ final DataNode newChildDataNode) {
+ addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, Collections.singleton(newChildDataNode));
}
@Override
+ @Transactional
public void addListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath,
- final Collection<DataNode> dataNodes) {
- final FragmentEntity parentFragment = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
- final List<FragmentEntity> newFragmentEntities =
- dataNodes.stream().map(
- dataNode -> toFragmentEntity(parentFragment.getDataspace(), parentFragment.getAnchor(), dataNode)
- ).collect(Collectors.toUnmodifiableList());
- parentFragment.getChildFragments().addAll(newFragmentEntities);
+ final Collection<DataNode> newListElements) {
+ addChildDataNodes(dataspaceName, anchorName, parentNodeXpath, newListElements);
+ }
+
+ private void addChildDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath,
+ final Collection<DataNode> newChildren) {
+ final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
try {
- fragmentRepository.save(parentFragment);
- dataNodes.forEach(
- dataNode -> getChildFragments(dataspaceName, anchorName, dataNode)
- );
+ for (final DataNode newChildAsDataNode : newChildren) {
+ final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants(
+ parentFragmentEntity.getDataspace(),
+ parentFragmentEntity.getAnchor(),
+ newChildAsDataNode);
+ newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
+ fragmentRepository.save(newChildAsFragmentEntity);
+ }
} catch (final DataIntegrityViolationException exception) {
- final List<String> conflictXpaths = dataNodes.stream()
+ final List<String> conflictXpaths = newChildren.stream()
.map(DataNode::getXpath)
.collect(Collectors.toList());
throw AlreadyDefinedException.forDataNodes(conflictXpaths, anchorName, exception);
@@ -150,17 +147,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return parentFragment;
}
- private void getChildFragments(final String dataspaceName, final String anchorName, final DataNode dataNode) {
- for (final DataNode childDataNode: dataNode.getChildDataNodes()) {
- final FragmentEntity getChildsParentFragmentByXPath =
- getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath());
- final FragmentEntity childFragmentEntity = toFragmentEntity(getChildsParentFragmentByXPath.getDataspace(),
- getChildsParentFragmentByXPath.getAnchor(), childDataNode);
- getChildsParentFragmentByXPath.getChildFragments().add(childFragmentEntity);
- fragmentRepository.save(getChildsParentFragmentByXPath);
- }
- }
-
private FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity,
final AnchorEntity anchorEntity, final DataNode dataNode) {
return FragmentEntity.builder()
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
index 41e7a419a..2277377a5 100755
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
@@ -155,25 +155,25 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
}
@Sql([CLEAR_DATA, SET_DATA])
- def 'Add multiple list elements including an element with a child datanode.'() {
- given: 'two new data nodes for an existing list'
+ def 'Add multiple new list elements including an element with a child datanode.'() {
+ given: 'two new child list elements for an existing parent'
def listElementXpaths = ['/parent-201/child-204[@key="NEW1"]', '/parent-201/child-204[@key="NEW2"]']
def listElements = toDataNodes(listElementXpaths)
- and: 'a child node for one of the new data nodes'
- def childDataNode = buildDataNode('/parent-201/child-204[@key="NEW1"]/grand-child-204[@key2="NEW1-CHILD"]', [leave:'value'], [])
- listElements[0].childDataNodes = [childDataNode]
- when: 'the data nodes (list elements) are added to existing parent node'
+ and: 'a (grand)child data node for one of the new list elements'
+ def grandChild = buildDataNode('/parent-201/child-204[@key="NEW1"]/grand-child-204[@key2="NEW1-CHILD"]', [leave:'value'], [])
+ listElements[0].childDataNodes = [grandChild]
+ when: 'the new data node (list elements) are added to an existing parent node'
objectUnderTest.addListElements(DATASPACE_NAME, ANCHOR_NAME3, '/parent-201', listElements)
- then: 'new entries successfully persisted, parent node now contains 5 children (2 new + 3 existing before)'
+ then: 'new entries are successfully persisted, parent node now contains 5 children (2 new + 3 existing before)'
def parentFragment = fragmentRepository.getById(LIST_DATA_NODE_PARENT201_FRAGMENT_ID)
def allChildXpaths = parentFragment.childFragments.collect { it.xpath }
assert allChildXpaths.size() == 5
assert allChildXpaths.containsAll(listElementXpaths)
- and: 'the child node of the new list entry is also present'
+ and: 'the (grand)child node of the new list entry is also present'
def dataspaceEntity = dataspaceRepository.getByName(DATASPACE_NAME)
def anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, ANCHOR_NAME3)
- def listElementChild = fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, childDataNode.xpath)
- assert listElementChild.isPresent()
+ def grandChildFragmentEntity = fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, grandChild.xpath)
+ assert grandChildFragmentEntity.isPresent()
}
@Sql([CLEAR_DATA, SET_DATA])