Commit 620861e3 by shanjiaqi Committed by nixonrodrigues

ATLAS-3319 :- Add API to get lineage by uniqueAttributes

parent 854a8a01
......@@ -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);
......
......@@ -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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment