package org.onap.cps.spi.impl;
-import com.google.common.base.Strings;
+import static org.onap.cps.spi.PaginationOption.NO_PAGINATION;
+
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import io.micrometer.core.annotation.Timed;
+import jakarta.transaction.Transactional;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import javax.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.StaleStateException;
import org.onap.cps.cpspath.parser.PathParsingException;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.spi.PaginationOption;
import org.onap.cps.spi.entities.AnchorEntity;
import org.onap.cps.spi.entities.DataspaceEntity;
import org.onap.cps.spi.entities.FragmentEntity;
private final SessionManager sessionManager;
private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@.+?])?)";
- private static final String QUERY_ACROSS_ANCHORS = null;
- private static final AnchorEntity ALL_ANCHORS = null;
@Override
public void addChildDataNodes(final String dataspaceName, final String anchorName,
newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
try {
fragmentRepository.save(newChildAsFragmentEntity);
- } catch (final DataIntegrityViolationException e) {
+ } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
throw AlreadyDefinedException.forDataNodes(Collections.singletonList(newChild.getXpath()),
anchorEntity.getName());
}
fragmentEntities.add(newChildAsFragmentEntity);
}
fragmentRepository.saveAll(fragmentEntities);
- } catch (final DataIntegrityViolationException e) {
+ } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
log.warn("Exception occurred : {} , While saving : {} children, retrying using individual save operations",
- e, fragmentEntities.size());
+ dataIntegrityViolationException, fragmentEntities.size());
retrySavingEachChildIndividually(anchorEntity, parentNodeXpath, newChildren);
}
}
for (final DataNode newChild : newChildren) {
try {
addNewChildDataNode(anchorEntity, parentNodeXpath, newChild);
- } catch (final AlreadyDefinedException e) {
+ } catch (final AlreadyDefinedException alreadyDefinedException) {
failedXpaths.add(newChild.getXpath());
}
}
try {
final FragmentEntity fragmentEntity = convertToFragmentWithAllDescendants(anchorEntity, dataNode);
fragmentRepository.save(fragmentEntity);
- } catch (final DataIntegrityViolationException e) {
+ } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
failedXpaths.add(dataNode.getXpath());
}
}
private Collection<FragmentEntity> getFragmentEntities(final AnchorEntity anchorEntity,
final Collection<String> xpaths) {
- final Collection<String> nonRootXpaths = new HashSet<>(xpaths);
- final boolean haveRootXpath = nonRootXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath);
+ final Collection<String> normalizedXpaths = getNormalizedXpaths(xpaths);
- final Collection<String> normalizedXpaths = new HashSet<>(nonRootXpaths.size());
- for (final String xpath : nonRootXpaths) {
- try {
- normalizedXpaths.add(CpsPathUtil.getNormalizedXpath(xpath));
- } catch (final PathParsingException e) {
- log.warn("Error parsing xpath \"{}\": {}", xpath, e.getMessage());
+ final boolean haveRootXpath = normalizedXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath);
+
+ final List<FragmentEntity> fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity,
+ normalizedXpaths);
+
+ for (final FragmentEntity fragmentEntity : fragmentEntities) {
+ normalizedXpaths.remove(fragmentEntity.getXpath());
+ }
+
+ for (final String xpath : normalizedXpaths) {
+ if (!CpsPathUtil.isPathToListElement(xpath)) {
+ fragmentEntities.addAll(fragmentRepository.findListByAnchorAndXpath(anchorEntity, xpath));
}
}
+
if (haveRootXpath) {
- normalizedXpaths.addAll(fragmentRepository.findAllXpathByAnchorAndParentIdIsNull(anchorEntity));
+ fragmentEntities.addAll(fragmentRepository.findRootsByAnchorId(anchorEntity.getId()));
}
- return fragmentRepository.findByAnchorAndXpathIn(anchorEntity, normalizedXpaths);
+ return fragmentEntities;
}
private FragmentEntity getFragmentEntity(final AnchorEntity anchorEntity, final String xpath) {
public List<DataNode> queryDataNodes(final String dataspaceName, final String anchorName, final String cpsPath,
final FetchDescendantsOption fetchDescendantsOption) {
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final AnchorEntity anchorEntity = Strings.isNullOrEmpty(anchorName) ? ALL_ANCHORS
- : anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
+ final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
+ final CpsPathQuery cpsPathQuery;
+ try {
+ cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
+ } catch (final PathParsingException pathParsingException) {
+ throw new CpsPathException(pathParsingException.getMessage());
+ }
+
+ Collection<FragmentEntity> fragmentEntities;
+ fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery);
+ if (cpsPathQuery.hasAncestorAxis()) {
+ final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery);
+ fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths);
+ }
+ fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption,
+ fragmentEntities);
+ return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
+ }
+
+ @Override
+ @Timed(value = "cps.data.persistence.service.datanode.query.anchors",
+ description = "Time taken to query data nodes across all anchors or list of anchors")
+ public List<DataNode> queryDataNodesAcrossAnchors(final String dataspaceName, final String cpsPath,
+ final FetchDescendantsOption fetchDescendantsOption,
+ final PaginationOption paginationOption) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final CpsPathQuery cpsPathQuery;
try {
cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
throw new CpsPathException(e.getMessage());
}
- Collection<FragmentEntity> fragmentEntities;
- if (anchorEntity == ALL_ANCHORS) {
- fragmentEntities = fragmentRepository.findByDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery);
+ final List<Long> anchorIds;
+ if (paginationOption == NO_PAGINATION) {
+ anchorIds = Collections.emptyList();
} else {
- fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery);
+ anchorIds = getAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, paginationOption);
+ if (anchorIds.isEmpty()) {
+ return Collections.emptyList();
+ }
}
+ Collection<FragmentEntity> fragmentEntities =
+ fragmentRepository.findByDataspaceAndCpsPath(dataspaceEntity, cpsPathQuery, anchorIds);
+
if (cpsPathQuery.hasAncestorAxis()) {
final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery);
- if (anchorEntity == ALL_ANCHORS) {
+ if (anchorIds.isEmpty()) {
fragmentEntities = fragmentRepository.findByDataspaceAndXpathIn(dataspaceEntity, ancestorXpaths);
} else {
- fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths);
+ fragmentEntities = fragmentRepository.findByAnchorIdsAndXpathIn(
+ anchorIds.toArray(new Long[0]), ancestorXpaths.toArray(new String[0]));
}
+
}
fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption,
fragmentEntities);
return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
}
- @Override
- public List<DataNode> queryDataNodesAcrossAnchors(final String dataspaceName, final String cpsPath,
- final FetchDescendantsOption fetchDescendantsOption) {
- return queryDataNodes(dataspaceName, QUERY_ACROSS_ANCHORS, cpsPath, fetchDescendantsOption);
+ private List<Long> getAnchorIdsForPagination(final DataspaceEntity dataspaceEntity, final CpsPathQuery cpsPathQuery,
+ final PaginationOption paginationOption) {
+ return fragmentRepository.findAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, paginationOption);
}
private List<DataNode> createDataNodesFromFragmentEntities(final FetchDescendantsOption fetchDescendantsOption,
}
try {
return CpsPathUtil.getNormalizedXpath(xpathSource);
- } catch (final PathParsingException e) {
- throw new CpsPathException(e.getMessage());
+ } catch (final PathParsingException pathParsingException) {
+ throw new CpsPathException(pathParsingException.getMessage());
}
}
+ private static Collection<String> getNormalizedXpaths(final Collection<String> xpaths) {
+ final Collection<String> normalizedXpaths = new HashSet<>(xpaths.size());
+ for (final String xpath : xpaths) {
+ try {
+ normalizedXpaths.add(getNormalizedXpath(xpath));
+ } catch (final CpsPathException cpsPathException) {
+ log.warn("Error parsing xpath \"{}\": {}", xpath, cpsPathException.getMessage());
+ }
+ }
+ return normalizedXpaths;
+ }
+
@Override
public String startSession() {
return sessionManager.startSession();
sessionManager.lockAnchor(sessionId, dataspaceName, anchorName, timeoutInMilliseconds);
}
+ @Override
+ public Integer countAnchorsForDataspaceAndCpsPath(final String dataspaceName, final String cpsPath) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+ final CpsPathQuery cpsPathQuery;
+ try {
+ cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
+ } catch (final PathParsingException e) {
+ throw new CpsPathException(e.getMessage());
+ }
+ final List<Long> anchorIdList = getAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, NO_PAGINATION);
+ return anchorIdList.size();
+ }
+
private static Set<String> processAncestorXpath(final Collection<FragmentEntity> fragmentEntities,
final CpsPathQuery cpsPathQuery) {
final Set<String> ancestorXpath = new HashSet<>();
for (final FragmentEntity dataNodeFragment : fragmentEntities) {
try {
fragmentRepository.save(dataNodeFragment);
- } catch (final StaleStateException e) {
+ } catch (final StaleStateException staleStateException) {
failedXpaths.add(dataNodeFragment.getXpath());
}
}
final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName);
- final Collection<String> deleteChecklist = new HashSet<>(xpathsToDelete.size());
- for (final String xpath : xpathsToDelete) {
- try {
- deleteChecklist.add(CpsPathUtil.getNormalizedXpath(xpath));
- } catch (final PathParsingException e) {
- log.warn("Error parsing xpath \"{}\": {}", xpath, e.getMessage());
- }
- }
-
+ final Collection<String> deleteChecklist = getNormalizedXpaths(xpathsToDelete);
final Collection<String> xpathsToExistingContainers =
fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist);
if (onlySupportListDeletion) {