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

pinal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 37c242755 ATLAS-4671: Basic Search : Exclude Header attributes of 
entities from the response
37c242755 is described below

commit 37c242755cdf5320c2eafce925d613061e584e6a
Author: Pinal Shah <pinal.s...@freestoneinfotech.com>
AuthorDate: Wed Sep 14 15:36:39 2022 +0530

    ATLAS-4671: Basic Search : Exclude Header attributes of entities from the 
response
    
    Signed-off-by: Pinal Shah <pinal.s...@freestoneinfotech.com>
---
 .../model/discovery/QuickSearchParameters.java     |   9 ++
 .../atlas/model/discovery/SearchParameters.java    |  14 ++-
 .../atlas/discovery/EntityDiscoveryService.java    |  27 +++++
 .../org/apache/atlas/discovery/SearchContext.java  |  38 +++++++
 .../atlas/discovery/AtlasDiscoveryServiceTest.java | 117 +++++++++++++++++++++
 .../search-parameters/combination-filters.json     |  12 +--
 .../json/search-parameters/entity-filters.json     |  13 ---
 7 files changed, 210 insertions(+), 20 deletions(-)

diff --git 
a/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
 
b/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
index 79f5aae0d..dcad83c01 100644
--- 
a/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
+++ 
b/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
@@ -50,6 +50,7 @@ public class QuickSearchParameters implements Serializable {
     private Set<String>    attributes;
     private String         sortBy;
     private SortOrder      sortOrder;
+    private boolean        excludeHeaderAttributes;
 
     /**
      * for framework use.
@@ -158,4 +159,12 @@ public class QuickSearchParameters implements Serializable 
{
     public void setSortOrder(SortOrder sortOrder) {
         this.sortOrder = sortOrder;
     }
+
+    public boolean getExcludeHeaderAttributes() {
+        return excludeHeaderAttributes;
+    }
+
+    public void setExcludeHeaderAttributes(boolean excludeHeaderAttributes) {
+        this.excludeHeaderAttributes = excludeHeaderAttributes;
+    }
 }
diff --git 
a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java 
b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
index 78fb4a48f..8e68d0e82 100644
--- a/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
+++ b/intg/src/main/java/org/apache/atlas/model/discovery/SearchParameters.java
@@ -50,6 +50,8 @@ public class SearchParameters implements Serializable {
     private boolean includeClassificationAttributes;
     private boolean includeSubTypes                 = true;
     private boolean includeSubClassifications       = true;
+    private boolean excludeHeaderAttributes         = false;
+
     private int     limit;
     private int     offset;
     private String  marker;
@@ -258,6 +260,14 @@ public class SearchParameters implements Serializable {
         this.tagFilters = tagFilters;
     }
 
+    public boolean getExcludeHeaderAttributes() {
+        return excludeHeaderAttributes;
+    }
+
+    public void setExcludeHeaderAttributes(boolean excludeHeaderAttributes) {
+        this.excludeHeaderAttributes = excludeHeaderAttributes;
+    }
+
     /**
      * Attribute values included in the results
      * @return
@@ -307,6 +317,7 @@ public class SearchParameters implements Serializable {
                 includeClassificationAttributes == 
that.includeClassificationAttributes &&
                 includeSubTypes == that.includeSubTypes &&
                 includeSubClassifications == that.includeSubClassifications &&
+                excludeHeaderAttributes == that.excludeHeaderAttributes &&
                 limit == that.limit &&
                 offset == that.offset &&
                 Objects.equals(query, that.query) &&
@@ -323,7 +334,7 @@ public class SearchParameters implements Serializable {
     @Override
     public int hashCode() {
         return Objects.hash(query, typeName, classification, termName, 
includeSubTypes, includeSubClassifications,
-                            excludeDeletedEntities, 
includeClassificationAttributes, limit, offset, entityFilters,
+                            excludeDeletedEntities, 
includeClassificationAttributes, excludeHeaderAttributes, limit, offset, 
entityFilters,
                             tagFilters, attributes, sortBy, sortOrder);
     }
 
@@ -341,6 +352,7 @@ public class SearchParameters implements Serializable {
         sb.append(", 
includeSubClassifications='").append(includeSubClassifications).append('\'');
         sb.append(", excludeDeletedEntities=").append(excludeDeletedEntities);
         sb.append(", 
includeClassificationAttributes=").append(includeClassificationAttributes);
+        sb.append(", 
excludeHeaderAttributes=").append(excludeHeaderAttributes);
         sb.append(", limit=").append(limit);
         sb.append(", offset=").append(offset);
         sb.append(", entityFilters=").append(entityFilters);
diff --git 
a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
 
b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 8fbc22fa0..4b113dbef 100644
--- 
a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ 
b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -468,6 +468,32 @@ public class EntityDiscoveryService implements 
AtlasDiscoveryService {
                 ret.setNextMarker(nextMarker);
             }
 
+            //If excludeHeaderAttributes is true, only primitive attributes 
requested in 'attributes' field will be sent in the response
+            Set<String> attributes = searchParameters.getAttributes();
+            if (searchContext.excludeHeaderAttributes()) {
+
+                AtlasSearchResult.AttributeSearchResult attributeSearchResult 
= new AtlasSearchResult.AttributeSearchResult();
+                attributeSearchResult.setName(new ArrayList<>(attributes));
+
+                Collection<List<Object>> values = new ArrayList<>();
+                for (AtlasVertex vertex : resultList) {
+                    List<Object> row = new ArrayList<>();
+
+                    for (String attrName : attributes) {
+                        AtlasEntityType entityType = 
searchContext.getEntityTypes().iterator().next();
+                        AtlasAttribute  attribute  = 
entityType.getAttribute(attrName);
+                        Object value               = 
vertex.getProperty(attribute.getVertexPropertyName(), Object.class);
+
+                        row.add(value != null ? value : StringUtils.EMPTY);
+                    }
+                    values.add(row);
+                }
+                attributeSearchResult.setValues(new ArrayList<>(values));
+
+                ret.setAttributes(attributeSearchResult);
+                return ret;
+            }
+
             // By default any attribute that shows up in the search parameter 
should be sent back in the response
             // If additional values are requested then the entityAttributes 
will be a superset of the all search attributes
             // and the explicitly requested attribute(s)
@@ -922,6 +948,7 @@ public class EntityDiscoveryService implements 
AtlasDiscoveryService {
         searchParameters.setAttributes(quickSearchParameters.getAttributes());
         searchParameters.setSortBy(quickSearchParameters.getSortBy());
         searchParameters.setSortOrder(quickSearchParameters.getSortOrder());
+        
searchParameters.setExcludeHeaderAttributes(quickSearchParameters.getExcludeHeaderAttributes());
 
         return searchParameters;
     }
diff --git 
a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java 
b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
index 01954d07e..b8976e079 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
@@ -32,10 +32,13 @@ import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
+import org.apache.atlas.type.AtlasArrayType;
+import org.apache.atlas.type.AtlasBuiltInTypes;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
+import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.util.AtlasRepositoryConfiguration;
 import org.apache.commons.collections.CollectionUtils;
@@ -86,6 +89,7 @@ public class SearchContext {
     private boolean                       terminateSearch = false;
     private SearchProcessor               searchProcessor;
     private Integer                       marker;
+    private boolean                       hasRelationshipAttributes = false;
 
     public final static AtlasClassificationType 
MATCH_ALL_WILDCARD_CLASSIFICATION = new AtlasClassificationType(new 
AtlasClassificationDef(WILDCARD_CLASSIFICATIONS));
     public final static AtlasClassificationType MATCH_ALL_CLASSIFIED           
   = new AtlasClassificationType(new 
AtlasClassificationDef(ALL_CLASSIFICATIONS));
@@ -146,6 +150,9 @@ public class SearchContext {
         //remove other types if builtin type is present
         filterStructTypes();
 
+        //validate 'attributes' field
+        validateAttributes();
+
         //gather all classifications and its corresponding subtypes
         Set<String> classificationTypeAndSubTypes  = new HashSet<>();
         String classificationTypeAndSubTypesQryStr = null;
@@ -345,6 +352,37 @@ public class SearchContext {
         }
     }
 
+    private void validateAttributes() throws AtlasBaseException {
+        Set<String> attributes = searchParameters.getAttributes();
+        if (CollectionUtils.isNotEmpty(attributes) && 
CollectionUtils.isNotEmpty(entityTypes)) {
+
+            AtlasEntityType entityType = entityTypes.iterator().next();
+            for (String attr : attributes) {
+                AtlasAttribute attribute = entityType.getAttribute(attr);
+
+                if (attribute == null) {
+                    attribute = entityType.getRelationshipAttribute(attr, 
null);
+                    hasRelationshipAttributes = attribute != null;
+                }
+
+                if (attribute == null) {
+                    throw new 
AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attr, 
entityType.getTypeName());
+                }
+            }
+        }
+    }
+
+    public boolean excludeHeaderAttributes() {
+        if (CollectionUtils.isNotEmpty(entityTypes) &&
+                searchParameters.getExcludeHeaderAttributes() &&
+                CollectionUtils.isNotEmpty(searchParameters.getAttributes()) &&
+                !hasRelationshipAttributes){
+            return true;
+        }
+
+        return false;
+    }
+
     public boolean hasAttributeFilter(FilterCriteria filterCriteria) {
         return filterCriteria != null &&
                (CollectionUtils.isNotEmpty(filterCriteria.getCriterion()) || 
StringUtils.isNotEmpty(filterCriteria.getAttributeName()));
diff --git 
a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
 
b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
index fbc739652..ecb398a44 100644
--- 
a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
@@ -31,6 +31,7 @@ import org.apache.atlas.model.discovery.AtlasAggregationEntry;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.repository.graph.AtlasGraphProvider;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
@@ -42,6 +43,7 @@ import org.testng.annotations.*;
 import javax.inject.Inject;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -929,6 +931,109 @@ public class AtlasDiscoveryServiceTest extends 
BasicTestSetup {
         
Assert.assertTrue(list.get(0).getDisplayText().equalsIgnoreCase("time_id"));
     }
 
+    //test excludeHeaderAttributes
+    @Test
+    public void excludeHeaderAttributesStringAttr() throws AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE);
+        params.setExcludeHeaderAttributes(true);
+        SearchParameters.FilterCriteria filterCriteria = 
getSingleFilterCondition("tableType", Operator.EQ, "Managed");
+        params.setEntityFilters(filterCriteria);
+        params.setSortBy("name");
+        params.setAttributes(new HashSet<String>() {{ add("name");}});
+        params.setLimit(1);
+
+        AtlasSearchResult searchResult = 
discoveryService.searchWithParameters(params);
+        AtlasSearchResult.AttributeSearchResult expected = new 
AtlasSearchResult.AttributeSearchResult();
+        expected.setName(Arrays.asList("name"));
+        expected.setValues(Arrays.asList(Arrays.asList("log_fact_daily_mv")));
+        assertSearchResult(searchResult,expected);
+    }
+
+    @Test
+    public void excludeHeaderAttributesRelationAttr() throws 
AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE);
+        params.setExcludeHeaderAttributes(true);
+        SearchParameters.FilterCriteria filterCriteria = 
getSingleFilterCondition("name", Operator.EQ, "time_dim");
+        params.setEntityFilters(filterCriteria);
+        params.setAttributes(new HashSet<String>() {{ add("name"); 
add("db");}});
+        params.setLimit(1);
+
+        AtlasSearchResult searchResult = 
discoveryService.searchWithParameters(params);
+
+        assertNotNull(searchResult);
+        assertNotNull(searchResult.getEntities());
+        assertNotNull(searchResult.getReferredEntities());
+    }
+
+    @Test
+    public void excludeHeaderAttributesSystemAttr() throws AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE);
+        params.setExcludeHeaderAttributes(true);
+        params.setAttributes(new HashSet<String>() {{ add("name"); 
add("__state");}});
+        params.setLimit(1);
+        SearchParameters.FilterCriteria filterCriteria = 
getSingleFilterCondition("tableType", Operator.EQ, "Managed");
+        params.setEntityFilters(filterCriteria);
+        params.setSortBy("name");
+
+        AtlasSearchResult searchResult = 
discoveryService.searchWithParameters(params);
+        AtlasSearchResult.AttributeSearchResult expected = new 
AtlasSearchResult.AttributeSearchResult();
+        expected.setName(Arrays.asList("name","__state"));
+        
expected.setValues(Arrays.asList(Arrays.asList("log_fact_daily_mv","ACTIVE")));
+        assertSearchResult(searchResult,expected);
+    }
+
+    @Test
+    public void excludeHeaderAttributesAllEntityTypeSysAttr() throws 
AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE+","+ALL_ENTITY_TYPES);
+        params.setExcludeHeaderAttributes(true);
+        params.setAttributes(new HashSet<String>() {{ add("__state");}});
+        params.setLimit(2);
+
+        AtlasSearchResult searchResult = 
discoveryService.searchWithParameters(params);
+        AtlasSearchResult.AttributeSearchResult expected = new 
AtlasSearchResult.AttributeSearchResult();
+        expected.setName(Arrays.asList("__state"));
+        expected.setValues(Arrays.asList(Arrays.asList("ACTIVE"), 
Arrays.asList("ACTIVE")));
+        assertSearchResult(searchResult,expected);
+    }
+    @Test
+    public void excludeHeaderAttributesAllEntityTypeSysAttrs() throws 
AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE+","+ALL_ENTITY_TYPES);
+        params.setExcludeHeaderAttributes(true);
+        params.setAttributes(new HashSet<String>() {{ add("__state"); 
add("__guid");}});
+        params.setLimit(2);
+
+        AtlasSearchResult searchResult = 
discoveryService.searchWithParameters(params);
+        assertEquals(searchResult.getAttributes().getValues().size(), 2);
+    }
+
+    @Test(expectedExceptions = AtlasBaseException.class, 
expectedExceptionsMessageRegExp = "Attribute name not found for type 
__ENTITY_ROOT")
+    public void excludeHeaderAttributesAllEntityType() throws 
AtlasBaseException {
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE+","+ALL_ENTITY_TYPES);
+        params.setExcludeHeaderAttributes(true);
+        params.setAttributes(new HashSet<String>() {{ add("name");}});
+        params.setLimit(1);
+
+        discoveryService.searchWithParameters(params);
+    }
+
+    @Test(expectedExceptions = AtlasBaseException.class, 
expectedExceptionsMessageRegExp = "Attribute name1 not found for type 
hive_table")
+    public void excludeHeaderAttributesInvalidAttr() throws AtlasBaseException 
{
+        SearchParameters params = new SearchParameters();
+        params.setTypeName(HIVE_TABLE_TYPE);
+        params.setExcludeHeaderAttributes(true);
+        params.setAttributes(new HashSet<String>() {{ add("name1");}});
+        params.setLimit(1);
+
+        discoveryService.searchWithParameters(params);
+    }
+
+
     private String gethiveTableSalesFactGuid() throws AtlasBaseException {
         if (salesFactGuid == null) {
             SearchParameters params = new SearchParameters();
@@ -958,6 +1063,18 @@ public class AtlasDiscoveryServiceTest extends 
BasicTestSetup {
         }
     }
 
+    private void assertSearchResult(AtlasSearchResult searchResult, 
AtlasSearchResult.AttributeSearchResult expected) {
+        assertNotNull(searchResult);
+        AtlasSearchResult.AttributeSearchResult result = 
searchResult.getAttributes();
+        assertNotNull(result);
+        assertTrue(result.getName().containsAll(expected.getName()));
+        int i = 0;
+        for (List<Object> value : result.getValues()) {
+            assertTrue(value.containsAll(expected.getValues().get(i)));
+            i++;
+        }
+    }
+
     private void assertAggregationMetrics(AtlasQuickSearchResult searchResult) 
{
         Map<String, List<AtlasAggregationEntry>> agg =  
searchResult.getAggregationMetrics();
         Assert.assertTrue(CollectionUtils.isNotEmpty(agg.get("__typeName")));
diff --git 
a/webapp/src/test/resources/json/search-parameters/combination-filters.json 
b/webapp/src/test/resources/json/search-parameters/combination-filters.json
index dc52d33d1..f65e2bae3 100644
--- a/webapp/src/test/resources/json/search-parameters/combination-filters.json
+++ b/webapp/src/test/resources/json/search-parameters/combination-filters.json
@@ -10,7 +10,7 @@
       "offset": 0,
       "entityFilters": null,
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 1
   },
@@ -25,7 +25,7 @@
       "offset": 0,
       "entityFilters": null,
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 0
   },
@@ -129,7 +129,7 @@
         ]
       },
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 1
   },
@@ -144,7 +144,7 @@
       "offset": 0,
       "entityFilters": null,
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 1
   },
@@ -159,7 +159,7 @@
       "offset": 0,
       "entityFilters": null,
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 3
   },
@@ -178,7 +178,7 @@
         "attributeValue" : "+"
       },
       "tagFilters": null,
-      "attributes": [""]
+      "attributes": []
     },
     "expectedCount": 1
   }
diff --git 
a/webapp/src/test/resources/json/search-parameters/entity-filters.json 
b/webapp/src/test/resources/json/search-parameters/entity-filters.json
index 93d2d7d36..255ed8adb 100644
--- a/webapp/src/test/resources/json/search-parameters/entity-filters.json
+++ b/webapp/src/test/resources/json/search-parameters/entity-filters.json
@@ -15,7 +15,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -38,7 +37,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -59,7 +57,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 2
@@ -81,7 +78,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 1
@@ -113,7 +109,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -145,7 +140,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -177,7 +171,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -199,7 +192,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -231,7 +223,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 1
@@ -263,7 +254,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 18
@@ -295,7 +285,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -327,7 +316,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3
@@ -359,7 +347,6 @@
       },
       "tagFilters": null,
       "attributes": [
-        ""
       ]
     },
     "expectedCount": 3

Reply via email to