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

[atlas] branch branch-2.0 updated (e3d4cf0 -> bacdfcf)

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

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


    from e3d4cf0  ATLAS-3457: Support Multi-Classification search without attributes
     new b86ce7c  ATLAS-3533: search with term and tag doesn't return right results
     new bacdfcf  ATLAS-3541: updated datatype for system attributes, timestamp and modifiedTimestamp, from long to date

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/atlas/type/AtlasClassificationType.java |   5 +-
 .../org/apache/atlas/type/AtlasEntityType.java     |   5 +-
 .../test/java/org/apache/atlas/TestUtilsV2.java    |   2 +-
 .../discovery/ClassificationSearchProcessor.java   |  21 +++-
 .../atlas/discovery/EntitySearchProcessor.java     |  12 +--
 .../org/apache/atlas/discovery/SearchContext.java  |   2 +-
 .../apache/atlas/discovery/SearchProcessor.java    |  21 ++++
 .../impexp/ZipFileResourceTestUtils.java           |   2 +-
 .../atlas/web/adapters/TestEntitiesREST.java       | 110 ++++++++++++++++++++-
 9 files changed, 156 insertions(+), 24 deletions(-)


[atlas] 02/02: ATLAS-3541: updated datatype for system attributes, timestamp and modifiedTimestamp, from long to date

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bacdfcfdb254b97c49e069d6c2f534194b865554
Author: Le Ma <lm...@cloudera.com>
AuthorDate: Wed Nov 27 15:43:34 2019 -0800

    ATLAS-3541: updated datatype for system attributes, timestamp and modifiedTimestamp, from long to date
    
    Signed-off-by: Madhan Neethiraj <ma...@apache.org>
    (cherry picked from commit af203374232bc1ba6f7c42731619416b40b1db1c)
---
 .../src/main/java/org/apache/atlas/type/AtlasClassificationType.java | 5 +++--
 intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java        | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
index 1b95df8..1518bbc 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
@@ -17,6 +17,7 @@
  */
 package org.apache.atlas.type;
 
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_DATE;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_LONG;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
 import static org.apache.atlas.type.Constants.CREATED_BY_KEY;
