Merge "Get Node API fix for attribute values with '/'"
[cps.git] / cps-ri / src / main / java / org / onap / cps / spi / repository / FragmentRepositoryCpsPathQueryImpl.java
index 3720249..654c1c0 100644 (file)
@@ -26,29 +26,33 @@ import java.util.Map;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.Query;
+import javax.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.onap.cps.cpspath.parser.CpsPathPrefixType;
 import org.onap.cps.cpspath.parser.CpsPathQuery;
 import org.onap.cps.spi.entities.FragmentEntity;
 import org.onap.cps.utils.JsonObjectMapper;
 
 @RequiredArgsConstructor
+@Slf4j
 public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCpsPathQuery {
 
-    public static final String SIMILAR_TO_ABSOLUTE_PATH_PREFIX = "%/";
-    public static final String SIMILAR_TO_OPTIONAL_LIST_INDEX_POSTFIX = "(\\[[^/]*])?";
+    public static final String REGEX_ABSOLUTE_PATH_PREFIX = ".*\\/";
+    public static final String REGEX_OPTIONAL_LIST_INDEX_POSTFIX = "(\\[@(?!.*\\[).*?])?$";
 
     @PersistenceContext
     private EntityManager entityManager;
     private final JsonObjectMapper jsonObjectMapper;
 
     @Override
+    @Transactional
     public List<FragmentEntity> findByAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) {
-        final var sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId");
+        final StringBuilder sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId");
         final Map<String, Object> queryParameters = new HashMap<>();
         queryParameters.put("anchorId", anchorId);
-        sqlStringBuilder.append(" AND xpath SIMILAR TO :xpathRegex");
-        final String xpathRegex = getSimilarToXpathSqlRegex(cpsPathQuery);
+        sqlStringBuilder.append(" AND xpath ~ :xpathRegex");
+        final String xpathRegex = getXpathSqlRegex(cpsPathQuery);
         queryParameters.put("xpathRegex", xpathRegex);
         if (cpsPathQuery.hasLeafConditions()) {
             sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb");
@@ -57,20 +61,22 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps
         }
 
         addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters);
-        final var query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class);
+        final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class);
         setQueryParameters(query, queryParameters);
-        return query.getResultList();
+        final List<FragmentEntity> fragmentEntities = query.getResultList();
+        log.debug("Fetched {} fragment entities by anchor and cps path.", fragmentEntities.size());
+        return fragmentEntities;
     }
 
-    private static String getSimilarToXpathSqlRegex(final CpsPathQuery cpsPathQuery) {
-        final var xpathRegexBuilder = new StringBuilder();
+    private static String getXpathSqlRegex(final CpsPathQuery cpsPathQuery) {
+        final StringBuilder xpathRegexBuilder = new StringBuilder();
         if (CpsPathPrefixType.ABSOLUTE.equals(cpsPathQuery.getCpsPathPrefixType())) {
             xpathRegexBuilder.append(escapeXpath(cpsPathQuery.getXpathPrefix()));
         } else {
-            xpathRegexBuilder.append(SIMILAR_TO_ABSOLUTE_PATH_PREFIX);
+            xpathRegexBuilder.append(REGEX_ABSOLUTE_PATH_PREFIX);
             xpathRegexBuilder.append(escapeXpath(cpsPathQuery.getDescendantName()));
         }
-        xpathRegexBuilder.append(SIMILAR_TO_OPTIONAL_LIST_INDEX_POSTFIX);
+        xpathRegexBuilder.append(REGEX_OPTIONAL_LIST_INDEX_POSTFIX);
         return xpathRegexBuilder.toString();
     }
 
@@ -96,7 +102,7 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps
                 .append(" OR attributes @> jsonb_build_object(:textLeafName, json_build_array(:textValue))");
             queryParameters.put("textLeafName", cpsPathQuery.getTextFunctionConditionLeafName());
             queryParameters.put("textValue", cpsPathQuery.getTextFunctionConditionValue());
-            final var textValueAsInt = getTextValueAsInt(cpsPathQuery);
+            final Integer textValueAsInt = getTextValueAsInt(cpsPathQuery);
             if (textValueAsInt != null) {
                 sqlStringBuilder.append(" OR attributes @> jsonb_build_object(:textLeafName, :textValueAsInt)");
                 sqlStringBuilder