diff options
author | danielhanrahan <daniel.hanrahan@est.tech> | 2024-10-02 21:31:04 +0100 |
---|---|---|
committer | danielhanrahan <daniel.hanrahan@est.tech> | 2024-10-03 21:04:09 +0100 |
commit | 153aa48c6945cfc54ceb1b3f6a38508ad93f1d16 (patch) | |
tree | 9b4510292b2efd1e11d34f4493d7604ea98d2172 | |
parent | 2686ec95a09bafa2846860d403516f89cb2ed0c0 (diff) |
[BUG] Fix memory leak related to using arrays in Hibernate
The use of arrays like String[] instead of Collection<String> in
JpaRepository methods is causing a memory leak, most likely due to a
bug in the hypersistence-utils dependency which provides the feature.
Note code using arrays in JDBC (via jdbcTemplate) is not affected.
This patch removes most uses of arrays in Java, except one needed for
FragmentPrefetchRepository using JDBC setArray(), which is safe.
Issue-ID: CPS-2430
Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech>
Change-Id: I94f8c3d4c8c32ebe0978c08d3226a196a95bf3b9
9 files changed, 72 insertions, 100 deletions
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java index bde9b0638f..4ede0d9c90 100644 --- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java +++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation + * Copyright (C) 2022-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,12 +59,10 @@ public class CpsPathUtil { return getCpsPathBuilder(xpathSource).build().getNormalizedParentPath(); } - public static String[] getXpathNodeIdSequence(final String xpathSource) { - final List<String> containerNames = getCpsPathBuilder(xpathSource).build().getContainerNames(); - return containerNames.toArray(new String[containerNames.size()]); + public static List<String> getXpathNodeIdSequence(final String xpathSource) { + return getCpsPathBuilder(xpathSource).build().getContainerNames(); } - /** * Returns boolean indicating xpath is an absolute path to a list element. * diff --git a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java index ec46fea4cb..ee555f7dc8 100644 --- a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java @@ -341,8 +341,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService if (anchorIds.isEmpty()) { fragmentEntities = fragmentRepository.findByDataspaceAndXpathIn(dataspaceEntity, ancestorXpaths); } else { - fragmentEntities = fragmentRepository.findByAnchorIdsAndXpathIn( - anchorIds.toArray(new Long[0]), ancestorXpaths.toArray(new String[0])); + fragmentEntities = fragmentRepository.findByAnchorIdsAndXpathIn(anchorIds, ancestorXpaths); } } @@ -475,7 +474,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist); if (onlySupportListDeletion) { final Collection<String> xpathsToExistingListElements = xpathsToExistingContainers.stream() - .filter(CpsPathUtil::isPathToListElement).collect(Collectors.toList()); + .filter(CpsPathUtil::isPathToListElement).toList(); deleteChecklist.removeAll(xpathsToExistingListElements); } else { deleteChecklist.removeAll(xpathsToExistingContainers); @@ -483,15 +482,19 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final Collection<String> xpathsToExistingLists = deleteChecklist.stream() .filter(xpath -> fragmentRepository.existsByAnchorAndXpathStartsWith(anchorEntity, xpath + "[")) - .collect(Collectors.toList()); + .toList(); deleteChecklist.removeAll(xpathsToExistingLists); if (!deleteChecklist.isEmpty()) { throw new DataNodeNotFoundExceptionBatch(dataspaceName, anchorName, deleteChecklist); } - fragmentRepository.deleteByAnchorIdAndXpaths(anchorEntity.getId(), xpathsToExistingContainers); - fragmentRepository.deleteListsByAnchorIdAndXpaths(anchorEntity.getId(), xpathsToExistingLists); + if (!xpathsToExistingContainers.isEmpty()) { + fragmentRepository.deleteByAnchorIdAndXpaths(anchorEntity.getId(), xpathsToExistingContainers); + } + for (final String listXpath : xpathsToExistingLists) { + fragmentRepository.deleteListByAnchorIdAndXpath(anchorEntity.getId(), listXpath); + } } @Override diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/AnchorRepository.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/AnchorRepository.java index 7fe14b3173..f7f750c983 100755 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/AnchorRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/AnchorRepository.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,26 +46,26 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Long> { Collection<AnchorEntity> findAllBySchemaSet(SchemaSetEntity schemaSetEntity); - @Query(value = "SELECT * FROM anchor WHERE dataspace_id = :dataspaceId AND name = ANY (:anchorNames)", + @Query(value = "SELECT * FROM anchor WHERE dataspace_id = :dataspaceId AND name IN (:anchorNames)", nativeQuery = true) Collection<AnchorEntity> findAllByDataspaceIdAndNameIn(@Param("dataspaceId") int dataspaceId, - @Param("anchorNames") String[] anchorNames); + @Param("anchorNames") Collection<String> anchorNames); default Collection<AnchorEntity> findAllByDataspaceAndNameIn(final DataspaceEntity dataspaceEntity, final Collection<String> anchorNames) { - return findAllByDataspaceIdAndNameIn(dataspaceEntity.getId(), anchorNames.toArray(new String[0])); + return findAllByDataspaceIdAndNameIn(dataspaceEntity.getId(), anchorNames); } @Query(value = "SELECT a.* FROM anchor a" + " LEFT OUTER JOIN schema_set s ON a.schema_set_id = s.id" - + " WHERE a.dataspace_id = :dataspaceId AND s.name = ANY (:schemaSetNames)", + + " WHERE a.dataspace_id = :dataspaceId AND s.name IN (:schemaSetNames)", nativeQuery = true) - Collection<AnchorEntity> findAllByDataspaceIdAndSchemaSetNameIn(@Param("dataspaceId") int dataspaceId, - @Param("schemaSetNames") String[] schemaSetNames); + Collection<AnchorEntity> findAllByDataspaceIdAndSchemaSetNameIn( + @Param("dataspaceId") int dataspaceId, @Param("schemaSetNames") Collection<String> schemaSetNames); default Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(final DataspaceEntity dataspaceEntity, final Collection<String> schemaSetNames) { - return findAllByDataspaceIdAndSchemaSetNameIn(dataspaceEntity.getId(), schemaSetNames.toArray(new String[0])); + return findAllByDataspaceIdAndSchemaSetNameIn(dataspaceEntity.getId(), schemaSetNames); } Integer countByDataspace(DataspaceEntity dataspaceEntity); @@ -80,7 +80,7 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Long> { JOIN anchor ON anchor.schema_set_id = schema_set.id WHERE schema_set.dataspace_id = :dataspaceId - AND module_name = ANY ( :moduleNames ) + AND module_name IN (:moduleNames) GROUP BY anchor.id, anchor.name, @@ -90,25 +90,18 @@ public interface AnchorRepository extends JpaRepository<AnchorEntity, Long> { COUNT(DISTINCT module_name) = :sizeOfModuleNames """, nativeQuery = true) Collection<String> getAnchorNamesByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId, - @Param("moduleNames") String[] moduleNames, + @Param("moduleNames") Collection<String> moduleNames, @Param("sizeOfModuleNames") int sizeOfModuleNames); - default Collection<String> getAnchorNamesByDataspaceIdAndModuleNames(final int dataspaceId, - final Collection<String> moduleNames, - final int sizeOfModuleNames) { - final String[] moduleNamesArray = moduleNames.toArray(new String[0]); - return getAnchorNamesByDataspaceIdAndModuleNames(dataspaceId, moduleNamesArray, sizeOfModuleNames); - } - @Modifying - @Query(value = "DELETE FROM anchor WHERE dataspace_id = :dataspaceId AND name = ANY (:anchorNames)", + @Query(value = "DELETE FROM anchor WHERE dataspace_id = :dataspaceId AND name IN (:anchorNames)", nativeQuery = true) void deleteAllByDataspaceIdAndNameIn(@Param("dataspaceId") int dataspaceId, - @Param("anchorNames") String[] anchorNames); + @Param("anchorNames") Collection<String> anchorNames); default void deleteAllByDataspaceAndNameIn(final DataspaceEntity dataspaceEntity, final Collection<String> anchorNames) { - deleteAllByDataspaceIdAndNameIn(dataspaceEntity.getId(), anchorNames.toArray(new String[0])); + deleteAllByDataspaceIdAndNameIn(dataspaceEntity.getId(), anchorNames); } @Modifying diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/FragmentRepository.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/FragmentRepository.java index 8edc3f2311..9598230cdb 100755 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/FragmentRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/FragmentRepository.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023 Nordix Foundation. + * Copyright (C) 2021-2024 Nordix Foundation. * Modifications Copyright (C) 2020-2021 Bell Canada. * Modifications Copyright (C) 2020-2021 Pantheon.tech. * Modifications Copyright (C) 2023 TechMahindra Ltd. @@ -48,14 +48,14 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, new DataNodeNotFoundException(anchorEntity.getDataspace().getName(), anchorEntity.getName(), xpath)); } - @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", + @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId AND xpath IN (:xpaths)", nativeQuery = true) List<FragmentEntity> findByAnchorIdAndXpathIn(@Param("anchorId") long anchorId, - @Param("xpaths") String[] xpaths); + @Param("xpaths") Collection<String> xpaths); default List<FragmentEntity> findByAnchorAndXpathIn(final AnchorEntity anchorEntity, final Collection<String> xpaths) { - return findByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths.toArray(new String[0])); + return findByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths); } @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId \n" @@ -70,58 +70,52 @@ public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, } @Query(value = "SELECT fragment.* FROM fragment JOIN anchor ON anchor.id = fragment.anchor_id " - + "WHERE dataspace_id = :dataspaceId AND xpath = ANY (:xpaths)", nativeQuery = true) + + "WHERE dataspace_id = :dataspaceId AND xpath IN (:xpaths)", nativeQuery = true) List<FragmentEntity> findByDataspaceIdAndXpathIn(@Param("dataspaceId") int dataspaceId, - @Param("xpaths") String[] xpaths); + @Param("xpaths") Collection<String> xpaths); default List<FragmentEntity> findByDataspaceAndXpathIn(final DataspaceEntity dataspaceEntity, final Collection<String> xpaths) { - return findByDataspaceIdAndXpathIn(dataspaceEntity.getId(), xpaths.toArray(new String[0])); + return findByDataspaceIdAndXpathIn(dataspaceEntity.getId(), xpaths); } @Query(value = "SELECT * FROM fragment WHERE anchor_id IN (:anchorIds)" - + " AND xpath = ANY (:xpaths)", nativeQuery = true) - List<FragmentEntity> findByAnchorIdsAndXpathIn(@Param("anchorIds") Long[] anchorIds, - @Param("xpaths") String[] xpaths); + + " AND xpath IN (:xpaths)", nativeQuery = true) + List<FragmentEntity> findByAnchorIdsAndXpathIn(@Param("anchorIds") Collection<Long> anchorIds, + @Param("xpaths") Collection<String> xpaths); @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId LIMIT 1", nativeQuery = true) Optional<FragmentEntity> findOneByAnchorId(@Param("anchorId") long anchorId); @Modifying - @Query(value = "DELETE FROM fragment WHERE anchor_id = ANY (:anchorIds)", nativeQuery = true) - void deleteByAnchorIdIn(@Param("anchorIds") long[] anchorIds); + @Query(value = "DELETE FROM fragment WHERE anchor_id IN (:anchorIds)", nativeQuery = true) + void deleteByAnchorIdIn(@Param("anchorIds") Collection<Long> anchorIds); default void deleteByAnchorIn(final Collection<AnchorEntity> anchorEntities) { - deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).mapToLong(id -> id).toArray()); + deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).toList()); } @Modifying - @Query(value = "DELETE FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", nativeQuery = true) - void deleteByAnchorIdAndXpaths(@Param("anchorId") long anchorId, @Param("xpaths") String[] xpaths); - - default void deleteByAnchorIdAndXpaths(final long anchorId, final Collection<String> xpaths) { - deleteByAnchorIdAndXpaths(anchorId, xpaths.toArray(new String[0])); - } + @Query(value = "DELETE FROM fragment WHERE anchor_id = :anchorId AND xpath IN (:xpaths)", nativeQuery = true) + void deleteByAnchorIdAndXpaths(@Param("anchorId") long anchorId, @Param("xpaths") Collection<String> xpaths); @Modifying - @Query(value = "DELETE FROM fragment f WHERE anchor_id = :anchorId AND xpath LIKE ANY (:xpathPatterns)", + @Query(value = "DELETE FROM fragment f WHERE anchor_id = :anchorId AND xpath LIKE :xpathPattern", nativeQuery = true) - void deleteByAnchorIdAndXpathLikeAny(@Param("anchorId") long anchorId, - @Param("xpathPatterns") String[] xpathPatterns); + void deleteByAnchorIdAndXpathLike(@Param("anchorId") long anchorId, @Param("xpathPattern") String xpathPattern); - default void deleteListsByAnchorIdAndXpaths(long anchorId, Collection<String> xpaths) { - deleteByAnchorIdAndXpathLikeAny(anchorId, - xpaths.stream().map(xpath -> EscapeUtils.escapeForSqlLike(xpath) + "[@%").toArray(String[]::new)); + default void deleteListByAnchorIdAndXpath(final long anchorId, final String xpath) { + deleteByAnchorIdAndXpathLike(anchorId, EscapeUtils.escapeForSqlLike(xpath) + "[@%"); } - @Query(value = "SELECT xpath FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", + @Query(value = "SELECT xpath FROM fragment WHERE anchor_id = :anchorId AND xpath IN (:xpaths)", nativeQuery = true) List<String> findAllXpathByAnchorIdAndXpathIn(@Param("anchorId") long anchorId, - @Param("xpaths") String[] xpaths); + @Param("xpaths") Collection<String> xpaths); default List<String> findAllXpathByAnchorAndXpathIn(final AnchorEntity anchorEntity, final Collection<String> xpaths) { - return findAllXpathByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths.toArray(new String[0])); + return findAllXpathByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths); } @Query(value = "SELECT EXISTS(SELECT 1 FROM fragment WHERE anchor_id = :anchorId" diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/ModuleReferenceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/ModuleReferenceRepositoryImpl.java index c160fb1e38..702b5896c7 100644 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/ModuleReferenceRepositoryImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/ModuleReferenceRepositoryImpl.java @@ -64,7 +64,7 @@ public class ModuleReferenceRepositoryImpl implements ModuleReferenceQuery { } final String tempTableName = tempTableCreator.createTemporaryTable( - "moduleReferencesToCheckTemp", sqlData, "module_name", "revision"); + "moduleReferencesToCheckTemp", sqlData, List.of("module_name", "revision")); return identifyNewModuleReferencesForCmHandle(tempTableName); } diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java index 9357a5c6a7..b455bc04c0 100644 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/SchemaSetRepository.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020 Pantheon.tech * Modifications Copyright (C) 2022 TechMahindra Ltd. - * Modifications Copyright (C) 2023 Nordix Foundation + * Modifications Copyright (C) 2023-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,10 +61,10 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte } @Modifying - @Query(value = "DELETE FROM schema_set WHERE dataspace_id = :dataspaceId AND name = ANY (:schemaSetNames)", + @Query(value = "DELETE FROM schema_set WHERE dataspace_id = :dataspaceId AND name IN (:schemaSetNames)", nativeQuery = true) void deleteByDataspaceIdAndNameIn(@Param("dataspaceId") final int dataspaceId, - @Param("schemaSetNames") final String[] schemaSetNames); + @Param("schemaSetNames") final Collection<String> schemaSetNames); /** * Delete multiple schema sets in a given dataspace. @@ -73,7 +73,7 @@ public interface SchemaSetRepository extends JpaRepository<SchemaSetEntity, Inte */ default void deleteByDataspaceAndNameIn(final DataspaceEntity dataspaceEntity, final Collection<String> schemaSetNames) { - deleteByDataspaceIdAndNameIn(dataspaceEntity.getId(), schemaSetNames.toArray(new String[0])); + deleteByDataspaceIdAndNameIn(dataspaceEntity.getId(), schemaSetNames); } } diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/TempTableCreator.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/TempTableCreator.java index cc83ab7d94..25c1491502 100644 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/TempTableCreator.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/TempTableCreator.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation. + * Copyright (C) 2022-2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,8 @@ package org.onap.cps.ri.repository; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @@ -54,7 +52,7 @@ public class TempTableCreator { */ public String createTemporaryTable(final String prefix, final Collection<List<String>> sqlData, - final String... columnNames) { + final Collection<String> columnNames) { final String tempTableName = prefix + UUID.randomUUID().toString().replace("-", ""); final StringBuilder sqlStringBuilder = new StringBuilder("CREATE TEMPORARY TABLE "); sqlStringBuilder.append(tempTableName); @@ -65,29 +63,21 @@ public class TempTableCreator { return tempTableName; } - private static void defineColumns(final StringBuilder sqlStringBuilder, final String[] columnNames) { - sqlStringBuilder.append('('); - final Iterator<String> it = Arrays.stream(columnNames).iterator(); - while (it.hasNext()) { - final String columnName = it.next(); - sqlStringBuilder.append(" "); - sqlStringBuilder.append(columnName); - sqlStringBuilder.append(" varchar NOT NULL"); - if (it.hasNext()) { - sqlStringBuilder.append(","); - } - } - sqlStringBuilder.append(")"); + private static void defineColumns(final StringBuilder sqlStringBuilder, final Collection<String> columnNames) { + final String columns = columnNames.stream() + .map(columnName -> " " + columnName + " varchar NOT NULL") + .collect(Collectors.joining(",")); + sqlStringBuilder.append('(').append(columns).append(')'); } private static void insertData(final StringBuilder sqlStringBuilder, final String tempTableName, - final String[] columnNames, + final Collection<String> columnNames, final Collection<List<String>> sqlData) { final Collection<String> sqlInserts = new HashSet<>(sqlData.size()); for (final Collection<String> rowValues : sqlData) { final Collection<String> escapedValues = - rowValues.stream().map(EscapeUtils::escapeForSqlStringLiteral).collect(Collectors.toList()); + rowValues.stream().map(EscapeUtils::escapeForSqlStringLiteral).toList(); sqlInserts.add("('" + String.join("','", escapedValues) + "')"); } sqlStringBuilder.append("INSERT INTO "); diff --git a/cps-ri/src/main/java/org/onap/cps/ri/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/ri/repository/YangResourceRepository.java index 9a11592310..831766cc9a 100644 --- a/cps-ri/src/main/java/org/onap/cps/ri/repository/YangResourceRepository.java +++ b/cps-ri/src/main/java/org/onap/cps/ri/repository/YangResourceRepository.java @@ -35,11 +35,7 @@ import org.springframework.stereotype.Repository; public interface YangResourceRepository extends JpaRepository<YangResourceEntity, Integer>, YangResourceNativeRepository, SchemaSetYangResourceRepository { - List<YangResourceEntity> findAllByChecksumIn(String[] checksums); - - default List<YangResourceEntity> findAllByChecksumIn(final Collection<String> checksums) { - return findAllByChecksumIn(checksums.toArray(new String[0])); - } + List<YangResourceEntity> findAllByChecksumIn(Collection<String> checksums); @Query(value = """ SELECT DISTINCT diff --git a/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java b/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java index 597164598a..a5865be657 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java +++ b/cps-service/src/main/java/org/onap/cps/utils/YangParserHelper.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLInputFactory; @@ -181,12 +182,12 @@ public class YangParserHelper { private static Map<String, Object> getDataSchemaNodeAndIdentifiersByXpath(final String parentNodeXpath, final SchemaContext schemaContext) { - final String[] xpathNodeIdSequence = xpathToNodeIdSequence(parentNodeXpath); + final List<String> xpathNodeIdSequence = xpathToNodeIdSequence(parentNodeXpath); return findDataSchemaNodeAndIdentifiersByXpathNodeIdSequence(xpathNodeIdSequence, schemaContext.getChildNodes(), new ArrayList<>()); } - private static String[] xpathToNodeIdSequence(final String xpath) { + private static List<String> xpathToNodeIdSequence(final String xpath) { try { return CpsPathUtil.getXpathNodeIdSequence(xpath); } catch (final PathParsingException pathParsingException) { @@ -196,17 +197,16 @@ public class YangParserHelper { } private static Map<String, Object> findDataSchemaNodeAndIdentifiersByXpathNodeIdSequence( - final String[] xpathNodeIdSequence, + final List<String> xpathNodeIdSequence, final Collection<? extends DataSchemaNode> dataSchemaNodes, final Collection<QName> dataSchemaNodeIdentifiers) { - final String currentXpathNodeId = xpathNodeIdSequence[0]; + final String currentXpathNodeId = xpathNodeIdSequence.get(0); final DataSchemaNode currentDataSchemaNode = dataSchemaNodes.stream() .filter(dataSchemaNode -> currentXpathNodeId.equals(dataSchemaNode.getQName().getLocalName())) .findFirst().orElseThrow(() -> schemaNodeNotFoundException(currentXpathNodeId)); dataSchemaNodeIdentifiers.add(currentDataSchemaNode.getQName()); - if (xpathNodeIdSequence.length <= 1) { - final Map<String, Object> dataSchemaNodeAndIdentifiers = - new HashMap<>(); + if (xpathNodeIdSequence.size() <= 1) { + final Map<String, Object> dataSchemaNodeAndIdentifiers = new HashMap<>(); dataSchemaNodeAndIdentifiers.put("dataSchemaNode", currentDataSchemaNode); dataSchemaNodeAndIdentifiers.put("dataSchemaNodeIdentifiers", dataSchemaNodeIdentifiers); return dataSchemaNodeAndIdentifiers; @@ -217,13 +217,11 @@ public class YangParserHelper { ((DataNodeContainer) currentDataSchemaNode).getChildNodes(), dataSchemaNodeIdentifiers); } - throw schemaNodeNotFoundException(xpathNodeIdSequence[1]); + throw schemaNodeNotFoundException(xpathNodeIdSequence.get(1)); } - private static String[] getNextLevelXpathNodeIdSequence(final String[] xpathNodeIdSequence) { - final String[] nextXpathNodeIdSequence = new String[xpathNodeIdSequence.length - 1]; - System.arraycopy(xpathNodeIdSequence, 1, nextXpathNodeIdSequence, 0, nextXpathNodeIdSequence.length); - return nextXpathNodeIdSequence; + private static List<String> getNextLevelXpathNodeIdSequence(final List<String> xpathNodeIdSequence) { + return xpathNodeIdSequence.subList(1, xpathNodeIdSequence.size()); } private static DataValidationException schemaNodeNotFoundException(final String schemaNodeIdentifier) { |