@@ -505,8 +506,8 @@ public class AtlasClassificationType extends AtlasStructType {
     private static AtlasClassificationType initRootClassificationType() {
         List<AtlasAttributeDef> attributeDefs = new ArrayList<AtlasAttributeDef>() {{
             add(new AtlasAttributeDef(TYPE_NAME_PROPERTY_KEY, AtlasBaseTypeDef.ATLAS_TYPE_STRING, false, true));
-            add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
-            add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
+            add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_DATE, false, true));
+            add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_DATE, false, true));
             add(new AtlasAttributeDef(MODIFIED_BY_KEY, ATLAS_TYPE_STRING, false, true));
             add(new AtlasAttributeDef(CREATED_BY_KEY, ATLAS_TYPE_STRING, false, true));
             add(new AtlasAttributeDef(STATE_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index 6665157..928ac0d 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -17,6 +17,7 @@
  */
 package org.apache.atlas.type;
 
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_DATE;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_INT;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_LONG;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
@@ -627,8 +628,8 @@ public class AtlasEntityType extends AtlasStructType {
 
     private static AtlasEntityType initRootEntityType() {
         List<AtlasAttributeDef> attributeDefs = new ArrayList<AtlasAttributeDef>() {{
-            add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
-            add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
+            add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_DATE, false, true));
+            add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_DATE, false, true));
             add(new AtlasAttributeDef(MODIFIED_BY_KEY, ATLAS_TYPE_STRING, false, true));
             add(new AtlasAttributeDef(CREATED_BY_KEY, ATLAS_TYPE_STRING, false, true));
             add(new AtlasAttributeDef(STATE_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));


[atlas] 01/02: ATLAS-3533: search with term and tag doesn't return right results

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b86ce7c59f344e12290b62587eb684701a37c034
Author: Le Ma <lm...@cloudera.com>
AuthorDate: Mon Nov 25 11:54:29 2019 -0800

    ATLAS-3533: search with term and tag doesn't return right results
    
    Signed-off-by: Madhan Neethiraj <ma...@apache.org>
    (cherry picked from commit d0c1b30c05a587839015db1c3ff1dafc959294fd)
---
 .../test/java/org/apache/atlas/TestUtilsV2.java    |   2 +-
 .../discovery/ClassificationSearchProcessor.java   |  21 +++-
 .../atlas/discovery/EntitySearchProcessor.java     |  12 +--
 .../org/apache/atlas/discovery/SearchContext.java  |   2 +-
 .../apache/atlas/discovery/SearchProcessor.java    |  21 ++++
 .../impexp/ZipFileResourceTestUtils.java           |   2 +-
 .../atlas/web/adapters/TestEntitiesREST.java       | 110 ++++++++++++++++++++-
 7 files changed, 150 insertions(+), 20 deletions(-)

diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index ff79994..6fe5063 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -548,7 +548,7 @@ public final class TestUtilsV2 {
 
     public static final String PII = "PII";
     public static final String PHI = "PHI";
-    public static final String SUPER_TYPE_NAME = "Base";
+    public static final String SUPER_TYPE_NAME = "Referenceable";
     public static final String STORAGE_DESC_TYPE = "hive_storagedesc";
     public static final String PARTITION_STRUCT_TYPE = "partition_struct_type";
     public static final String PARTITION_CLASS_TYPE = "partition_class_type";
diff --git a/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
index 63880f9..c0a5a46 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
@@ -69,13 +69,14 @@ public class ClassificationSearchProcessor extends SearchProcessor {
     private final AtlasGraphQuery        tagGraphQueryWithAttributes;
     private final Map<String, Object>    gremlinQueryBindings;
     private final String                 gremlinTagFilterQuery;
+    private final Predicate              traitPredicate;
 
     // Some index engines may take space as a delimiter, when basic search is
     // executed, unsatisfying results may be returned.
     // eg, an entity A has classification "cls" and B has "cls 1"
     // when user execute a exact search for "cls", only A should be returned
     // but both A and B are returned. To avoid this, we should filter the res.
-    private boolean whiteSpaceFilter = false;
+    private boolean   whiteSpaceFilter = false;
 
     public ClassificationSearchProcessor(SearchContext context) {
         super(context);
@@ -146,8 +147,13 @@ public class ClassificationSearchProcessor extends SearchProcessor {
             indexQuery              = graph.indexQuery(Constants.VERTEX_INDEX, indexQueryString);
 
             LOG.debug("Using query string  '{}'.", indexQuery);
+
+            traitPredicate    = buildTraitPredict(classificationType);
+            inMemoryPredicate = inMemoryPredicate == null ? traitPredicate : PredicateUtils.andPredicate(inMemoryPredicate, traitPredicate);
+
         } else {
-            indexQuery = null;
+            indexQuery     = null;
+            traitPredicate = null;
         }
 
         // index query directly on classification
@@ -165,12 +171,15 @@ public class ClassificationSearchProcessor extends SearchProcessor {
             indexQueryString = STRAY_ELIPSIS_PATTERN.matcher(indexQueryString).replaceAll("");
 
             Predicate typeNamePredicate  = isClassificationRootType() ? null : SearchPredicateUtil.getINPredicateGenerator().generatePredicate(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
+
+            if (typeNamePredicate != null) {
+                inMemoryPredicate = inMemoryPredicate == null ? typeNamePredicate : PredicateUtils.andPredicate(inMemoryPredicate, typeNamePredicate);
+            }
+
             Predicate attributePredicate = constructInMemoryPredicate(classificationType, filterCriteria, indexAttributes);
 
             if (attributePredicate != null) {
-                inMemoryPredicate = typeNamePredicate == null ? attributePredicate : PredicateUtils.andPredicate(typeNamePredicate, attributePredicate);
-            } else {
-                inMemoryPredicate = typeNamePredicate;
+                inMemoryPredicate = inMemoryPredicate == null ? attributePredicate : PredicateUtils.andPredicate(inMemoryPredicate, attributePredicate);
             }
 
             this.classificationIndexQuery = graph.indexQuery(Constants.VERTEX_INDEX, indexQueryString);
@@ -360,6 +369,8 @@ public class ClassificationSearchProcessor extends SearchProcessor {
                     LOG.warn(e.getMessage(), e);
                 }
             }
+        } else if (traitPredicate != null) {
+            CollectionUtils.filter(entityVertices, traitPredicate);
         }
 
         super.filter(entityVertices);
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
index 93dbe87..b5606d0 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
@@ -88,20 +88,10 @@ public class EntitySearchProcessor extends SearchProcessor {
         }
 
         final Predicate typeNamePredicate;
-        final Predicate traitPredicate;
+        final Predicate traitPredicate    = buildTraitPredict(classificationType);
         final Predicate activePredicate   = SearchPredicateUtil.getEQPredicateGenerator()
                                                                .generatePredicate(Constants.STATE_PROPERTY_KEY, "ACTIVE", String.class);
 
-        if (classificationType == MATCH_ALL_WILDCARD_CLASSIFICATION || classificationType == MATCH_ALL_CLASSIFIED) {
-            traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class),
-                                                        SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, null, List.class));
-        } else if (classificationType == MATCH_ALL_NOT_CLASSIFIED) {
-            traitPredicate = PredicateUtils.andPredicate(SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class),
-                                                         SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, null, List.class));
-        } else {
-            traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, classificationTypeAndSubTypes, List.class),
-                                                        SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, classificationTypeAndSubTypes, List.class));
-        }
 
         if (!isEntityRootType()) {
             typeNamePredicate = SearchPredicateUtil.getINPredicateGenerator().generatePredicate(TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
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 ef50d8d..3534113 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
@@ -243,7 +243,7 @@ public class SearchContext {
     }
 
     boolean needClassificationProcessor() {
-        return (classificationType != null || isWildCardSearch());
+        return (classificationType != null && (entityType == null || hasAttributeFilter(searchParameters.getTagFilters()))) || isWildCardSearch() ;
     }
 
     boolean isBuiltInClassificationType() {
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 b04021f..76d5a01 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
@@ -32,6 +32,7 @@ import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.atlas.type.*;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import org.apache.atlas.util.AtlasGremlinQueryProvider;
+import org.apache.atlas.util.SearchPredicateUtil;
 import org.apache.atlas.util.SearchPredicateUtil.*;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.Predicate;
@@ -45,10 +46,15 @@ import java.math.BigInteger;
 import java.util.*;
 import java.util.regex.Pattern;
 
+import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_CLASSIFIED;
+import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_NOT_CLASSIFIED;
+import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_WILDCARD_CLASSIFICATION;
 import static org.apache.atlas.repository.Constants.CLASSIFICATION_NAMES_KEY;
 import static org.apache.atlas.repository.Constants.CUSTOM_ATTRIBUTES_PROPERTY_KEY;
 import static org.apache.atlas.repository.Constants.LABELS_PROPERTY_KEY;
 import static org.apache.atlas.repository.Constants.PROPAGATED_CLASSIFICATION_NAMES_KEY;
+import static org.apache.atlas.repository.Constants.PROPAGATED_TRAIT_NAMES_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.TRAIT_NAMES_PROPERTY_KEY;
 import static org.apache.atlas.util.SearchPredicateUtil.*;
 
 public abstract class SearchProcessor {
@@ -179,6 +185,21 @@ public abstract class SearchProcessor {
         }
     }
 
+    protected Predicate buildTraitPredict(AtlasClassificationType classificationType) {
+        Predicate traitPredicate;
+        if (classificationType == MATCH_ALL_WILDCARD_CLASSIFICATION || classificationType == MATCH_ALL_CLASSIFIED || context.isWildCardSearch()) {
+            traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class),
+                SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, null, List.class));
+        } else if (classificationType == MATCH_ALL_NOT_CLASSIFIED) {
+            traitPredicate = PredicateUtils.andPredicate(SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class),
+                SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, null, List.class));
+        } else {
+            traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, context.getClassificationTypes(), List.class),
+                SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, context.getClassificationTypes(), List.class));
+        }
+        return traitPredicate;
+    }
+
 
     protected void processSearchAttributes(AtlasStructType structType, FilterCriteria filterCriteria, Set<String> indexFiltered, Set<String> graphFiltered, Set<String> allAttributes) {
         if (structType == null || filterCriteria == null) {
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
index f4e84b2..0ffc3d5 100644
--- a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
@@ -294,7 +294,7 @@ public class ZipFileResourceTestUtils {
         createTypesAsNeeded(typesFromJson, typeDefStore, typeRegistry);
     }
 
-    private static void createTypesAsNeeded(AtlasTypesDef typesFromJson, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+    public static void createTypesAsNeeded(AtlasTypesDef typesFromJson, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         if(typesFromJson == null) {
             return;
         }
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 e2906a2..afc4c50 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
@@ -30,19 +30,26 @@ import static org.apache.atlas.repository.Constants.MODIFICATION_TIMESTAMP_PROPE
 import static org.apache.atlas.repository.Constants.STATE_PROPERTY_KEY;
 import static org.apache.atlas.repository.Constants.TIMESTAMP_PROPERTY_KEY;
 import static org.apache.atlas.repository.Constants.TYPE_NAME_PROPERTY_KEY;
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.createTypesAsNeeded;
 
 import org.apache.atlas.AtlasClient;
 import org.apache.atlas.RequestContext;
 import org.apache.atlas.TestModules;
 import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.glossary.GlossaryService;
 import org.apache.atlas.model.discovery.AtlasSearchResult;
 import org.apache.atlas.model.discovery.SearchParameters;
 import org.apache.atlas.model.discovery.SearchParameters.FilterCriteria;
+import org.apache.atlas.model.glossary.AtlasGlossary;
+import org.apache.atlas.model.glossary.AtlasGlossaryTerm;
+import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.instance.AtlasRelatedObjectId;
 import org.apache.atlas.model.instance.AtlasStruct;
 import org.apache.atlas.model.instance.ClassificationAssociateRequest;
 import org.apache.atlas.model.instance.EntityMutationResponse;
@@ -55,6 +62,7 @@ import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.atlas.web.rest.DiscoveryREST;
 import org.apache.atlas.web.rest.EntityREST;
+import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -64,6 +72,8 @@ import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
 import javax.inject.Inject;
+
+import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -81,12 +91,16 @@ public class TestEntitiesREST {
     @Inject
     private AtlasTypeRegistry typeRegistry;
     @Inject
+    private GlossaryService   glossaryService;
+    @Inject
     private AtlasTypeDefStore typeStore;
     @Inject
     private DiscoveryREST     discoveryREST;
     @Inject
     private EntityREST        entityREST;
 
+    private AtlasGlossary                     glossary;
+    private AtlasGlossaryTerm                 term1;
     private AtlasEntity                       dbEntity;
     private AtlasEntity                       tableEntity;
     private AtlasEntity                       tableEntity2;
@@ -108,8 +122,14 @@ public class TestEntitiesREST {
             }
         }
 
+        loadGlossaryType();
+
         createEntities();
 
+        createGlossary();
+
+        createTerms();
+
         initTagMap();
 
         registerEntities();
@@ -372,6 +392,33 @@ public class TestEntitiesREST {
     }
 
     @Test(dependsOnMethods = "testSearchByMultiTags")
+    public void testSearchByTerms() throws Exception {
+
+        // database - phi, felt_classification
+        // table1 - phi, classification, term: term1 | table2 - classification, term:term2
+        // column - phi
+        assignTermTo(term1, tableEntity);
+        assignTermTo(term1, tableEntity2);
+
+        searchParameters = new SearchParameters();
+        searchParameters.setTermName(term1.getName() + "@testSearchGlossary");
+        searchParameters.setClassification(CLASSIFICATION);
+
+        AtlasSearchResult res = discoveryREST.searchWithParameters(searchParameters);
+        Assert.assertNotNull(res.getEntities());
+        Assert.assertEquals(res.getEntities().size(), 2);
+
+        searchParameters.setClassification(PII);
+        res = discoveryREST.searchWithParameters(searchParameters);
+        Assert.assertNull(res.getEntities());
+
+        searchParameters.setClassification(PHI);
+        res = discoveryREST.searchWithParameters(searchParameters);
+        Assert.assertNotNull(res.getEntities());
+        Assert.assertEquals(res.getEntities().size(), 1);
+    }
+
+    @Test(dependsOnMethods = "testSearchByMultiTags")
     public void testSearchByOtherSystemAttributes() throws Exception {
 
         // database - phi, felt_classification
@@ -506,6 +553,14 @@ public class TestEntitiesREST {
         AtlasSearchResult res = discoveryREST.searchWithParameters(searchParameters);
         Assert.assertNotNull(res.getEntities());
         Assert.assertEquals(res.getEntities().size(), 1);
+
+        searchParameters = new SearchParameters();
+        searchParameters.setQuery("classification");
+        searchParameters.setClassification(PHI);
+
+        res = discoveryREST.searchWithParameters(searchParameters);
+        Assert.assertNotNull(res.getEntities());
+        Assert.assertEquals(res.getEntities().size(), 1);
     }
 
     @Test(dependsOnMethods = "testSearchBySystemAttributesWithQuery")
@@ -536,7 +591,7 @@ public class TestEntitiesREST {
         AtlasSearchResult res = discoveryREST.searchWithParameters(searchParameters);
 
         Assert.assertNotNull(res.getEntities());
-        Assert.assertEquals(res.getEntities().size(), 5);
+        Assert.assertEquals(res.getEntities().size(), 7);
     }
 
     @Test(dependsOnMethods = "testTagSearchBySystemAttributes")
@@ -582,6 +637,59 @@ public class TestEntitiesREST {
 	*
 	*/
 
+    private void loadGlossaryType() throws IOException, AtlasBaseException {
+
+        registerAtlasTypesDef("/addons/models/0000-Area0/0010-base_model.json");
+        registerAtlasTypesDef("/addons/models/0000-Area0/0011-glossary_model.json");
+    }
+
+    private void registerAtlasTypesDef (String path) throws IOException, AtlasBaseException {
+        String projectBaseDirectory = System.getProperty("projectBaseDir");
+
+        String baseModel = projectBaseDirectory + path;
+        File f = new File(baseModel);
+        String s = FileUtils.readFileToString(f);
+        createTypesAsNeeded(AtlasType.fromJson(s, AtlasTypesDef.class), typeStore, typeRegistry);
+    }
+
+	   private void createGlossary() throws AtlasBaseException {
+        glossary = new AtlasGlossary();
+        glossary.setQualifiedName("testSearchGlossary");
+        glossary.setName("Search glossary");
+        glossary.setShortDescription("Short description");
+        glossary.setLongDescription("Long description");
+        glossary.setUsage("N/A");
+        glossary.setLanguage("en-US");
+
+        AtlasGlossary created = glossaryService.createGlossary(glossary);
+        glossary.setGuid(created.getGuid());
+    }
+
+	   private void assignTermTo(AtlasGlossaryTerm term, AtlasEntity entity) throws AtlasBaseException {
+        AtlasRelatedObjectId relatedObjectId = new AtlasRelatedObjectId();
+        relatedObjectId.setGuid(entity.getGuid());
+        relatedObjectId.setTypeName(entity.getTypeName());
+
+        glossaryService.assignTermToEntities(term.getGuid(), Arrays.asList(relatedObjectId));
+    }
+
+    private void createTerms() throws AtlasBaseException {
+        term1 = new AtlasGlossaryTerm();
+        // Glossary anchor
+        AtlasGlossaryHeader glossaryId = new AtlasGlossaryHeader();
+        glossaryId.setGlossaryGuid(glossary.getGuid());
+
+        term1.setName("term1");
+        term1.setShortDescription("Short description");
+        term1.setLongDescription("Long description");
+        term1.setAbbreviation("CHK");
+        term1.setExamples(Arrays.asList("Personal", "Joint"));
+        term1.setUsage("N/A");
+        term1.setAnchor(glossaryId);
+	       AtlasGlossaryTerm created1 = glossaryService.createTerm(term1);
+	       term1.setGuid(created1.getGuid());
+    }
+
     private void createEntities() {
         dbEntity     = TestUtilsV2.createDBEntity();
         tableEntity  = TestUtilsV2.createTableEntity(dbEntity);