diff options
author | Toine Siebelink <toine.siebelink@est.tech> | 2024-09-24 16:23:40 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2024-09-24 16:23:40 +0000 |
commit | 16fac4c85041d060b5b2ea470e0fe12590d1c1af (patch) | |
tree | 7c6ca9a6251c0c03263081102759d32d2f1b6857 | |
parent | 1125bd88a0daab49e1c92e86d42e17d370dc1af4 (diff) | |
parent | ad021691bb5296f203ddeaba41241d8ca1317414 (diff) |
Merge "Reduce anchor lookups related to PrefixResolver (CPS-2417 #1)"
7 files changed, 46 insertions, 43 deletions
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java index 6015e0e3ae..f86073fb06 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2022-2024 TechMahindra Ltd. * Modifications Copyright (C) 2022 Deutsche Telekom AG * ================================================================================ @@ -37,9 +37,11 @@ import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; import org.onap.cps.rest.api.CpsDataApi; import org.onap.cps.spi.FetchDescendantsOption; +import org.onap.cps.spi.model.Anchor; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DeltaReport; import org.onap.cps.utils.ContentType; @@ -63,6 +65,7 @@ public class DataRestController implements CpsDataApi { private static final DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_FORMAT); private final CpsDataService cpsDataService; + private final CpsAnchorService cpsAnchorService; private final JsonObjectMapper jsonObjectMapper; private final PrefixResolver prefixResolver; @@ -112,7 +115,8 @@ public class DataRestController implements CpsDataApi { ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS; final DataNode dataNode = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption).iterator().next(); - final String prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); + final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); return new ResponseEntity<>(DataMapUtils.toDataMapWithIdentifier(dataNode, prefix), HttpStatus.OK); } @@ -127,8 +131,9 @@ public class DataRestController implements CpsDataApi { final Collection<DataNode> dataNodes = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption); final List<Map<String, Object>> dataMaps = new ArrayList<>(dataNodes.size()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); for (final DataNode dataNode: dataNodes) { - final String prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); final Map<String, Object> dataMap = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); dataMaps.add(dataMap); } diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java index 5334b48143..547be669ae 100644 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada. * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ @@ -29,10 +29,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsQueryService; import org.onap.cps.rest.api.CpsQueryApi; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.PaginationOption; +import org.onap.cps.spi.model.Anchor; import org.onap.cps.spi.model.DataNode; import org.onap.cps.utils.DataMapUtils; import org.onap.cps.utils.JsonObjectMapper; @@ -48,6 +50,7 @@ import org.springframework.web.bind.annotation.RestController; public class QueryRestController implements CpsQueryApi { private final CpsQueryService cpsQueryService; + private final CpsAnchorService cpsAnchorService; private final JsonObjectMapper jsonObjectMapper; private final PrefixResolver prefixResolver; @@ -87,14 +90,15 @@ public class QueryRestController implements CpsQueryApi { cpsPath, fetchDescendantsOption, paginationOption); final List<Map<String, Object>> dataNodesAsListOfMaps = new ArrayList<>(dataNodes.size()); String prefix = null; - final Map<String, List<DataNode>> anchorDataNodeListMap = prepareDataNodesForAnchor(dataNodes); - for (final Map.Entry<String, List<DataNode>> anchorDataNodesMapEntry : anchorDataNodeListMap.entrySet()) { + final Map<String, List<DataNode>> dataNodesPerAnchor = groupDataNodesPerAnchor(dataNodes); + for (final Map.Entry<String, List<DataNode>> dataNodesPerAnchorEntry : dataNodesPerAnchor.entrySet()) { + final String anchorName = dataNodesPerAnchorEntry.getKey(); if (prefix == null) { - prefix = prefixResolver.getPrefix(dataspaceName, anchorDataNodesMapEntry.getKey(), - anchorDataNodesMapEntry.getValue().get(0).getXpath()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); + prefix = prefixResolver.getPrefix(anchor, dataNodesPerAnchorEntry.getValue().get(0).getXpath()); } final Map<String, Object> dataMap = DataMapUtils.toDataMapWithIdentifierAndAnchor( - anchorDataNodesMapEntry.getValue(), anchorDataNodesMapEntry.getKey(), prefix); + dataNodesPerAnchorEntry.getValue(), anchorName, prefix); dataNodesAsListOfMaps.add(dataMap); } final Integer totalPages = getTotalPages(dataspaceName, cpsPath, paginationOption); @@ -112,7 +116,7 @@ public class QueryRestController implements CpsQueryApi { : (int) Math.ceil((double) totalAnchors / paginationOption.getPageSize()); } - private Map<String, List<DataNode>> prepareDataNodesForAnchor(final Collection<DataNode> dataNodes) { + private Map<String, List<DataNode>> groupDataNodesPerAnchor(final Collection<DataNode> dataNodes) { final Map<String, List<DataNode>> dataNodesMapForAnchor = new HashMap<>(); for (final DataNode dataNode : dataNodes) { List<DataNode> dataNodesInAnchor = dataNodesMapForAnchor.get(dataNode.getAnchorName()); @@ -130,10 +134,11 @@ public class QueryRestController implements CpsQueryApi { final Collection<DataNode> dataNodes = cpsQueryService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption); final List<Map<String, Object>> dataNodesAsListOfMaps = new ArrayList<>(dataNodes.size()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); String prefix = null; for (final DataNode dataNode : dataNodes) { if (prefix == null) { - prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); } final Map<String, Object> dataMap = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); dataNodesAsListOfMaps.add(dataMap); diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy index 5241f61bd9..e101ea6c41 100755 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada. * Modifications Copyright (C) 2022 Deutsche Telekom AG @@ -26,6 +26,7 @@ package org.onap.cps.rest.controller import com.fasterxml.jackson.databind.ObjectMapper import groovy.json.JsonSlurper +import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsDataService import org.onap.cps.spi.FetchDescendantsOption import org.onap.cps.spi.model.DataNode @@ -63,6 +64,9 @@ class DataRestControllerSpec extends Specification { CpsDataService mockCpsDataService = Mock() @SpringBean + CpsAnchorService mockCpsAnchorService = Mock() + + @SpringBean JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) @SpringBean diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy index c30a63fd46..80b287cda8 100644 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2021-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. @@ -23,18 +23,13 @@ package org.onap.cps.rest.controller -import org.onap.cps.spi.PaginationOption -import org.onap.cps.utils.PrefixResolver - -import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS -import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get - import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.utils.JsonObjectMapper +import org.onap.cps.api.CpsAnchorService import org.onap.cps.api.CpsQueryService +import org.onap.cps.spi.PaginationOption import org.onap.cps.spi.model.DataNodeBuilder +import org.onap.cps.utils.JsonObjectMapper +import org.onap.cps.utils.PrefixResolver import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -43,6 +38,11 @@ import org.springframework.http.HttpStatus import org.springframework.test.web.servlet.MockMvc import spock.lang.Specification +import static org.onap.cps.spi.FetchDescendantsOption.DIRECT_CHILDREN_ONLY +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get + @WebMvcTest(QueryRestController) class QueryRestControllerSpec extends Specification { @@ -50,6 +50,9 @@ class QueryRestControllerSpec extends Specification { CpsQueryService mockCpsQueryService = Mock() @SpringBean + CpsAnchorService mockCpsAnchorService = Mock() + + @SpringBean JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) @SpringBean diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java index 951770b053..eed4f09bf0 100644 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java @@ -400,8 +400,7 @@ public class CpsDataServiceImpl implements CpsDataService { private List<Map<String, Object>> prefixResolver(final Anchor anchor, final Collection<DataNode> dataNodes) { final List<Map<String, Object>> prefixToDataNodes = new ArrayList<>(dataNodes.size()); for (final DataNode dataNode: dataNodes) { - final String prefix = prefixResolver - .getPrefix(anchor.getDataspaceName(), anchor.getName(), dataNode.getXpath()); + final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); final Map<String, Object> prefixToDataNode = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); prefixToDataNodes.add(prefixToDataNode); } diff --git a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java index 35dc7347b2..93fb72864f 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java +++ b/cps-service/src/main/java/org/onap/cps/utils/PrefixResolver.java @@ -55,19 +55,6 @@ public class PrefixResolver { private final IMap<String, AnchorDataCacheEntry> anchorDataCache; /** - * Get the module prefix for the given xpath for a dataspace and anchor name. - * - * @param dataspaceName the name of the dataspace - * @param anchorName the name of the anchor the xpath belongs to - * @param xpath the xpath to prefix a prefix for - * @return the prefix of the module the top level element of given xpath - */ - public String getPrefix(final String dataspaceName, final String anchorName, final String xpath) { - final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); - return getPrefix(anchor, xpath); - } - - /** * Get the module prefix for the given xpath under the given anchor. * * @param anchor the anchor the xpath belong to diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy index b975de6555..5ef584a0b8 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/PrefixResolverSpec.groovy @@ -48,10 +48,10 @@ class PrefixResolverSpec extends Specification { def schemaContext = YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent).getSchemaContext() + def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor') + def setup() { - given: 'an anchor for the test-tree model' - def anchor = new Anchor(dataspaceName: 'testDataspace', name: 'testAnchor') - and: 'the system can get this anchor' + given: 'the system can get the anchor' mockCpsAnchorService.getAnchor('testDataspace', 'testAnchor') >> anchor and: 'the schema source cache contains the schema context for the test-tree module' mockYangTextSchemaSourceSet.getSchemaContext() >> schemaContext @@ -59,7 +59,7 @@ class PrefixResolverSpec extends Specification { def 'get xpath prefix using node schema context'() { when: 'the prefix of the yang module is retrieved' - def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', xpath) + def result = objectUnderTest.getPrefix(anchor, xpath) then: 'the expected prefix is returned' result == expectedPrefix and: 'the cache is updated for the given anchor with a map of prefixes per top level container (just one one this case)' @@ -90,7 +90,7 @@ class PrefixResolverSpec extends Specification { mockAnchorDataCache.containsKey('testAnchor') >> true mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry when: 'the prefix of the yang module is retrieved' - def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree') + def result = objectUnderTest.getPrefix(anchor, '/test-tree') then: 'the expected prefix is returned' result == expectedPrefix and: 'schema source cache is not used (i.e. no need to build schema context)' @@ -108,7 +108,7 @@ class PrefixResolverSpec extends Specification { mockAnchorDataCache.containsKey('testAnchor') >> true mockAnchorDataCache.get('testAnchor') >> anchorDataCacheEntry when: 'the prefix of the yang module is retrieved' - def result = objectUnderTest.getPrefix('testDataspace', 'testAnchor', '/test-tree') + def result = objectUnderTest.getPrefix(anchor, '/test-tree') then: 'the expected prefix is returned' result == 'tree' and: 'schema source cache is used (i.e. need to build schema context)' |