You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2020/01/21 05:14:09 UTC

[atlas] branch branch-2.0 updated: ATLAS-3591: Improve user-defined attributes search

This is an automated email from the ASF dual-hosted git repository.

sarath pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 86caee1  ATLAS-3591: Improve user-defined attributes search
86caee1 is described below

commit 86caee1b58718ef26db5ab7b78eeba8a1a7ff59d
Author: Sarath Subramanian <sa...@apache.org>
AuthorDate: Mon Jan 20 00:16:05 2020 -0800

    ATLAS-3591: Improve user-defined attributes search
    
    (cherry picked from commit ea653e0388aa45a1eeeb016592ca155cda8eb480)
---
 .../apache/atlas/discovery/SearchProcessor.java    | 28 +++++++++++++++++++++-
 .../atlas/web/adapters/TestEntitiesREST.java       | 20 ++++++++--------
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
index 278b97f..8c17a90 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
@@ -73,6 +73,8 @@ public abstract class SearchProcessor {
     public static final String  BRACE_OPEN_STR             = "(";
     public static final String  BRACE_CLOSE_STR            = ")";
     public static final String  ALL_TYPE_QUERY             = "[* TO *]";
+    public static final char    CUSTOM_ATTR_SEPARATOR      = '=';
+    public static final String  CUSTOM_ATTR_SEARCH_FORMAT  = "\"\\\"%s\\\":\\\"%s\\\"\"";
 
     private static final Map<SearchParameters.Operator, String>                            OPERATOR_MAP           = new HashMap<>();
     private static final Map<SearchParameters.Operator, VertexAttributePredicateGenerator> OPERATOR_PREDICATE_MAP = new HashMap<>();
@@ -493,7 +495,13 @@ public abstract class SearchProcessor {
                 String qualifiedName         = type.getQualifiedAttributeName(attrName);
                 String escapeIndexQueryValue = AtlasAttribute.escapeIndexQueryValue(attrVal);
 
-                ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue);
+                // map '__customAttributes' 'CONTAINS' operator to 'EQ' operator (solr limitation for json serialized string search)
+                // map '__customAttributes' value from 'key1=value1' to '\"key1\":\"value1\"' (escape special characters and surround with quotes)
+                if (attrName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY) && op == SearchParameters.Operator.CONTAINS) {
+                    ret = String.format(OPERATOR_MAP.get(SearchParameters.Operator.EQ), qualifiedName, getCustomAttributeIndexQueryValue(escapeIndexQueryValue));
+                } else {
+                    ret = String.format(OPERATOR_MAP.get(op), qualifiedName, escapeIndexQueryValue);
+                }
             }
         } catch (AtlasBaseException ex) {
             LOG.warn(ex.getMessage());
@@ -502,6 +510,24 @@ public abstract class SearchProcessor {
         return ret;
     }
 
+    private String getCustomAttributeIndexQueryValue(String attrValue) {
+        String ret = null;
+
+        if (StringUtils.isNotEmpty(attrValue)) {
+            int    separatorIdx = attrValue.indexOf(CUSTOM_ATTR_SEPARATOR);
+            String key          = separatorIdx != -1 ? attrValue.substring(0, separatorIdx) : null;
+            String value        = key != null ? attrValue.substring(separatorIdx + 1) : null;
+
+            if (key != null && value != null) {
+                ret = String.format(CUSTOM_ATTR_SEARCH_FORMAT, key, value);
+            } else {
+                ret = attrValue;
+            }
+        }
+
+        return ret;
+    }
+
     private Predicate toInMemoryPredicate(AtlasStructType type, String attrName, SearchParameters.Operator op, String attrVal) {
         Predicate ret = null;
 
diff --git a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
index b2c1d4a..65a9aa3 100644
--- a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
@@ -156,26 +156,26 @@ public class TestEntitiesREST {
 
     @Test
     public void testCustomAttributesSearch() throws Exception {
-
         AtlasEntity dbWithCustomAttr = new AtlasEntity(dbEntity);
-        HashMap customAttr = new HashMap<String, String>() {{
-            put("key1", "value1");
-        }};
+        Map         customAttr       = new HashMap<String, String>() {{ put("key1", "value1"); }};
+
         dbWithCustomAttr.setCustomAttributes(customAttr);
+
         AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo(dbWithCustomAttr);
-        EntityMutationResponse response = entityREST.createOrUpdate(atlasEntitiesWithExtInfo);
+        EntityMutationResponse   response                 = entityREST.createOrUpdate(atlasEntitiesWithExtInfo);
 
         Assert.assertNotNull(response.getUpdatedEntitiesByTypeName(DATABASE_TYPE));
 
         searchParameters = new SearchParameters();
         searchParameters.setTypeName("_ALL_ENTITY_TYPES");
-        SearchParameters.FilterCriteria fc = new SearchParameters.FilterCriteria();
 
-        fc.setAttributeName(CUSTOM_ATTRIBUTES_PROPERTY_KEY);
-        fc.setOperator(SearchParameters.Operator.EQ);
-        fc.setAttributeValue("\"key1:value1\"");
+        SearchParameters.FilterCriteria filter = new SearchParameters.FilterCriteria();
 
-        searchParameters.setEntityFilters(fc);
+        filter.setAttributeName(CUSTOM_ATTRIBUTES_PROPERTY_KEY);
+        filter.setOperator(SearchParameters.Operator.CONTAINS);
+        filter.setAttributeValue("key1=value1");
+
+        searchParameters.setEntityFilters(filter);
 
         AtlasSearchResult res = discoveryREST.searchWithParameters(searchParameters);