You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ni...@apache.org on 2020/07/24 12:03:30 UTC
[atlas] branch master updated: ATLAS-3782 : Support NOT_CONTAINS
operator in basic search
This is an automated email from the ASF dual-hosted git repository.
nixon 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 9a067d3 ATLAS-3782 : Support NOT_CONTAINS operator in basic search
9a067d3 is described below
commit 9a067d38e27fc2255647133373b952a6a64ed1a4
Author: Pinal Shah <pi...@freestoneinfotech.com>
AuthorDate: Tue Jun 30 14:53:45 2020 +0530
ATLAS-3782 : Support NOT_CONTAINS operator in basic search
Signed-off-by: nixonrodrigues <ni...@apache.org>
---
.../graphdb/janus/AtlasSolrQueryBuilder.java | 15 +-
.../discovery/ClassificationSearchProcessor.java | 104 +++----
.../apache/atlas/discovery/SearchProcessor.java | 7 +-
.../test/java/org/apache/atlas/BasicTestSetup.java | 43 ++-
.../atlas/discovery/AtlasDiscoveryServiceTest.java | 338 +++++++++++++++++++++
...java => ClassificationSearchProcessorTest.java} | 175 ++++++++---
.../atlas/discovery/EntitySearchProcessorTest.java | 59 +++-
7 files changed, 608 insertions(+), 133 deletions(-)
diff --git a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasSolrQueryBuilder.java b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasSolrQueryBuilder.java
index 6c06a3c..43114e9 100644
--- a/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasSolrQueryBuilder.java
+++ b/graphdb/janus/src/main/java/org/apache/atlas/repository/graphdb/janus/AtlasSolrQueryBuilder.java
@@ -195,11 +195,15 @@ public class AtlasSolrQueryBuilder {
if (!indexAttributes.contains(indexAttributeName)) {
StringBuilder sb = new StringBuilder();
- if (attributeName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY) && operator.equals(Operator.CONTAINS)) {
+ if (attributeName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY)) {
// CustomAttributes stores key value pairs in String format, so ideally it should be 'contains' operator to search for one pair,
// for use-case, E1 having key1=value1 and E2 having key1=value2, searching key1=value1 results both E1,E2
// surrounding inverted commas to attributeValue works
- operator = Operator.EQ;
+ if (operator.equals(Operator.CONTAINS)) {
+ operator = Operator.EQ;
+ } else if (operator.equals(Operator.NOT_CONTAINS)) {
+ operator = Operator.NEQ;
+ }
attributeValue = getIndexQueryAttributeValue(attributeValue);
}
@@ -261,6 +265,9 @@ public class AtlasSolrQueryBuilder {
case CONTAINS:
withContains(queryBuilder, indexFieldName, attributeValue);
break;
+ case NOT_CONTAINS:
+ withNotContains(queryBuilder, indexFieldName, attributeValue);
+ break;
case IS_NULL:
withIsNull(queryBuilder, indexFieldName);
break;
@@ -388,6 +395,10 @@ public class AtlasSolrQueryBuilder {
queryBuilder.append("+").append(indexFieldName).append(":*").append(attributeValue).append("* ");
}
+ private void withNotContains(StringBuilder queryBuilder, String indexFieldName, String attributeValue) {
+ queryBuilder.append("*:* -").append(indexFieldName).append(":*").append(attributeValue).append("* ");
+ }
+
private void withIsNull(StringBuilder queryBuilder, String indexFieldName) {
queryBuilder.append("-").append(indexFieldName).append(":*").append(" ");
}
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 9c72cd4..647ff9c 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
@@ -18,13 +18,12 @@
package org.apache.atlas.discovery;
import org.apache.atlas.SortOrder;
-import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.SearchParameters.FilterCriteria;
+import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.*;
import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
import org.apache.atlas.type.AtlasClassificationType;
-import org.apache.atlas.util.AtlasGremlinQueryProvider;
import org.apache.atlas.util.SearchPredicateUtil;
import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.commons.collections.CollectionUtils;
@@ -35,8 +34,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
import java.util.*;
/**
@@ -52,10 +49,9 @@ public class ClassificationSearchProcessor extends SearchProcessor {
private final AtlasIndexQuery indexQuery;
private final AtlasIndexQuery classificationIndexQuery;
private final AtlasGraphQuery tagGraphQueryWithAttributes;
- private final Map<String, Object> gremlinQueryBindings;
- private final String gremlinTagFilterQuery;
private final Predicate traitPredicate;
private final Predicate isEntityPredicate;
+ private Predicate activePredicate;
// Some index engines may take space as a delimiter, when basic search is
// executed, unsatisfying results may be returned.
@@ -107,6 +103,14 @@ public class ClassificationSearchProcessor extends SearchProcessor {
traitPredicate = buildTraitPredict(classificationTypes);
isEntityPredicate = SearchPredicateUtil.generateIsEntityVertexPredicate(context.getTypeRegistry());
+ if (context.getSearchParameters().getExcludeDeletedEntities()) {
+ activePredicate = SearchPredicateUtil.getEQPredicateGenerator()
+ .generatePredicate(Constants.STATE_PROPERTY_KEY, AtlasEntity.Status.ACTIVE.name(), String.class);
+ }
+
+ Predicate attributePredicate = null;
+ Predicate typeNamePredicate = null;
+
AtlasGraph graph = context.getGraph();
// index query directly on entity
@@ -156,19 +160,12 @@ public class ClassificationSearchProcessor extends SearchProcessor {
indexQueryString = STRAY_OR_PATTERN.matcher(indexQueryString).replaceAll(")");
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(classificationTypes, filterCriteria, indexAttributes);
+ this.classificationIndexQuery = graph.indexQuery(Constants.VERTEX_INDEX, indexQueryString);
- if (attributePredicate != null) {
- inMemoryPredicate = inMemoryPredicate == null ? attributePredicate : PredicateUtils.andPredicate(inMemoryPredicate, attributePredicate);
- }
+ typeNamePredicate = isClassificationRootType() ? null :
+ SearchPredicateUtil.getINPredicateGenerator().generatePredicate(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
+ attributePredicate = constructInMemoryPredicate(classificationTypes, filterCriteria, indexAttributes);
- this.classificationIndexQuery = graph.indexQuery(Constants.VERTEX_INDEX, indexQueryString);
} else {
classificationIndexQuery = null;
}
@@ -176,7 +173,6 @@ public class ClassificationSearchProcessor extends SearchProcessor {
// only registered classification will search with tag filters
if (useGraphSearchForClassification) {
- AtlasGremlinQueryProvider queryProvider = AtlasGremlinQueryProvider.INSTANCE;
AtlasGraphQuery query = graph.query();
if (!isClassificationRootType()) {
@@ -184,31 +180,20 @@ public class ClassificationSearchProcessor extends SearchProcessor {
}
tagGraphQueryWithAttributes = toGraphFilterQuery(classificationTypes, filterCriteria, allAttributes, query);
- gremlinQueryBindings = new HashMap<>();
- StringBuilder gremlinQuery = new StringBuilder();
- gremlinQuery.append("g.V().has('__guid', within(guids))");
- gremlinQuery.append(queryProvider.getQuery(AtlasGremlinQueryProvider.AtlasGremlinQuery.BASIC_SEARCH_CLASSIFICATION_FILTER));
- gremlinQuery.append(".as('e').filter(out()");
- gremlinQuery.append(queryProvider.getQuery(AtlasGremlinQueryProvider.AtlasGremlinQuery.BASIC_SEARCH_TYPE_FILTER));
+ typeNamePredicate = isClassificationRootType() ? null :
+ SearchPredicateUtil.getINPredicateGenerator().generatePredicate(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
+ attributePredicate = constructInMemoryPredicate(classificationTypes, filterCriteria, allAttributes);
- // constructGremlinFilterQuery(gremlinQuery, gremlinQueryBindings, context.getClassificationType(), context.getSearchParameters().getTagFilters());
-
- // After filtering on tags go back to e and output the list of entity vertices
- gremlinQuery.append(").toList()");
-
- gremlinQueryBindings.put("traitNames", typeAndSubTypes);
- gremlinQueryBindings.put("typeNames", typeAndSubTypes); // classification typeName
-
- gremlinTagFilterQuery = gremlinQuery.toString();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("gremlinTagFilterQuery={}", gremlinTagFilterQuery);
- }
} else {
tagGraphQueryWithAttributes = null;
- gremlinTagFilterQuery = null;
- gremlinQueryBindings = null;
+ }
+
+ if (typeNamePredicate != null) {
+ inMemoryPredicate = inMemoryPredicate == null ? typeNamePredicate : PredicateUtils.andPredicate(inMemoryPredicate, typeNamePredicate);
+ }
+ if (attributePredicate != null) {
+ inMemoryPredicate = inMemoryPredicate == null ? attributePredicate : PredicateUtils.andPredicate(inMemoryPredicate, attributePredicate);
}
}
@@ -274,23 +259,23 @@ public class ClassificationSearchProcessor extends SearchProcessor {
CollectionUtils.filter(entityVertices, isEntityPredicate);
} else {
- if (tagGraphQueryWithAttributes != null) {
+ if (classificationIndexQuery != null) {
- Iterator<AtlasVertex> queryResult = tagGraphQueryWithAttributes.vertices(qryOffset, limit).iterator();
+ Iterator<AtlasIndexQuery.Result> queryResult = classificationIndexQuery.vertices(qryOffset, limit);
- getVertices(queryResult, classificationVertices);
+ getVerticesFromIndexQueryResult(queryResult, classificationVertices);
isLastResultPage = classificationVertices.size() < limit;
- } else if (classificationIndexQuery != null){
+ CollectionUtils.filter(classificationVertices, inMemoryPredicate);
+ } else if (tagGraphQueryWithAttributes != null) {
- Iterator<AtlasIndexQuery.Result> queryResult = classificationIndexQuery.vertices(qryOffset, limit);
+ Iterator<AtlasVertex> queryResult = tagGraphQueryWithAttributes.vertices(qryOffset, limit).iterator();
- getVerticesFromIndexQueryResult(queryResult, classificationVertices);
+ getVertices(queryResult, classificationVertices);
isLastResultPage = classificationVertices.size() < limit;
- // Do in-memory filtering before the graph query
CollectionUtils.filter(classificationVertices, inMemoryPredicate);
}
}
@@ -322,6 +307,9 @@ public class ClassificationSearchProcessor extends SearchProcessor {
}
// Do in-memory filtering
CollectionUtils.filter(entityVertices, isEntityPredicate);
+ if (activePredicate != null) {
+ CollectionUtils.filter(entityVertices, activePredicate);
+ }
super.filter(entityVertices);
@@ -347,30 +335,8 @@ public class ClassificationSearchProcessor extends SearchProcessor {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ClassificationSearchProcessor.filter({})", entityVertices.size());
}
- //in case of classification type + graph attributes
- if (gremlinTagFilterQuery != null && gremlinQueryBindings != null) {
- // Now filter on the tag attributes
- Set<String> guids = getGuids(entityVertices);
-
- // Clear prior results
- entityVertices.clear();
-
- if (CollectionUtils.isNotEmpty(guids)) {
- gremlinQueryBindings.put("guids", guids);
- try {
- AtlasGraph graph = context.getGraph();
- ScriptEngine gremlinScriptEngine = graph.getGremlinScriptEngine();
- List<AtlasVertex> atlasVertices = (List<AtlasVertex>) graph.executeGremlinScript(gremlinScriptEngine, gremlinQueryBindings, gremlinTagFilterQuery, false);
-
- if (CollectionUtils.isNotEmpty(atlasVertices)) {
- entityVertices.addAll(atlasVertices);
- }
- } catch (AtlasBaseException | ScriptException e) {
- LOG.warn(e.getMessage(), e);
- }
- }
- } else if (inMemoryPredicate != null) {
+ if (inMemoryPredicate != null) {
//in case of classification type + index attributes
CollectionUtils.filter(entityVertices, traitPredicate);
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 c9a6053..044179d 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
@@ -464,9 +464,9 @@ public abstract class SearchProcessor {
AtlasType attributeType = structType.getAttributeType(filterCriteria.getAttributeName());
if (AtlasBaseTypeDef.ATLAS_TYPE_STRING.equals(attributeType.getTypeName())) {
- if (filterCriteria.getOperator() == SearchParameters.Operator.NEQ) {
+ if (filterCriteria.getOperator() == SearchParameters.Operator.NEQ || filterCriteria.getOperator() == SearchParameters.Operator.NOT_CONTAINS) {
if (LOG.isDebugEnabled()) {
- LOG.debug("NEQ operator found for string attribute {}, deferring to in-memory or graph query (might cause poor performance)", qualifiedName);
+ LOG.debug("{} operator found for string attribute {}, deferring to in-memory or graph query (might cause poor performance)", filterCriteria.getOperator(), qualifiedName);
}
ret = false;
@@ -633,6 +633,7 @@ public abstract class SearchProcessor {
op = SearchParameters.Operator.NOT_CONTAINS;
break;
case CONTAINS:
+ case NOT_CONTAINS:
if (attrName.equals(CUSTOM_ATTRIBUTES_PROPERTY_KEY)) {
attrVal = getCustomAttributeIndexQueryValue(attrVal, true);
}
@@ -849,6 +850,8 @@ public abstract class SearchProcessor {
case NOT_NULL:
innerQry.has(qualifiedName, AtlasGraphQuery.ComparisionOperator.NOT_EQUAL, null);
break;
+ case NOT_CONTAINS:
+ break;
default:
LOG.warn("{}: unsupported operator. Ignored", operator);
break;
diff --git a/repository/src/test/java/org/apache/atlas/BasicTestSetup.java b/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
index 8b98b39..270051f 100644
--- a/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
+++ b/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
@@ -19,10 +19,12 @@ package org.apache.atlas;
import com.google.common.collect.ImmutableList;
import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.glossary.GlossaryService;
import org.apache.atlas.model.discovery.SearchParameters;
-import org.apache.atlas.model.instance.AtlasClassification;
-import org.apache.atlas.model.instance.AtlasEntity;
-import org.apache.atlas.model.instance.AtlasObjectId;
+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.*;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.repository.store.graph.AtlasEntityStore;
import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
@@ -42,6 +44,7 @@ import static org.testng.Assert.fail;
public abstract class BasicTestSetup {
+ // Entity type //
protected static final String DATABASE_TYPE = "hive_db";
protected static final String HIVE_TABLE_TYPE = "hive_table";
private static final String COLUMN_TYPE = "hive_column";
@@ -50,6 +53,7 @@ public abstract class BasicTestSetup {
private static final String VIEW_TYPE = "hive_process";
protected static final String DATASET_SUBTYPE = "Asset";
+ //Classification type //
public static final String DIMENSION_CLASSIFICATION = "Dimension";
public static final String FACT_CLASSIFICATION = "Fact";
public static final String PII_CLASSIFICATION = "PII";
@@ -59,14 +63,21 @@ public abstract class BasicTestSetup {
public static final String LOGDATA_CLASSIFICATION = "Log Data";
public static final String DIMENSIONAL_CLASSIFICATION = "Dimensional";
+ // Glossary type //
+ public static final String SALES_GLOSSARY = "salesGlossary";
+ public static final String SALES_TERM = "salesTerm";
+
@Inject
protected AtlasTypeRegistry typeRegistry;
@Inject
protected AtlasTypeDefStore typeDefStore;
@Inject
protected AtlasEntityStore entityStore;
+ @Inject
+ protected GlossaryService glossaryService;
private boolean baseLoaded = false;
+ private EntityMutationResponse hiveEntities;
protected void setupTestData() {
loadBaseModels();
@@ -77,6 +88,7 @@ public abstract class BasicTestSetup {
private void loadBaseModels() {
try {
loadModelFromJson("0000-Area0/0010-base_model.json", typeDefStore, typeRegistry);
+ loadModelFromJson("0000-Area0/0011-glossary_model.json", typeDefStore, typeRegistry);
baseLoaded = true;
} catch (IOException | AtlasBaseException e) {
fail("Base model setup is required for test to run!");
@@ -97,7 +109,7 @@ public abstract class BasicTestSetup {
AtlasEntity.AtlasEntitiesWithExtInfo hiveTestEntities = hiveTestEntities();
try {
- entityStore.createOrUpdate(new AtlasEntityStream(hiveTestEntities), false);
+ hiveEntities = entityStore.createOrUpdate(new AtlasEntityStream(hiveTestEntities), false);
} catch (AtlasBaseException e) {
fail("Hive entities need to be created for test to run!");
}
@@ -450,12 +462,13 @@ public abstract class BasicTestSetup {
return datasetSubType;
}
- public void createDummyEntity(String name, String type, String... traitNames) throws AtlasBaseException {
+ public EntityMutationResponse createDummyEntity(String name, String type, String... traitNames) throws AtlasBaseException {
AtlasEntity entity = new AtlasEntity(type);
entity.setAttribute("name", name);
entity.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, name);
entity.setClassifications(Stream.of(traitNames).map(AtlasClassification::new).collect(Collectors.toList()));
- entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity)), false);
+ EntityMutationResponse resp = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity)), false);
+ return resp;
}
public SearchParameters.FilterCriteria getSingleFilterCondition(String attName, SearchParameters.Operator op, String attrValue) {
@@ -472,4 +485,22 @@ public abstract class BasicTestSetup {
return filterCriteria;
}
+ public void assignGlossary() throws AtlasBaseException {
+ AtlasGlossary glossary = new AtlasGlossary();
+ glossary.setName(SALES_GLOSSARY);
+ glossary = glossaryService.createGlossary(glossary);
+
+ AtlasGlossaryTerm term = new AtlasGlossaryTerm();
+ term.setAnchor(new AtlasGlossaryHeader(glossary.getGuid()));
+ term.setName(SALES_TERM);
+ term = glossaryService.createTerm(term);
+
+ List<AtlasRelatedObjectId> guids = hiveEntities.getCreatedEntities().stream().filter(e -> e.getTypeName().equals(HIVE_TABLE_TYPE))
+ .map(p -> {AtlasRelatedObjectId obj = new AtlasRelatedObjectId();
+ obj.setGuid(p.getGuid());
+ obj.setTypeName(p.getTypeName()); return obj;}).collect(Collectors.toList());
+
+ glossaryService.assignTermToEntities(term.getGuid(), guids);
+ }
+
}
diff --git a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
new file mode 100644
index 0000000..d8c1546
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
@@ -0,0 +1,338 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.discovery;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.BasicTestSetup;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.commons.collections.CollectionUtils;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.apache.atlas.model.discovery.SearchParameters.*;
+import static org.testng.Assert.assertEquals;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasDiscoveryServiceTest extends BasicTestSetup {
+
+ @Inject
+ private AtlasDiscoveryService discoveryService;
+
+ @BeforeClass
+ public void setup() throws AtlasException, AtlasBaseException {
+ ApplicationProperties.get().setProperty(ApplicationProperties.ENABLE_FREETEXT_SEARCH_CONF, true);
+ setupTestData();
+ createDimensionalTaggedEntity("sales");
+ assignGlossary();
+ }
+
+ /* TermSearchProcessor(TSP),
+ FreeTextSearchProcessor(FSP),
+ ClassificationSearchProcessor(CSP),
+ EntitySearchProcessor(ESP) */
+
+ @Test
+ public void term() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTermName(SALES_TERM+"@"+SALES_GLOSSARY);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 10);
+ }
+
+ // TSP execute and CSP,ESP filter
+ @Test
+ public void term_tag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTermName(SALES_TERM+"@"+SALES_GLOSSARY);
+ params.setClassification(METRIC_CLASSIFICATION);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ for(AtlasEntityHeader e : entityHeaders){
+ System.out.println(e.toString());
+ }
+ assertEquals(entityHeaders.size(), 4);
+ }
+
+ @Test
+ public void term_entity() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTermName(SALES_TERM+"@"+SALES_GLOSSARY);
+ params.setTypeName(HIVE_TABLE_TYPE);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 10);
+ }
+
+ @Test
+ public void term_entity_tag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTermName(SALES_TERM+"@"+SALES_GLOSSARY);
+ params.setTypeName(HIVE_TABLE_TYPE);
+ params.setClassification(DIMENSIONAL_CLASSIFICATION);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isEmpty(entityHeaders));
+ }
+
+ //FSP execute and CSP,ESP filter
+ @Test
+ public void query_ALLTag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(ALL_CLASSIFICATION_TYPES);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 5);
+ }
+
+ @Test
+ public void query_ALLTag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(ALL_CLASSIFICATION_TYPES);
+ //typeName will check for only classification name not propogated classification
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("__typeName", Operator.NOT_CONTAINS, METRIC_CLASSIFICATION);
+ params.setTagFilters(fc);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 4);
+ }
+
+ @Test
+ public void query_NOTCLASSIFIEDTag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(NO_CLASSIFICATIONS);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 1);
+ }
+
+
+ @Test
+ public void query_ALLWildcardTag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification("*");
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 5);
+ }
+
+ @Test
+ public void query_wildcardTag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification("Dimen*on");
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 2);
+ }
+
+ @Test
+ public void query_tag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(METRIC_CLASSIFICATION);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 3);
+ }
+
+ @Test
+ public void query_tag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(METRIC_CLASSIFICATION);
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("__timestamp", SearchParameters.Operator.LT, String.valueOf(System.currentTimeMillis()));
+ params.setTagFilters(fc);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 3);
+ }
+
+ @Test
+ public void query_entity() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 4);
+ }
+
+ @Test
+ public void query_entity_entityFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("tableType", Operator.NOT_NULL, "null");
+ params.setEntityFilters(fc);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 3);
+ }
+
+ @Test
+ public void query_entity_entityFilter_tag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("tableType", Operator.IS_NULL, "null");
+ params.setEntityFilters(fc);
+ params.setClassification(DIMENSIONAL_CLASSIFICATION);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 1);
+ }
+
+ @Test
+ public void query_entity_entityFilter_tag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria fcE = getSingleFilterCondition("tableType", Operator.IS_NULL, "null");
+ params.setEntityFilters(fcE);
+ params.setClassification(DIMENSIONAL_CLASSIFICATION);
+ params.setQuery("sales");
+ SearchParameters.FilterCriteria fcC = getSingleFilterCondition("attr1", Operator.EQ, "value1");
+ params.setTagFilters(fcC);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 1);
+ }
+
+ @Test
+ public void query_entity_tag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ params.setClassification(METRIC_CLASSIFICATION);
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("__timestamp", SearchParameters.Operator.LT, String.valueOf(System.currentTimeMillis()));
+ params.setTagFilters(fc);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 2);
+
+ }
+
+ @Test
+ public void query_entity_tag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ params.setClassification(METRIC_CLASSIFICATION);
+ params.setQuery("sales");
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 2);
+ }
+
+ // CSP Execute and ESP filter
+ @Test
+ public void entity_entityFilter_tag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria fcE = getSingleFilterCondition("tableType", Operator.EQ, "Managed");
+ params.setEntityFilters(fcE);
+ params.setClassification(METRIC_CLASSIFICATION);
+ SearchParameters.FilterCriteria fcC = getSingleFilterCondition("__timestamp", SearchParameters.Operator.LT, String.valueOf(System.currentTimeMillis()));
+ params.setTagFilters(fcC);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 4);
+
+ }
+
+ @Test
+ public void entity_tag_tagFilter() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ params.setClassification(METRIC_CLASSIFICATION);
+ SearchParameters.FilterCriteria fc = getSingleFilterCondition("__timestamp", SearchParameters.Operator.LT, String.valueOf(System.currentTimeMillis()));
+ params.setTagFilters(fc);
+
+ List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ assertEquals(entityHeaders.size(), 4);
+ }
+
+ private void createDimensionalTaggedEntity(String name) throws AtlasBaseException {
+ EntityMutationResponse resp = createDummyEntity(name, HIVE_TABLE_TYPE);
+ AtlasEntityHeader entityHeader = resp.getCreatedEntities().get(0);
+ String guid = entityHeader.getGuid();
+ HashMap<String,Object> attr = new HashMap<>();
+ attr.put("attr1","value1");
+ entityStore.addClassification(Arrays.asList(guid), new AtlasClassification(DIMENSIONAL_CLASSIFICATION, attr));
+ }
+
+ @AfterClass
+ public void teardown() {
+ AtlasGraphProvider.cleanup();
+ }
+}
diff --git a/repository/src/test/java/org/apache/atlas/discovery/BasicSearchClassificationTest.java b/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
similarity index 52%
rename from repository/src/test/java/org/apache/atlas/discovery/BasicSearchClassificationTest.java
rename to repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
index 9b16e91..8693459 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/BasicSearchClassificationTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
@@ -26,9 +26,15 @@ 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.EntityMutationResponse;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
+import org.apache.atlas.repository.graphdb.AtlasGraph;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
+import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.commons.collections.CollectionUtils;
import org.testng.Assert;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -37,19 +43,23 @@ import javax.inject.Inject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.stream.Collectors;
import static org.apache.atlas.model.discovery.SearchParameters.*;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
@Guice(modules = TestModules.TestOnlyModule.class)
-public class BasicSearchClassificationTest extends BasicTestSetup {
+public class ClassificationSearchProcessorTest extends BasicTestSetup {
@Inject
- private AtlasDiscoveryService discoveryService;
+ private AtlasGraph graph;
+ @Inject
+ public GraphBackedSearchIndexer indexer;
+ @Inject
+ private EntityGraphRetriever entityRetriever;
- private int totalEntities = 0;
private int totalClassifiedEntities = 0;
- private int getTotalClassifiedEntitiesHistorical = 0;
private int dimensionTagEntities = 10;
private String dimensionTagDeleteGuid;
private String dimensionalTagGuid;
@@ -65,14 +75,14 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
public void searchByALLTag() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setClassification(ALL_CLASSIFICATION_TYPES);
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
-
- Assert.assertTrue(CollectionUtils.isNotEmpty(entityHeaders));
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- totalEntities = getEntityCount();
- totalClassifiedEntities = entityHeaders.size();
- getTotalClassifiedEntitiesHistorical = getEntityWithTagCountHistorical();
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ totalClassifiedEntities = vertices.size();
}
@Test
@@ -81,10 +91,14 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
params.setClassification(ALL_CLASSIFICATION_TYPES);
FilterCriteria filterCriteria = getSingleFilterCondition("__timestamp", Operator.LT, String.valueOf(System.currentTimeMillis()));
params.setTagFilters(filterCriteria);
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), totalClassifiedEntities);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), totalClassifiedEntities);
}
@Test
@@ -95,29 +109,40 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
params.setTagFilters(filterCriteria);
params.setLimit(totalClassifiedEntities - 2);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), totalClassifiedEntities - 2);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), totalClassifiedEntities - 2);
}
- @Test
+ //@Test
public void searchByNOTCLASSIFIED() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setClassification(NO_CLASSIFICATIONS);
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), totalEntities - totalClassifiedEntities);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 20);
}
@Test
public void searchByTag() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setClassification(DIMENSION_CLASSIFICATION);
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), dimensionTagEntities);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), dimensionTagEntities);
}
@Test
@@ -126,11 +151,23 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
params.setClassification(DIMENSIONAL_CLASSIFICATION);
FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.EQ, "Test");
params.setTagFilters(filterCriteria);
-
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
-
- assertEquals(entityHeaders.size(), 1);
- assertEquals(entityHeaders.get(0).getGuid(), dimensionalTagGuid);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(dimensionalTagGuid));
}
@@ -141,35 +178,86 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
params.setClassification(DIMENSION_CLASSIFICATION);
FilterCriteria filterCriteria = getSingleFilterCondition("__timestamp", Operator.LT, String.valueOf(System.currentTimeMillis()));
params.setTagFilters(filterCriteria);
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), dimensionTagEntities);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), dimensionTagEntities);
}
@Test
public void searchByWildcardTag() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setClassification("Dimension*");
+ params.setLimit(20);
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
- assertEquals(entityHeaders.size(), dimensionTagEntities + 1);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), dimensionTagEntities + 1);
}
- //@Test
+ @Test
+ public void searchByALLWildcardTag() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification("*");
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(),20);
+
+ }
+
+ @Test
+ public void searchWithNotContains() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(DIMENSIONAL_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.NOT_CONTAINS, "Test");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isEmpty(vertices));
+ }
+
+
+ @Test
public void searchByTagAndGraphSysFilters() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setClassification(DIMENSION_CLASSIFICATION);
FilterCriteria filterCriteria = getSingleFilterCondition("__entityStatus", Operator.EQ, "DELETED");
params.setTagFilters(filterCriteria);
params.setExcludeDeletedEntities(false);
-
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
-
- assertEquals(entityHeaders.size(), 1);
- assertEquals(entityHeaders.get(0).getGuid(), dimensionTagDeleteGuid);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(dimensionTagDeleteGuid));
}
@@ -209,21 +297,8 @@ public class BasicSearchClassificationTest extends BasicTestSetup {
}
- private int getEntityCount() throws AtlasBaseException {
- SearchParameters params = new SearchParameters();
- params.setTypeName(ALL_ENTITY_TYPES);
-
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
- return entityHeaders.size();
+ @AfterClass
+ public void teardown() {
+ AtlasGraphProvider.cleanup();
}
-
- private int getEntityWithTagCountHistorical() throws AtlasBaseException {
- SearchParameters params = new SearchParameters();
- params.setClassification(ALL_CLASSIFICATION_TYPES);
- params.setExcludeDeletedEntities(false);
-
- List<AtlasEntityHeader> entityHeaders = discoveryService.searchWithParameters(params).getEntities();
- return entityHeaders.size();
- }
-
}
diff --git a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
index 8e42d17..7b40c21 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
@@ -23,11 +23,13 @@ import org.apache.atlas.SortOrder;
import org.apache.atlas.TestModules;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -60,6 +62,7 @@ public class EntitySearchProcessorTest extends BasicTestSetup {
@Inject
public GraphBackedSearchIndexer indexer;
+ private String expectedEntityName = "hive_Table_Null_tableType";
@Test
public void searchTablesByClassification() throws AtlasBaseException {
@@ -132,7 +135,6 @@ public class EntitySearchProcessorTest extends BasicTestSetup {
@Test(priority = -1)
public void searchWithNEQ_stringAttr() throws AtlasBaseException {
- String expectedEntityName = "hive_Table_Null_tableType";
createDummyEntity(expectedEntityName,HIVE_TABLE_TYPE);
SearchParameters params = new SearchParameters();
params.setTypeName(HIVE_TABLE_TYPE);
@@ -154,7 +156,7 @@ public class EntitySearchProcessorTest extends BasicTestSetup {
assertTrue(nameList.contains(expectedEntityName));
}
- @Test(dependsOnMethods = "searchWithNEQ_stringAttr")
+ @Test
public void searchWithNEQ_pipeSeperatedAttr() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setTypeName(HIVE_TABLE_TYPE);
@@ -173,10 +175,10 @@ public class EntitySearchProcessorTest extends BasicTestSetup {
nameList.add((String) entityRetriever.toAtlasEntityHeader(vertex, Collections.singleton("name")).getAttribute("name"));
}
- assertTrue(nameList.contains("hive_Table_Null_tableType"));
+ assertTrue(nameList.contains(expectedEntityName));
}
- @Test(dependsOnMethods = "searchWithNEQ_stringAttr")
+ @Test
public void searchWithNEQ_doubleAttr() throws AtlasBaseException {
SearchParameters params = new SearchParameters();
params.setTypeName(HIVE_TABLE_TYPE);
@@ -309,4 +311,53 @@ public class EntitySearchProcessorTest extends BasicTestSetup {
assertEquals(processor.execute().size(), 2);
}
+ @Test
+ public void searchWithNotContains_stringAttr() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("tableType", SearchParameters.Operator.NOT_CONTAINS, "Managed");
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 3);
+
+ List<String> nameList = new ArrayList<>();
+ for (AtlasVertex vertex : vertices) {
+ nameList.add((String) entityRetriever.toAtlasEntityHeader(vertex, Collections.singleton("name")).getAttribute("name"));
+ }
+
+ assertTrue(nameList.contains(expectedEntityName));
+ }
+
+ @Test
+ public void searchWithNotContains_pipeSeperatedAttr() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HIVE_TABLE_TYPE);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("__classificationNames", SearchParameters.Operator.NOT_CONTAINS, METRIC_CLASSIFICATION);
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 7);
+
+ List<String> nameList = new ArrayList<>();
+ for (AtlasVertex vertex : vertices) {
+ nameList.add((String) entityRetriever.toAtlasEntityHeader(vertex, Collections.singleton("name")).getAttribute("name"));
+ }
+
+ assertTrue(nameList.contains(expectedEntityName));
+ }
+
+ @AfterClass
+ public void teardown() {
+ AtlasGraphProvider.cleanup();
+ }
+
}