X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ri%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fonap%2Fcps%2Fspi%2Fimpl%2FCpsDataPersistenceServiceIntegrationSpec.groovy;h=67ccc805ae0bd77f2cf09eea03bffc0d29f4adc6;hb=ec061d5caba23c76f0cdc183c1f5a37e0c11b6c7;hp=28916b1c4a9b7f1a005c783d89f7d7c3127a863c;hpb=2e29e4f1942df9e13c38ce8f4e29c5753096c946;p=cps.git 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 28916b1c4..67ccc805a 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 @@ -23,9 +23,7 @@ package org.onap.cps.spi.impl -import com.fasterxml.jackson.databind.ObjectMapper import com.google.common.collect.ImmutableSet -import org.onap.cps.cpspath.parser.PathParsingException import org.onap.cps.spi.CpsDataPersistenceService import org.onap.cps.spi.entities.FragmentEntity import org.onap.cps.spi.exceptions.AlreadyDefinedExceptionBatch @@ -36,7 +34,6 @@ import org.onap.cps.spi.exceptions.DataNodeNotFoundException import org.onap.cps.spi.exceptions.DataspaceNotFoundException import org.onap.cps.spi.model.DataNode import org.onap.cps.spi.model.DataNodeBuilder -import org.onap.cps.utils.JsonObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.jdbc.Sql @@ -50,7 +47,6 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { @Autowired CpsDataPersistenceService objectUnderTest - static JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) static DataNodeBuilder dataNodeBuilder = new DataNodeBuilder() static final String SET_DATA = '/data/fragment.sql' @@ -71,13 +67,6 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { def static deleteTestChildXpath = "${deleteTestParentXPath}/child-with-slash[@key='a/b']" def static deleteTestGrandChildXPath = "${deleteTestChildXpath}/grandChild" - def expectedLeavesByXpathMap = [ - '/parent-207' : ['parent-leaf': 'parent-leaf value'], - '/parent-207/child-001' : ['first-child-leaf': 'first-child-leaf value'], - '/parent-207/child-002' : ['second-child-leaf': 'second-child-leaf value'], - '/parent-207/child-002/grand-child': ['grand-child-leaf': 'grand-child-leaf value'] - ] - @Sql([CLEAR_DATA, SET_DATA]) def 'Get all datanodes with descendants .'() { when: 'data nodes are retrieved by their xpath' @@ -181,14 +170,14 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { when: 'the new data node (list elements) are added to an existing parent node' objectUnderTest.addMultipleLists(DATASPACE_NAME, ANCHOR_NAME3, '/parent-201', [listElements]) 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 parentFragment = fragmentRepository.getReferenceById(LIST_DATA_NODE_PARENT201_FRAGMENT_ID) def allChildXpaths = parentFragment.childFragments.collect { it.xpath } assert allChildXpaths.size() == 5 assert allChildXpaths.containsAll(listElementXpaths) 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 grandChildFragmentEntity = fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, grandChild.xpath) + def grandChildFragmentEntity = fragmentRepository.findByAnchorAndXpath(anchorEntity, grandChild.xpath) assert grandChildFragmentEntity.isPresent() } @@ -213,7 +202,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { and: 'the new entity is inserted correctly' def dataspaceEntity = dataspaceRepository.getByName(DATASPACE_NAME) def anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, ANCHOR_HAVING_SINGLE_TOP_LEVEL_FRAGMENT) - fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, '/parent-200/child-new2').isPresent() + fragmentRepository.findByAnchorAndXpath(anchorEntity, '/parent-200/child-new2').isPresent() } @Sql([CLEAR_DATA, SET_DATA]) @@ -253,8 +242,8 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { when: 'trying to execute a query with a syntax (parsing) error' objectUnderTest.getDataNodes(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, 'invalid-cps-path/child' , OMIT_DESCENDANTS) then: 'exception is thrown' - def exceptionThrown = thrown(PathParsingException) - assert exceptionThrown.getMessage().contains('failed to parse at line 1 due to extraneous input \'invalid-cps-path\' expecting \'/\'') + def exceptionThrown = thrown(CpsPathException) + assert exceptionThrown.getDetails() == "failed to parse at line 1 due to extraneous input 'invalid-cps-path' expecting '/'" } @Sql([CLEAR_DATA, SET_DATA]) @@ -288,7 +277,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { where: 'the following data is used' scenario | dataspaceName | anchorName | xpath || expectedException 'non existing xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | '/NO-XPATH' || DataNodeNotFoundException - 'invalid Xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | 'INVALID XPATH' || PathParsingException + 'invalid Xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | 'INVALID XPATH' || CpsPathException } @Sql([CLEAR_DATA, SET_DATA]) @@ -315,7 +304,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { 'root xpath' | ["/"] || 7 'empty (root) xpath' | [""] || 7 'root and top-level xpaths' | ["/", "/parent-200", "/parent-201"] || 7 - 'root and child xpaths' | ["/", "/parent-200/child-201"] || 8 + 'root and child xpaths' | ["/", "/parent-200/child-201"] || 7 } @Sql([CLEAR_DATA, SET_DATA]) @@ -336,7 +325,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { objectUnderTest.updateDataLeaves(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, '/parent-200/child-201', ['leaf-value': 'new']) then: 'leaves are updated for selected data node' - def updatedFragment = fragmentRepository.getById(DATA_NODE_202_FRAGMENT_ID) + def updatedFragment = fragmentRepository.getReferenceById(DATA_NODE_202_FRAGMENT_ID) def updatedLeaves = getLeavesMap(updatedFragment) assert updatedLeaves.size() == 1 assert updatedLeaves.'leaf-value' == 'new' @@ -361,13 +350,13 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Update data node and descendants by removing descendants.'() { - given: 'data node object with leaves updated, no children' - def submittedDataNode = buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], []) + def 'Update data nodes and descendants by removing descendants.'() { + given: 'data nodes with leaves updated, no children' + def submittedDataNodes = [buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [])] when: 'update data nodes and descendants is performed' - objectUnderTest.updateDataNodeAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode) + objectUnderTest.updateDataNodesAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNodes) then: 'leaves have been updated for selected data node' - def updatedFragment = fragmentRepository.getById(DATA_NODE_202_FRAGMENT_ID) + def updatedFragment = fragmentRepository.getReferenceById(DATA_NODE_202_FRAGMENT_ID) def updatedLeaves = getLeavesMap(updatedFragment) assert updatedLeaves.size() == 1 assert updatedLeaves.'leaf-value' == 'new' @@ -378,15 +367,15 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Update data node and descendants with new descendants'() { - given: 'data node object with leaves updated, having child with old content' - def submittedDataNode = buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ + def 'Update data nodes and descendants with new descendants'() { + given: 'data nodes with leaves updated, having child with old content' + def submittedDataNodes = [buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ buildDataNode('/parent-200/child-201/grand-child', ['leaf-value': 'original'], []) - ]) + ])] when: 'update is performed including descendants' - objectUnderTest.updateDataNodeAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode) + objectUnderTest.updateDataNodesAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNodes) then: 'leaves have been updated for selected data node' - def updatedFragment = fragmentRepository.getById(DATA_NODE_202_FRAGMENT_ID) + def updatedFragment = fragmentRepository.getReferenceById(DATA_NODE_202_FRAGMENT_ID) def updatedLeaves = getLeavesMap(updatedFragment) assert updatedLeaves.size() == 1 assert updatedLeaves.'leaf-value' == 'new' @@ -398,15 +387,15 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Update data node and descendants with same descendants but changed leaf value.'() { - given: 'data node object with leaves updated, having child with old content' - def submittedDataNode = buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ + def 'Update data nodes and descendants with same descendants but changed leaf value.'() { + given: 'data nodes with leaves updated, having child with old content' + def submittedDataNodes = [buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ buildDataNode('/parent-200/child-201/grand-child', ['leaf-value': 'new'], []) - ]) + ])] when: 'update is performed including descendants' - objectUnderTest.updateDataNodeAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode) + objectUnderTest.updateDataNodesAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNodes) then: 'leaves have been updated for selected data node' - def updatedFragment = fragmentRepository.getById(DATA_NODE_202_FRAGMENT_ID) + def updatedFragment = fragmentRepository.getReferenceById(DATA_NODE_202_FRAGMENT_ID) def updatedLeaves = getLeavesMap(updatedFragment) assert updatedLeaves.size() == 1 assert updatedLeaves.'leaf-value' == 'new' @@ -418,15 +407,15 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Update data node and descendants with different descendants xpath'() { - given: 'data node object with leaves updated, having child with old content' - def submittedDataNode = buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ + def 'Update data nodes and descendants with different descendants xpath'() { + given: 'data nodes with leaves updated, having child with old content' + def submittedDataNodes = [buildDataNode('/parent-200/child-201', ['leaf-value': 'new'], [ buildDataNode('/parent-200/child-201/grand-child-new', ['leaf-value': 'new'], []) - ]) + ])] when: 'update is performed including descendants' - objectUnderTest.updateDataNodeAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNode) + objectUnderTest.updateDataNodesAndDescendants(DATASPACE_NAME, ANCHOR_FOR_DATA_NODES_WITH_LEAVES, submittedDataNodes) then: 'leaves have been updated for selected data node' - def updatedFragment = fragmentRepository.getById(DATA_NODE_202_FRAGMENT_ID) + def updatedFragment = fragmentRepository.getReferenceById(DATA_NODE_202_FRAGMENT_ID) def updatedLeaves = getLeavesMap(updatedFragment) assert updatedLeaves.size() == 1 assert updatedLeaves.'leaf-value' == 'new' @@ -440,19 +429,17 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { } @Sql([CLEAR_DATA, SET_DATA]) - def 'Update data node and descendants error scenario: #scenario.'() { - given: 'data node object' - def submittedDataNode = buildDataNode(xpath, ['leaf-name': 'leaf-value'], []) + def 'Update data nodes and descendants error scenario: #scenario.'() { + given: 'data nodes collection' + def submittedDataNodes = [buildDataNode(xpath, ['leaf-name': 'leaf-value'], [])] when: 'attempt to update data node for #scenario' - objectUnderTest.updateDataNodeAndDescendants(dataspaceName, anchorName, submittedDataNode) + objectUnderTest.updateDataNodesAndDescendants(dataspaceName, anchorName, submittedDataNodes) then: 'a #expectedException is thrown' thrown(expectedException) where: 'the following data is used' scenario | dataspaceName | anchorName | xpath || expectedException 'non-existing dataspace' | 'NO DATASPACE' | 'not relevant' | '/not relevant' || DataspaceNotFoundException 'non-existing anchor' | DATASPACE_NAME | 'NO ANCHOR' | '/not relevant' || AnchorNotFoundException - 'non-existing xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | '/NON-EXISTING-XPATH' || DataNodeNotFoundException - 'invalid xpath' | DATASPACE_NAME | ANCHOR_FOR_DATA_NODES_WITH_LEAVES | 'INVALID XPATH' || CpsPathException } @Sql([CLEAR_DATA, SET_DATA]) @@ -464,13 +451,13 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { objectUnderTest.addListElements(DATASPACE_NAME, ANCHOR_NAME1, parentXpath, originalListEntriesAsDataNodes) } and: 'each original list element has one child' - def originalParentFragment = fragmentRepository.getById(PARENT_3_FRAGMENT_ID) + def originalParentFragment = fragmentRepository.getReferenceById(PARENT_3_FRAGMENT_ID) originalParentFragment.childFragments.each {assert it.childFragments.size() == 1 } when: 'it is updated with #scenario' def replacementListEntriesAsDataNodes = createChildListAllHavingAttributeValue(parentXpath, 'new value', replacementKeys, false) objectUnderTest.replaceListContent(DATASPACE_NAME, ANCHOR_NAME1, parentXpath, replacementListEntriesAsDataNodes) then: 'the result list ONLY contains the expected replacement elements' - def parentFragment = fragmentRepository.getById(PARENT_3_FRAGMENT_ID) + def parentFragment = fragmentRepository.getReferenceById(PARENT_3_FRAGMENT_ID) def allChildXpaths = parentFragment.childFragments.collect { it.xpath } def expectedListEntriesAfterUpdateAsXpaths = keysToXpaths(parentXpath, replacementKeys) assert allChildXpaths.size() == replacementKeys.size() @@ -498,7 +485,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { def replacementListEntriesAsDataNodes = createChildListAllHavingAttributeValue(parentXpath, 'new', ['A'], true) objectUnderTest.replaceListContent(DATASPACE_NAME, ANCHOR_NAME1, parentXpath, replacementListEntriesAsDataNodes) then: 'The updated fragment has a child-list with ONLY element "A"' - def parentFragment = fragmentRepository.getById(PARENT_3_FRAGMENT_ID) + def parentFragment = fragmentRepository.getReferenceById(PARENT_3_FRAGMENT_ID) parentFragment.childFragments.size() == 1 def childListElementA = parentFragment.childFragments[0] childListElementA.xpath == "/parent-3/child-list[@key='A']" @@ -519,7 +506,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { def replacementListEntriesAsDataNodes = createChildListAllHavingAttributeValue(XPATH_DATA_NODE_WITH_DESCENDANTS, 'new', ['A','B'], false) objectUnderTest.replaceListContent(DATASPACE_NAME, ANCHOR_NAME1, XPATH_DATA_NODE_WITH_DESCENDANTS, replacementListEntriesAsDataNodes) then: 'the parent will have 3 children after the replacement' - def parentFragment = fragmentRepository.getById(ID_DATA_NODE_WITH_DESCENDANTS) + def parentFragment = fragmentRepository.getReferenceById(ID_DATA_NODE_WITH_DESCENDANTS) parentFragment.childFragments.size() == 3 def xpaths = parentFragment.childFragments.collect {it.xpath} and: 'one of the children is the original child fragment' @@ -552,7 +539,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { when: 'deleting list is executed for: #scenario.' objectUnderTest.deleteListDataNode(DATASPACE_NAME, ANCHOR_NAME3, targetXpaths) and: 'remaining children are fetched' - def parentFragment = fragmentRepository.getById(parentFragmentId) + def parentFragment = fragmentRepository.getReferenceById(parentFragmentId) def remainingChildXpaths = parentFragment.childFragments.collect { it.xpath } then: 'only the expected children remain' assert remainingChildXpaths.size() == expectedRemainingChildXpaths.size() @@ -570,7 +557,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { when: 'deleting nodes is executed for: #scenario.' objectUnderTest.deleteDataNodes(DATASPACE_NAME, ANCHOR_NAME3, targetXpaths) and: 'remaining children are fetched' - def parentFragment = fragmentRepository.getById(LIST_DATA_NODE_PARENT203_FRAGMENT_ID) + def parentFragment = fragmentRepository.getReferenceById(LIST_DATA_NODE_PARENT203_FRAGMENT_ID) def remainingChildXpaths = parentFragment.childFragments.collect { it.xpath } then: 'only the expected children remain' assert remainingChildXpaths.size() == expectedRemainingChildXpaths.size() @@ -667,35 +654,35 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { then: 'a #expectedException is thrown' thrown(expectedException) where: 'the following parameters were used' - scenario | datanodeXpath | expectedException - 'valid data node, non existent child node' | '/parent-203/child-non-existent' | DataNodeNotFoundException - 'invalid list element' | '/parent-206/child-206/grand-child-206@key="A"]' | PathParsingException + scenario | datanodeXpath | expectedException + 'valid data node, non existent child node' | '/parent-203/child-non-existent' | DataNodeNotFoundException + 'invalid list element' | '/parent-206/child-206/grand-child-206@key="A"]' | CpsPathException } @Sql([CLEAR_DATA, SET_DATA]) def 'Delete data node for an anchor.'() { given: 'a data-node exists for an anchor' - assert fragmentsExistInDB(1001, 3003) + assert fragmentsExistInDB(3003) when: 'data nodes are deleted ' objectUnderTest.deleteDataNodes(DATASPACE_NAME, ANCHOR_NAME3) then: 'all data-nodes are deleted successfully' - assert !fragmentsExistInDB(1001, 3003) + assert !fragmentsExistInDB(3003) } @Sql([CLEAR_DATA, SET_DATA]) def 'Delete data node for multiple anchors.'() { given: 'a data-node exists for an anchor' - assert fragmentsExistInDB(1001, 3001) - assert fragmentsExistInDB(1001, 3003) + assert fragmentsExistInDB(3001) + assert fragmentsExistInDB(3003) when: 'data nodes are deleted ' objectUnderTest.deleteDataNodes(DATASPACE_NAME, ['ANCHOR-001', 'ANCHOR-003']) then: 'all data-nodes are deleted successfully' - assert !fragmentsExistInDB(1001, 3001) - assert !fragmentsExistInDB(1001, 3003) + assert !fragmentsExistInDB(3001) + assert !fragmentsExistInDB(3003) } - def fragmentsExistInDB(dataSpaceId, anchorId) { - !fragmentRepository.findRootsByDataspaceAndAnchor(dataSpaceId, anchorId).isEmpty() + def fragmentsExistInDB(anchorId) { + fragmentRepository.existsByAnchorId(anchorId) } static Collection toDataNodes(xpaths) { @@ -707,23 +694,10 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { return dataNodeBuilder.withXpath(xpath).withLeaves(leaves).withChildDataNodes(childDataNodes).build() } - static Map getLeavesMap(FragmentEntity fragmentEntity) { + Map getLeavesMap(FragmentEntity fragmentEntity) { return jsonObjectMapper.convertJsonString(fragmentEntity.attributes, Map.class) } - def static assertLeavesMaps(actualLeavesMap, expectedLeavesMap) { - expectedLeavesMap.forEach((key, value) -> { - def actualValue = actualLeavesMap[key] - if (value instanceof Collection && actualValue instanceof Collection) { - assert value.size() == actualValue.size() - assert value.containsAll(actualValue) - } else { - assert value == actualValue - } - }) - return true - } - def static treeToFlatMapByXpath(Map flatMap, DataNode dataNodeTree) { flatMap.put(dataNodeTree.xpath, dataNodeTree) dataNodeTree.childDataNodes @@ -757,10 +731,9 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase { def getFragmentByXpath(dataspaceName, anchorName, xpath) { def dataspace = dataspaceRepository.getByName(dataspaceName) def anchor = anchorRepository.getByDataspaceAndName(dataspace, anchorName) - return fragmentRepository.findByDataspaceAndAnchorAndXpath(dataspace, anchor, xpath).orElseThrow() + return fragmentRepository.findByAnchorAndXpath(anchor, xpath).orElseThrow() } - def createChildListAllHavingAttributeValue(parentXpath, tag, Collection keys, boolean addGrandChild) { def listElementAsDataNodes = keysToXpaths(parentXpath, keys).collect { new DataNodeBuilder()