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 2019/07/30 09:38:52 UTC

[atlas] branch master updated: ATLAS-3319 :- Add API to get lineage by uniqueAttributes

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 620861e  ATLAS-3319 :- Add API to get lineage by uniqueAttributes
620861e is described below

commit 620861e313478faa9966fbbd89ff26b3fdd41deb
Author: shanjiaqi <sh...@qiyi.com>
AuthorDate: Thu Jul 18 20:53:50 2019 +0800

    ATLAS-3319 :- Add API to get lineage by uniqueAttributes
---
 .../main/java/org/apache/atlas/AtlasClientV2.java  |  9 +++
 .../org/apache/atlas/web/rest/LineageREST.java     | 88 +++++++++++++++++++++-
 2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/client/client-v2/src/main/java/org/apache/atlas/AtlasClientV2.java b/client/client-v2/src/main/java/org/apache/atlas/AtlasClientV2.java
index f582fbd..199d6bf 100644
--- a/client/client-v2/src/main/java/org/apache/atlas/AtlasClientV2.java
+++ b/client/client-v2/src/main/java/org/apache/atlas/AtlasClientV2.java
@@ -259,6 +259,14 @@ public class AtlasClientV2 extends AtlasBaseClient {
         return callAPI(API_V2.LINEAGE_INFO, AtlasLineageInfo.class, queryParams, guid);
     }
 
+    public AtlasLineageInfo getLineageInfo(String type, Map<String, String> attributes, final LineageDirection direction, final int depth) throws AtlasServiceException {
+        MultivaluedMap<String, String> queryParams = attributesToQueryParams(attributes);
+        queryParams.add("direction", direction.toString());
+        queryParams.add("depth", String.valueOf(depth));
+
+        return callAPI(API_V2.GET_LINEAGE_BY_ATTRIBUTES, AtlasLineageInfo.class, queryParams, type);
+    }
+
     public AtlasEntityWithExtInfo getEntityByGuid(String guid) throws AtlasServiceException {
         return getEntityByGuid(guid, false, false);
     }
@@ -552,6 +560,7 @@ public class AtlasClientV2 extends AtlasBaseClient {
         public static final API_V2 UPDATE_CLASSIFICATIONS      = new API_V2(ENTITY_API + "guid/%s/classifications", HttpMethod.PUT, Response.Status.NO_CONTENT);
         public static final API_V2 DELETE_CLASSIFICATION       = new API_V2(ENTITY_API + "guid/%s/classification/%s", HttpMethod.DELETE, Response.Status.NO_CONTENT);
         public static final API_V2 LINEAGE_INFO                = new API_V2(LINEAGE_URI, HttpMethod.GET, Response.Status.OK);
+        public static final API_V2 GET_LINEAGE_BY_ATTRIBUTES   = new API_V2(LINEAGE_URI + "uniqueAttribute/type/", HttpMethod.GET, Response.Status.OK);
         public static final API_V2 DSL_SEARCH                  = new API_V2(DSL_URI, HttpMethod.GET, Response.Status.OK);
         public static final API_V2 FULL_TEXT_SEARCH            = new API_V2(FULL_TEXT_URI, HttpMethod.GET, Response.Status.OK);
         public static final API_V2 BASIC_SEARCH                = new API_V2(BASIC_SEARCH_URI, HttpMethod.GET, Response.Status.OK);
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java
index 4210077..08c6555 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/LineageREST.java
@@ -19,12 +19,19 @@
 package org.apache.atlas.web.rest;
 
 
+import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.discovery.AtlasLineageService;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.lineage.AtlasLineageInfo;
 import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection;
+import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.utils.AtlasPerfTracer;
 import org.apache.atlas.web.util.Servlets;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.slf4j.Logger;
 import org.springframework.stereotype.Service;
 
@@ -40,6 +47,8 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * REST interface for an entity's lineage information
@@ -51,7 +60,9 @@ import javax.ws.rs.core.MediaType;
 @Produces({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
 public class LineageREST {
     private static final Logger PERF_LOG = AtlasPerfTracer.getPerfLogger("rest.LineageREST");
+    private static final String PREFIX_ATTR = "attr:";
 
+    private final AtlasTypeRegistry typeRegistry;
     private final AtlasLineageService atlasLineageService;
     private static final String DEFAULT_DIRECTION = "BOTH";
     private static final String DEFAULT_DEPTH     = "3";
@@ -60,7 +71,8 @@ public class LineageREST {
     private HttpServletRequest httpServletRequest;
 
     @Inject
-    public LineageREST(AtlasLineageService atlasLineageService) {
+    public LineageREST(AtlasTypeRegistry typeRegistry, AtlasLineageService atlasLineageService) {
+        this.typeRegistry = typeRegistry;
         this.atlasLineageService = atlasLineageService;
     }
 
@@ -95,4 +107,76 @@ public class LineageREST {
             AtlasPerfTracer.log(perf);
         }
     }
-}
\ No newline at end of file
+
+    /**
+     * Returns lineage info about entity.
+     *
+     * In addition to the typeName path parameter, attribute key-value pair(s) can be provided in the following format
+     *
+     * attr:<attrName>=<attrValue>
+     *
+     * NOTE: The attrName and attrValue should be unique across entities, eg. qualifiedName
+     *
+     * @param typeName - typeName of entity
+     * @param direction - input, output or both
+     * @param depth - number of hops for lineage
+     * @return AtlasLineageInfo
+     * @throws AtlasBaseException
+     * @HTTP 200 If Lineage exists for the given entity
+     * @HTTP 400 Bad query parameters
+     * @HTTP 404 If no lineage is found for the given entity
+     */
+    @GET
+    @Path("/uniqueAttribute/type/{typeName}")
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasLineageInfo getLineageByUniqueAttribute(@PathParam("typeName") String typeName, @QueryParam("direction") @DefaultValue(DEFAULT_DIRECTION) LineageDirection direction,
+                                                        @QueryParam("depth") @DefaultValue(DEFAULT_DEPTH) int depth, @Context HttpServletRequest servletRequest) throws AtlasBaseException {
+        Servlets.validateQueryParamLength("typeName", typeName);
+        AtlasPerfTracer perf = null;
+
+        try {
+            AtlasEntityType entityType = ensureEntityType(typeName);
+            Map<String, Object> attributes = getAttributes(servletRequest);
+            String guid = AtlasGraphUtilsV2.getGuidByUniqueAttributes(entityType, attributes);
+
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "LineageREST.getLineageByUniqueAttribute(" + typeName + "," + attributes + "," + direction +
+                        "," + depth + ")");
+            }
+
+            return atlasLineageService.getAtlasLineageInfo(guid, direction, depth);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    private Map<String, Object> getAttributes(HttpServletRequest request) {
+        Map<String, Object> attributes = new HashMap<>();
+
+        if (MapUtils.isNotEmpty(request.getParameterMap())) {
+            for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
+                String key = e.getKey();
+
+                if (key != null && key.startsWith(PREFIX_ATTR)) {
+                    String[] values = e.getValue();
+                    String value = values != null && values.length > 0 ? values[0] : null;
+
+                    attributes.put(key.substring(PREFIX_ATTR.length()), value);
+                }
+            }
+        }
+
+        return attributes;
+    }
+
+    private AtlasEntityType ensureEntityType(String typeName) throws AtlasBaseException {
+        AtlasEntityType ret = typeRegistry.getEntityTypeByName(typeName);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), typeName);
+        }
+
+        return ret;
+    }
+}