package org.onap.cps.spi.impl
-import com.fasterxml.jackson.databind.ObjectMapper
import com.google.common.collect.ImmutableSet
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.entities.FragmentEntity
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
@Autowired
CpsDataPersistenceService objectUnderTest
- static JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
static DataNodeBuilder dataNodeBuilder = new DataNodeBuilder()
static final String SET_DATA = '/data/fragment.sql'
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)
}
@Sql([CLEAR_DATA, SET_DATA])
- def 'Update data node leaves.'() {
- when: 'update is performed for leaves'
- 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 updatedLeaves = getLeavesMap(updatedFragment)
- assert updatedLeaves.size() == 1
- assert updatedLeaves.'leaf-value' == 'new'
- and: 'existing child entry remains as is'
- def childFragment = updatedFragment.childFragments.iterator().next()
- def childLeaves = getLeavesMap(childFragment)
- assert childFragment.id == CHILD_OF_DATA_NODE_202_FRAGMENT_ID
- assert childLeaves.'leaf-value' == 'original'
- }
-
- @Sql([CLEAR_DATA, SET_DATA])
- def 'Update data leaves error scenario: #scenario.'() {
- when: 'attempt to update data node for #scenario'
- objectUnderTest.updateDataLeaves(dataspaceName, anchorName, xpath, ['leaf-name': 'leaf-value'])
- 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
- }
-
- @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'
}
@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'
}
@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'
}
@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'
}
@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])
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()
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']"
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'
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()
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()
given: 'a data nodes with list-element child with "/" in index value (and grandchild)'
def grandChild = new DataNodeBuilder().withXpath(deleteTestGrandChildXPath).build()
def child = new DataNodeBuilder().withXpath(deleteTestChildXpath).withChildDataNodes([grandChild]).build()
- objectUnderTest.addChildDataNode(DATASPACE_NAME, ANCHOR_NAME3, deleteTestParentXPath, child)
+ objectUnderTest.addChildDataNodes(DATASPACE_NAME, ANCHOR_NAME3, deleteTestParentXPath, [child])
and: 'number of children before delete is stored'
def numberOfChildrenBeforeDelete = objectUnderTest.getDataNodes(DATASPACE_NAME, ANCHOR_NAME3, pathToParentOfDeletedNode, INCLUDE_ALL_DESCENDANTS)[0].childDataNodes.size()
when: 'target node is deleted'
return dataNodeBuilder.withXpath(xpath).withLeaves(leaves).withChildDataNodes(childDataNodes).build()
}
- static Map<String, Object> getLeavesMap(FragmentEntity fragmentEntity) {
+ Map<String, Object> getLeavesMap(FragmentEntity fragmentEntity) {
return jsonObjectMapper.convertJsonString(fragmentEntity.attributes, Map<String, Object>.class)
}