/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
+ * Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
}
+ @Override
+ public <T> Set<T> queryDataLeaf(final String dataspaceName, final String anchorName, final String cpsPath,
+ final Class<T> targetClass) {
+ final CpsPathQuery cpsPathQuery = getCpsPathQuery(cpsPath);
+ if (!cpsPathQuery.hasAttributeAxis()) {
+ throw new IllegalArgumentException(
+ "Only Cps Path Queries with attribute-axis are supported by queryDataLeaf");
+ }
+
+ final String attributeName = cpsPathQuery.getAttributeAxisAttributeName();
+ final List<DataNode> dataNodes = queryDataNodes(dataspaceName, anchorName, cpsPath,
+ FetchDescendantsOption.OMIT_DESCENDANTS);
+ return dataNodes.stream()
+ .map(dataNode -> {
+ final Object attributeValue = dataNode.getLeaves().get(attributeName);
+ return targetClass.isInstance(attributeValue) ? targetClass.cast(attributeValue) : null;
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ }
+
@Override
@Timed(value = "cps.data.persistence.service.datanode.query.anchors",
description = "Time taken to query data nodes across all anchors or list of anchors")
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation
+ * Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
public <T> Set<T> queryDataLeaf(final String dataspaceName, final String anchorName, final String cpsPath,
final Class<T> targetClass) {
cpsValidator.validateNameCharacters(dataspaceName, anchorName);
- throw new UnsupportedOperationException("Query by attribute-axis not implemented yet!");
+ return cpsDataPersistenceService.queryDataLeaf(dataspaceName, anchorName, cpsPath, targetClass);
}
@Override
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020-2024 Nordix Foundation.
+ * Copyright (C) 2020-2025 Nordix Foundation.
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 Bell Canada
* Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.onap.cps.api.model.DataNode;
import org.onap.cps.api.parameters.FetchDescendantsOption;
import org.onap.cps.api.parameters.PaginationOption;
List<DataNode> queryDataNodes(String dataspaceName, String anchorName,
String cpsPath, FetchDescendantsOption fetchDescendantsOption);
+ /**
+ * Get data leaf for the given dataspace and anchor by cps path.
+ *
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @param cpsPath cps path
+ * @param targetClass class of the expected data type
+ * @return a collection of data objects of expected type
+ */
+ <T> Set<T> queryDataLeaf(String dataspaceName, String anchorName, String cpsPath, Class<T> targetClass);
+
/**
* Get a datanode by dataspace name and cps path across all anchors.
*
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2021-2025 Nordix Foundation
* Modifications Copyright (C) 2023 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
1 * mockCpsDataPersistenceService.countAnchorsForDataspaceAndCpsPath("some-dataspace", "/cps-path")
}
- // TODO will be implemented in CPS-2416
def 'Query data leaf.'() {
when: 'a query for a specific leaf is executed'
objectUnderTest.queryDataLeaf('some-dataspace', 'some-anchor', '/cps-path/@id', Object.class)
then: 'solution is not implemented yet'
- thrown(UnsupportedOperationException)
+ 1 * mockCpsDataPersistenceService.queryDataLeaf('some-dataspace', 'some-anchor', '/cps-path/@id', Object.class)
}
}
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation
+ * Copyright (C) 2023-2025 Nordix Foundation
* Modifications Copyright (C) 2023-2025 TechMahindra Ltd
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the 'License');
import org.onap.cps.api.parameters.FetchDescendantsOption
import org.onap.cps.api.parameters.PaginationOption
import org.onap.cps.api.exceptions.CpsPathException
-import spock.lang.Ignore
import static org.onap.cps.api.parameters.FetchDescendantsOption.DIRECT_CHILDREN_ONLY
import static org.onap.cps.api.parameters.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
'the AND is used where result does not exist' | '//books[@lang="English" and @price=1000]' || 0 | []
}
- @Ignore // TODO will be implemented in CPS-2416
def 'Query data leaf using CPS path for #scenario.'() {
when: 'query data leaf for bookstore container'
def result = objectUnderTest.queryDataLeaf(FUNCTIONAL_TEST_DATASPACE_1, BOOKSTORE_ANCHOR_1, cpsPath, Object.class)
'non-existing path' | '/non-existing/@title' || 0
}
- @Ignore
def 'Query data leaf with type #leafType using CPS path.'() {
given: 'a cps path query for two books, returning only #leafName'
def cpsPath = '//books[@title="Matilda" or @title="Good Omens"]/@' + leafName
'editions' | List.class || [[1988, 2000], [2006]]
}
- @Ignore
def 'Query data leaf using CPS path with ancestor axis.'() {
given: 'a cps path query that will return the names of the categories of two books'
def cpsPath = '//books[@title="Matilda" or @title="Good Omens"]/ancestor::categories/@name'