Repository: atlas Updated Branches: refs/heads/0.8-incubating b8255d418 -> 0183beca0
ATLAS-1988: Implement REST API to search for related entities - Add excludeDeletedEntities flag Project: http://git-wip-us.apache.org/repos/asf/atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/0183beca Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/0183beca Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/0183beca Branch: refs/heads/0.8-incubating Commit: 0183beca085b95de4e8a24da85bae843011ce732 Parents: b8255d4 Author: Sarath Subramanian <ssubraman...@hortonworks.com> Authored: Thu Aug 17 13:51:28 2017 -0700 Committer: Sarath Subramanian <ssubraman...@hortonworks.com> Committed: Thu Aug 17 13:51:28 2017 -0700 ---------------------------------------------------------------------- .../main/java/org/apache/atlas/AtlasClient.java | 1 + .../atlas/discovery/AtlasDiscoveryService.java | 3 +- .../atlas/discovery/EntityDiscoveryService.java | 61 ++++++++++++-------- .../store/graph/v1/EntityGraphRetriever.java | 2 + .../atlas/util/AtlasGremlin2QueryProvider.java | 8 +-- .../apache/atlas/web/rest/DiscoveryREST.java | 17 +++--- 6 files changed, 54 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/client/src/main/java/org/apache/atlas/AtlasClient.java ---------------------------------------------------------------------- diff --git a/client/src/main/java/org/apache/atlas/AtlasClient.java b/client/src/main/java/org/apache/atlas/AtlasClient.java index c50f3f5..5fa5df7 100755 --- a/client/src/main/java/org/apache/atlas/AtlasClient.java +++ b/client/src/main/java/org/apache/atlas/AtlasClient.java @@ -101,6 +101,7 @@ public class AtlasClient extends AtlasBaseClient { public static final String NAME = "name"; public static final String DESCRIPTION = "description"; public static final String OWNER = "owner"; + public static final String CREATE_TIME = "createTime"; public static final String INFRASTRUCTURE_SUPER_TYPE = "Infrastructure"; public static final String DATA_SET_SUPER_TYPE = "DataSet"; http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java index ead5d3c..8196a67 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java +++ b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java @@ -73,9 +73,10 @@ public interface AtlasDiscoveryService { * @param relation relation name. * @param sortByAttribute sort the result using this attribute name, default value is 'name' * @param sortOrder sorting order + * @param excludeDeletedEntities exclude deleted entities in search result. * @param limit number of resultant rows (for pagination). [ limit > 0 ] and [ limit < maxlimit ]. -1 maps to atlas.search.defaultlimit property. * @param offset offset to the results returned (for pagination). [ offset >= 0 ]. -1 maps to offset 0. * @return AtlasSearchResult */ - AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttribute, SortOrder sortOrder, int limit, int offset) throws AtlasBaseException; + AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttribute, SortOrder sortOrder, boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException; } http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java ---------------------------------------------------------------------- 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 d5062a7..1e68835 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java +++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java @@ -76,14 +76,19 @@ import java.util.*; import static org.apache.atlas.AtlasErrorCode.CLASSIFICATION_NOT_FOUND; import static org.apache.atlas.AtlasErrorCode.DISCOVERY_QUERY_FAILED; import static org.apache.atlas.AtlasErrorCode.UNKNOWN_TYPENAME; +import static org.apache.atlas.SortOrder.ASCENDING; import static org.apache.atlas.SortOrder.DESCENDING; import static org.apache.atlas.model.TypeCategory.ARRAY; import static org.apache.atlas.model.TypeCategory.MAP; import static org.apache.atlas.model.TypeCategory.OBJECT_ID_TYPE; +import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE; +import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED; import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX; +import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.BASIC_SEARCH_STATE_FILTER; import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH; import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_DESCENDING_SORT; import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.RELATIONSHIP_SEARCH_ASCENDING_SORT; +import static org.apache.atlas.util.AtlasGremlinQueryProvider.AtlasGremlinQuery.TO_RANGE_LIST; @Component public class EntityDiscoveryService implements AtlasDiscoveryService { @@ -364,9 +369,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { } if (excludeDeletedEntities) { - bindings.put("state", Status.ACTIVE.toString()); + bindings.put("state", ACTIVE.toString()); - basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.BASIC_SEARCH_STATE_FILTER); + basicQuery += gremlinQueryProvider.getQuery(BASIC_SEARCH_STATE_FILTER); } if (isGuidPrefixSearch) { @@ -378,7 +383,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { bindings.put("startIdx", params.offset()); bindings.put("endIdx", params.offset() + params.limit()); - basicQuery += gremlinQueryProvider.getQuery(AtlasGremlinQuery.TO_RANGE_LIST); + basicQuery += gremlinQueryProvider.getQuery(TO_RANGE_LIST); ScriptEngine scriptEngine = graph.getGremlinScriptEngine(); @@ -504,8 +509,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { @Override @GraphTransaction - public AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttributeName, - SortOrder sortOrder, int limit, int offset) throws AtlasBaseException { + public AtlasSearchResult searchRelatedEntities(String guid, String relation, String sortByAttributeName, SortOrder sortOrder, + boolean excludeDeletedEntities, int limit, int offset) throws AtlasBaseException { AtlasSearchResult ret = new AtlasSearchResult(AtlasQueryType.RELATIONSHIP); if (StringUtils.isEmpty(guid) || StringUtils.isEmpty(relation)) { @@ -543,21 +548,37 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { sortByAttributeName = sortByAttribute.getQualifiedName(); if (sortOrder == null) { - sortOrder = SortOrder.ASCENDING; + sortOrder = ASCENDING; } } - String relatedEntitiesQuery = getRelatedEntitiesQuery(sortOrder); + QueryParams params = validateSearchParams(limit, offset); ScriptEngine scriptEngine = graph.getGremlinScriptEngine(); Bindings bindings = scriptEngine.createBindings(); - QueryParams params = validateSearchParams(limit, offset); + Set<String> states = getEntityStates(); + String relatedEntitiesQuery = gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH); + + if (excludeDeletedEntities) { + states.remove(DELETED.toString()); + } + + if (sortOrder == ASCENDING) { + relatedEntitiesQuery += gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH_ASCENDING_SORT); + bindings.put("sortAttributeName", sortByAttributeName); + + } else if (sortOrder == DESCENDING) { + relatedEntitiesQuery += gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH_DESCENDING_SORT); + bindings.put("sortAttributeName", sortByAttributeName); + } + + relatedEntitiesQuery += gremlinQueryProvider.getQuery(TO_RANGE_LIST); bindings.put("g", graph); bindings.put("guid", guid); bindings.put("relation", relation); - bindings.put("sortAttributeName", sortByAttributeName); - bindings.put("offset", params.offset()); - bindings.put("limit", params.offset() + params.limit()); + bindings.put("states", Collections.unmodifiableSet(states)); + bindings.put("startIdx", params.offset()); + bindings.put("endIdx", params.offset() + params.limit()); try { Object result = graph.executeGremlinScript(scriptEngine, bindings, relatedEntitiesQuery, false); @@ -725,7 +746,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { } private boolean skipDeletedEntities(boolean excludeDeletedEntities, AtlasVertex<?, ?> vertex) { - return excludeDeletedEntities && GraphHelper.getStatus(vertex) == Status.DELETED; + return excludeDeletedEntities && GraphHelper.getStatus(vertex) == DELETED; } private static String getClassificationFilter(AtlasTypeRegistry typeRegistry, String classificationName, int maxTypesLengthInIdxQuery) { @@ -767,17 +788,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { return ret; } - private String getRelatedEntitiesQuery(SortOrder sortOrder) { - final String ret; - - if (sortOrder == null) { - ret = gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH); - } else if (sortOrder == DESCENDING) { - ret = gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH_DESCENDING_SORT); - } else { - ret = gremlinQueryProvider.getQuery(RELATIONSHIP_SEARCH_ASCENDING_SORT); - } - - return ret; + private Set<String> getEntityStates() { + return new HashSet<>(Arrays.asList(ACTIVE.toString(), DELETED.toString())); } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java index f6c8c72..83c9c2b 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java @@ -218,11 +218,13 @@ public final class EntityGraphRetriever { Object name = getVertexAttribute(entityVertex, entityType.getAttribute(AtlasClient.NAME)); Object description = getVertexAttribute(entityVertex, entityType.getAttribute(AtlasClient.DESCRIPTION)); Object owner = getVertexAttribute(entityVertex, entityType.getAttribute(AtlasClient.OWNER)); + Object createTime = entityVertex.getProperty(Constants.TIMESTAMP_PROPERTY_KEY, Long.class); Object displayText = name != null ? name : ret.getAttribute(AtlasClient.QUALIFIED_NAME); ret.setAttribute(AtlasClient.NAME, name); ret.setAttribute(AtlasClient.DESCRIPTION, description); ret.setAttribute(AtlasClient.OWNER, owner); + ret.setAttribute(AtlasClient.CREATE_TIME, createTime); if (displayText != null) { ret.setDisplayText(displayText.toString()); http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java b/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java index 2869e88..ea4676a 100644 --- a/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java +++ b/repository/src/main/java/org/apache/atlas/util/AtlasGremlin2QueryProvider.java @@ -76,11 +76,11 @@ public class AtlasGremlin2QueryProvider extends AtlasGremlinQueryProvider { case GUID_PREFIX_FILTER: return ".filter{it.'__guid'.matches(guid)}"; case RELATIONSHIP_SEARCH: - return "g.V('__guid', guid).both(relation)[offset..<limit].toList()"; - case RELATIONSHIP_SEARCH_DESCENDING_SORT: - return "g.V('__guid', guid).both(relation)[offset..<limit].order{it.b.getProperty(sortAttributeName) <=> it.a.getProperty(sortAttributeName)}.toList()"; + return "g.V('__guid', guid).both(relation).has('__state', T.in, states)"; case RELATIONSHIP_SEARCH_ASCENDING_SORT: - return "g.V('__guid', guid).both(relation)[offset..<limit].order{it.a.getProperty(sortAttributeName) <=> it.b.getProperty(sortAttributeName)}.toList()"; + return ".order{it.a.getProperty(sortAttributeName) <=> it.b.getProperty(sortAttributeName)}"; + case RELATIONSHIP_SEARCH_DESCENDING_SORT: + return ".order{it.b.getProperty(sortAttributeName) <=> it.a.getProperty(sortAttributeName)}"; case COMPARE_LT: return ".has('%s', T.lt, %s)"; case COMPARE_LTE: http://git-wip-us.apache.org/repos/asf/atlas/blob/0183beca/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java ---------------------------------------------------------------------- diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java index 032bde8..52258e3 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java @@ -285,21 +285,22 @@ public class DiscoveryREST { @Path("relationship") @Consumes(Servlets.JSON_MEDIA_TYPE) @Produces(Servlets.JSON_MEDIA_TYPE) - public AtlasSearchResult searchRelatedEntities(@QueryParam("guid") String guid, - @QueryParam("relation") String relation, - @QueryParam("sortBy") String sortByAttribute, - @QueryParam("sortOrder") SortOrder sortOrder, - @QueryParam("limit") int limit, - @QueryParam("offset") int offset) throws AtlasBaseException { + public AtlasSearchResult searchRelatedEntities(@QueryParam("guid") String guid, + @QueryParam("relation") String relation, + @QueryParam("sortBy") String sortByAttribute, + @QueryParam("sortOrder") SortOrder sortOrder, + @QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities, + @QueryParam("limit") int limit, + @QueryParam("offset") int offset) throws AtlasBaseException { AtlasPerfTracer perf = null; try { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.relatedEntitiesSearchUsingGremlin(" + guid + - ", " + relation + ", " + sortByAttribute + ", " + sortOrder + ", " + limit + ", " + offset + ")"); + ", " + relation + ", " + sortByAttribute + ", " + sortOrder + ", " + excludeDeletedEntities + ", " + ", " + limit + ", " + offset + ")"); } - return atlasDiscoveryService.searchRelatedEntities(guid, relation, sortByAttribute, sortOrder, limit, offset); + return atlasDiscoveryService.searchRelatedEntities(guid, relation, sortByAttribute, sortOrder, excludeDeletedEntities, limit, offset); } finally { AtlasPerfTracer.log(perf); }