Commit d934645b by Suma Shivaprasad

ATLAS-1049 List types by supertype (shwethags via sumasai)

parent fa47dd2d
...@@ -36,6 +36,7 @@ import org.apache.atlas.typesystem.TypesDef; ...@@ -36,6 +36,7 @@ import org.apache.atlas.typesystem.TypesDef;
import org.apache.atlas.typesystem.json.InstanceSerialization; import org.apache.atlas.typesystem.json.InstanceSerialization;
import org.apache.atlas.typesystem.json.TypesSerialization; import org.apache.atlas.typesystem.json.TypesSerialization;
import org.apache.atlas.typesystem.types.AttributeDefinition; import org.apache.atlas.typesystem.types.AttributeDefinition;
import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition; import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType; import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.utils.TypesUtil; import org.apache.atlas.typesystem.types.utils.TypesUtil;
...@@ -107,6 +108,9 @@ public class AtlasClient { ...@@ -107,6 +108,9 @@ public class AtlasClient {
public static final String ATTRIBUTE_NAME = "property"; public static final String ATTRIBUTE_NAME = "property";
public static final String ATTRIBUTE_VALUE = "value"; public static final String ATTRIBUTE_VALUE = "value";
public static final String SUPERTYPE = "supertype";
public static final String NOT_SUPERTYPE = "notsupertype";
public static final String ASSET_TYPE = "Asset"; public static final String ASSET_TYPE = "Asset";
public static final String NAME = "name"; public static final String NAME = "name";
public static final String DESCRIPTION = "description"; public static final String DESCRIPTION = "description";
...@@ -606,11 +610,61 @@ public class AtlasClient { ...@@ -606,11 +610,61 @@ public class AtlasClient {
return updateType(TypesSerialization.toJson(typeDef)); return updateType(TypesSerialization.toJson(typeDef));
} }
/**
* Returns all type names in the system
* @return list of type names
* @throws AtlasServiceException
*/
public List<String> listTypes() throws AtlasServiceException { public List<String> listTypes() throws AtlasServiceException {
final JSONObject jsonObject = callAPI(API.LIST_TYPES, null); final JSONObject jsonObject = callAPI(API.LIST_TYPES, null);
return extractResults(jsonObject, AtlasClient.RESULTS, new ExtractOperation<String, String>()); return extractResults(jsonObject, AtlasClient.RESULTS, new ExtractOperation<String, String>());
} }
/**
* Returns all type names with the given category
* @param category
* @return list of type names
* @throws AtlasServiceException
*/
public List<String> listTypes(final DataTypes.TypeCategory category) throws AtlasServiceException {
JSONObject response = callAPIWithRetries(API.LIST_TYPES, null, new ResourceCreator() {
@Override
public WebResource createResource() {
WebResource resource = getResource(API.LIST_TYPES);
resource = resource.queryParam(TYPE, category.name());
return resource;
}
});
return extractResults(response, AtlasClient.RESULTS, new ExtractOperation<String, String>());
}
/**
* Return the list of type names in the type system which match the specified filter.
*
* @param category returns types whose category is the given typeCategory
* @param superType returns types which contain the given supertype
* @param notSupertype returns types which do not contain the given supertype
*
* Its possible to specify combination of these filters in one request and the conditions are combined with AND
* For example, typeCategory = TRAIT && supertype contains 'X' && supertype !contains 'Y'
* If there is no filter, all the types are returned
* @return list of type names
*/
public List<String> listTypes(final DataTypes.TypeCategory category, final String superType,
final String notSupertype) throws AtlasServiceException {
JSONObject response = callAPIWithRetries(API.LIST_TYPES, null, new ResourceCreator() {
@Override
public WebResource createResource() {
WebResource resource = getResource(API.LIST_TYPES);
resource = resource.queryParam(TYPE, category.name());
resource = resource.queryParam(SUPERTYPE, superType);
resource = resource.queryParam(NOT_SUPERTYPE, notSupertype);
return resource;
}
});
return extractResults(response, AtlasClient.RESULTS, new ExtractOperation<String, String>());
}
public TypesDef getType(String typeName) throws AtlasServiceException { public TypesDef getType(String typeName) throws AtlasServiceException {
try { try {
JSONObject response = callAPI(API.GET_TYPE, null, typeName);; JSONObject response = callAPI(API.GET_TYPE, null, typeName);;
......
...@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES: ...@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
ALL CHANGES: ALL CHANGES:
ATLAS-1049 List types by supertype (shwethags via sumasai)
ATLAS-1032 Atlas hook package should not include libraries already present in host component - like log4j(mneethiraj via sumasai) ATLAS-1032 Atlas hook package should not include libraries already present in host component - like log4j(mneethiraj via sumasai)
ATLAS-1001 UI Paginate search APIs (kevalbhatt18 via sumasai) ATLAS-1001 UI Paginate search APIs (kevalbhatt18 via sumasai)
ATLAS-1042 Performance improvement changes for propertykey+typeName based queries (sumasai via shwethags) ATLAS-1042 Performance improvement changes for propertykey+typeName based queries (sumasai via shwethags)
......
...@@ -23,11 +23,8 @@ import com.google.common.collect.ImmutableList; ...@@ -23,11 +23,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.thinkaurelius.titan.core.schema.TitanManagement;
import com.tinkerpop.blueprints.Vertex;
import org.apache.atlas.ApplicationProperties; import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasConstants;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.EntityAuditEvent; import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
...@@ -302,23 +299,16 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang ...@@ -302,23 +299,16 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
} }
/** /**
* Return the list of types in the repository. * Return the list of type names in the type system which match the specified filter.
* *
* @return list of type names in the repository * @return list of type names
* @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
* If there is no filter, all the types are returned
*/ */
@Override @Override
public List<String> getTypeNamesList() throws AtlasException { public List<String> getTypeNames(Map<TypeCache.TYPE_FILTER, String> filterMap) throws AtlasException {
return typeSystem.getTypeNames(); return typeSystem.getTypeNames(filterMap);
}
/**
* Return the list of trait type names in the type system.
*
* @return list of trait type names in the type system
*/
@Override
public List<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) throws AtlasException {
return typeSystem.getTypeNamesByCategory(typeCategory);
} }
/** /**
......
...@@ -26,10 +26,11 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance; ...@@ -26,10 +26,11 @@ import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct; import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.Referenceable; import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.Struct; import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.cache.TypeCache;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Metadata service. * Metadata service.
...@@ -62,18 +63,14 @@ public interface MetadataService { ...@@ -62,18 +63,14 @@ public interface MetadataService {
String getTypeDefinition(String typeName) throws AtlasException; String getTypeDefinition(String typeName) throws AtlasException;
/** /**
* Return the list of types in the type system. * Return the list of type names in the type system which match the specified filter.
* *
* @return list of type names in the type system * @return list of type names
* @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
* If there is no filter, all the types are returned
*/ */
List<String> getTypeNamesList() throws AtlasException; List<String> getTypeNames(Map<TypeCache.TYPE_FILTER, String> filterMap) throws AtlasException;
/**
* Return the list of trait type names in the type system.
*
* @return list of trait type names in the type system
*/
List<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) throws AtlasException;
/** /**
* Creates an entity, instance of the type. * Creates an entity, instance of the type.
......
...@@ -101,12 +101,17 @@ public class TypeSystem { ...@@ -101,12 +101,17 @@ public class TypeSystem {
return ImmutableList.copyOf(typeNames); return ImmutableList.copyOf(typeNames);
} }
public ImmutableList<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) throws AtlasException { public ImmutableList<String> getTypeNamesByCategory(final DataTypes.TypeCategory typeCategory) throws AtlasException {
return ImmutableList.copyOf(typeCache.getTypeNames(typeCategory)); return getTypeNames(new HashMap<TypeCache.TYPE_FILTER, String>() {{
put(TypeCache.TYPE_FILTER.CATEGORY, typeCategory.name());
}});
} }
private void registerPrimitiveTypes() { public ImmutableList<String> getTypeNames(Map<TypeCache.TYPE_FILTER, String> filterMap) throws AtlasException {
return ImmutableList.copyOf(typeCache.getTypeNames(filterMap));
}
private void registerPrimitiveTypes() {
coreTypes.put(DataTypes.BOOLEAN_TYPE.getName(), DataTypes.BOOLEAN_TYPE); coreTypes.put(DataTypes.BOOLEAN_TYPE.getName(), DataTypes.BOOLEAN_TYPE);
coreTypes.put(DataTypes.BYTE_TYPE.getName(), DataTypes.BYTE_TYPE); coreTypes.put(DataTypes.BYTE_TYPE.getName(), DataTypes.BYTE_TYPE);
coreTypes.put(DataTypes.SHORT_TYPE.getName(), DataTypes.SHORT_TYPE); coreTypes.put(DataTypes.SHORT_TYPE.getName(), DataTypes.SHORT_TYPE);
......
...@@ -17,22 +17,24 @@ ...@@ -17,22 +17,24 @@
*/ */
package org.apache.atlas.typesystem.types.cache; package org.apache.atlas.typesystem.types.cache;
import java.util.ArrayList; import com.google.inject.Singleton;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.atlas.typesystem.types.EnumType; import org.apache.atlas.typesystem.types.EnumType;
import org.apache.atlas.typesystem.types.HierarchicalType;
import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.IDataType;
import org.apache.atlas.typesystem.types.StructType; import org.apache.atlas.typesystem.types.StructType;
import org.apache.atlas.typesystem.types.TraitType; import org.apache.atlas.typesystem.types.TraitType;
import org.apache.commons.lang.StringUtils;
import com.google.inject.Singleton; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Caches the types in-memory within the same process space. * Caches the types in-memory within the same process space.
...@@ -42,6 +44,10 @@ import com.google.inject.Singleton; ...@@ -42,6 +44,10 @@ import com.google.inject.Singleton;
public class DefaultTypeCache implements TypeCache { public class DefaultTypeCache implements TypeCache {
private Map<String, IDataType> types_ = new ConcurrentHashMap<>(); private Map<String, IDataType> types_ = new ConcurrentHashMap<>();
private static final List<TypeCategory> validTypeFilterCategories =
Arrays.asList(TypeCategory.CLASS, TypeCategory.TRAIT, TypeCategory.ENUM, TypeCategory.STRUCT);
private static final List<TypeCategory> validSupertypeFilterCategories =
Arrays.asList(TypeCategory.CLASS, TypeCategory.TRAIT);
/* /*
* (non-Javadoc) * (non-Javadoc)
...@@ -67,26 +73,23 @@ public class DefaultTypeCache implements TypeCache { ...@@ -67,26 +73,23 @@ public class DefaultTypeCache implements TypeCache {
return has(typeName); return has(typeName);
} }
private void assertValidTypeCategory(TypeCategory typeCategory) throws private void assertValidTypeCategory(String typeCategory) {
AtlasException { assertValidTypeCategory(TypeCategory.valueOf(typeCategory));
}
private void assertValidTypeCategory(TypeCategory typeCategory) {
// there might no need of 'typeCategory' in this implementation for // there might no need of 'typeCategory' in this implementation for
// certain API, but for a distributed cache, it might help for the // certain API, but for a distributed cache, it might help for the
// implementers to partition the types per their category // implementers to partition the types per their category
// while persisting so that look can be efficient // while persisting so that look can be efficient
if (typeCategory == null) { if (typeCategory == null) {
throw new AtlasException("Category of the types to be filtered is null."); throw new IllegalArgumentException("Category of the types to be filtered is null.");
} }
boolean validTypeCategory = typeCategory.equals(TypeCategory.CLASS) || if (!validTypeFilterCategories.contains(typeCategory)) {
typeCategory.equals(TypeCategory.TRAIT) || throw new IllegalArgumentException("Category of the types should be one of " +
typeCategory.equals(TypeCategory.ENUM) || StringUtils.join(validTypeFilterCategories, ", "));
typeCategory.equals(TypeCategory.STRUCT);
if (!validTypeCategory) {
throw new AtlasException("Category of the types should be one of CLASS "
+ "| TRAIT | ENUM | STRUCT.");
} }
} }
...@@ -113,29 +116,83 @@ public class DefaultTypeCache implements TypeCache { ...@@ -113,29 +116,83 @@ public class DefaultTypeCache implements TypeCache {
return get(typeName); return get(typeName);
} }
/* /**
* (non-Javadoc) * Return the list of type names in the type system which match the specified filter.
* @see *
* org.apache.atlas.typesystem.types.cache.TypeCache#getNames(org * @return list of type names
* .apache.atlas.typesystem.types.DataTypes.TypeCategory) * @param filterMap - Map of filter for type names. Valid keys are CATEGORY, SUPERTYPE, NOT_SUPERTYPE
* For example, CATEGORY = TRAIT && SUPERTYPE contains 'X' && SUPERTYPE !contains 'Y'
*/ */
@Override @Override
public Collection<String> getTypeNames(TypeCategory typeCategory) throws AtlasException { public Collection<String> getTypeNames(Map<TYPE_FILTER, String> filterMap) throws AtlasException {
assertFilter(filterMap);
assertValidTypeCategory(typeCategory);
List<String> typeNames = new ArrayList<>(); List<String> typeNames = new ArrayList<>();
for (Entry<String, IDataType> typeEntry : types_.entrySet()) { for (IDataType type : types_.values()) {
String name = typeEntry.getKey(); if (shouldIncludeType(type, filterMap)) {
IDataType type = typeEntry.getValue(); typeNames.add(type.getName());
if (type.getTypeCategory().equals(typeCategory)) {
typeNames.add(name);
} }
} }
return typeNames; return typeNames;
} }
private boolean shouldIncludeType(IDataType type, Map<TYPE_FILTER, String> filterMap) {
if (filterMap == null) {
return true;
}
for (Entry<TYPE_FILTER, String> filterEntry : filterMap.entrySet()) {
switch (filterEntry.getKey()) {
case CATEGORY:
if (!filterEntry.getValue().equals(type.getTypeCategory().name())) {
return false;
}
break;
case SUPERTYPE:
if (!validSupertypeFilterCategories.contains(type.getTypeCategory()) ||
!((HierarchicalType) type).getAllSuperTypeNames().contains(filterEntry.getValue())) {
return false;
}
break;
case NOT_SUPERTYPE:
if (!validSupertypeFilterCategories.contains(type.getTypeCategory()) ||
type.getName().equals(filterEntry.getValue()) ||
((HierarchicalType) type).getAllSuperTypeNames().contains(filterEntry.getValue())) {
return false;
}
break;
}
}
return true;
}
private void assertFilter(Map<TYPE_FILTER, String> filterMap) throws AtlasException {
if (filterMap == null) {
return;
}
for (Entry<TYPE_FILTER, String> filterEntry : filterMap.entrySet()) {
switch (filterEntry.getKey()) {
case CATEGORY:
assertValidTypeCategory(filterEntry.getValue());
break;
case SUPERTYPE:
case NOT_SUPERTYPE:
if (!has(filterEntry.getValue())) {
throw new IllegalArgumentException("Invalid supertype " + filterEntry.getValue());
}
break;
default:
throw new IllegalStateException("Unhandled filter " + filterEntry.getKey());
}
}
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see * @see
......
...@@ -18,12 +18,13 @@ ...@@ -18,12 +18,13 @@
package org.apache.atlas.typesystem.types.cache; package org.apache.atlas.typesystem.types.cache;
import java.util.Collection;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.IDataType;
import java.util.Collection;
import java.util.Map;
/** /**
* The types are cached to allow faster lookup when type info is needed during * The types are cached to allow faster lookup when type info is needed during
* creation/updation of entities, DSL query translation/execution. * creation/updation of entities, DSL query translation/execution.
...@@ -39,6 +40,10 @@ import org.apache.atlas.typesystem.types.IDataType; ...@@ -39,6 +40,10 @@ import org.apache.atlas.typesystem.types.IDataType;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public interface TypeCache { public interface TypeCache {
enum TYPE_FILTER {
CATEGORY, SUPERTYPE, NOT_SUPERTYPE
}
/** /**
* @param typeName * @param typeName
* @return true if the type exists in cache, false otherwise. * @return true if the type exists in cache, false otherwise.
...@@ -56,7 +61,7 @@ public interface TypeCache { ...@@ -56,7 +61,7 @@ public interface TypeCache {
boolean has(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException; boolean has(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException;
/** /**
* @param name The name of the type. * @param typeName The name of the type.
* @return returns non-null type if cached, otherwise null * @return returns non-null type if cached, otherwise null
* @throws AtlasException * @throws AtlasException
*/ */
...@@ -72,18 +77,16 @@ public interface TypeCache { ...@@ -72,18 +77,16 @@ public interface TypeCache {
public IDataType get(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException; public IDataType get(DataTypes.TypeCategory typeCategory, String typeName) throws AtlasException;
/** /**
* @param typeCategory The category of types to filter the returned types. Cannot be null. *
* The category can be one of TypeCategory.CLASS | TypeCategory.TRAIT | * @param filter @return
* TypeCategory.STRUCT | TypeCategory.ENUM.
* @return
* @throws AtlasException * @throws AtlasException
*/ */
Collection<String> getTypeNames(DataTypes.TypeCategory typeCategory) throws AtlasException; Collection<String> getTypeNames(Map<TYPE_FILTER, String> filter) throws AtlasException;
/** /**
* This is a convenience API to get the names of all types. * This is a convenience API to get the names of all types.
* *
* @see TypeCache#getTypeNames(org.apache.atlas.typesystem.types.DataTypes.TypeCategory) * @see TypeCache#getTypeNames(Map)
* @return * @return
* @throws AtlasException * @throws AtlasException
*/ */
......
...@@ -23,9 +23,10 @@ import org.apache.atlas.AtlasClient; ...@@ -23,9 +23,10 @@ import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.services.MetadataService; import org.apache.atlas.services.MetadataService;
import org.apache.atlas.typesystem.exception.TypeExistsException; import org.apache.atlas.typesystem.exception.TypeExistsException;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.cache.TypeCache;
import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.atlas.web.util.Servlets; import org.apache.atlas.web.util.Servlets;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONObject;
...@@ -36,7 +37,6 @@ import javax.inject.Inject; ...@@ -36,7 +37,6 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
...@@ -48,7 +48,9 @@ import javax.ws.rs.WebApplicationException; ...@@ -48,7 +48,9 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* This class provides RESTful API for Types. * This class provides RESTful API for Types.
...@@ -67,8 +69,6 @@ public class TypesResource { ...@@ -67,8 +69,6 @@ public class TypesResource {
private final MetadataService metadataService; private final MetadataService metadataService;
static final String TYPE_ALL = "all";
@Inject @Inject
public TypesResource(MetadataService metadataService) { public TypesResource(MetadataService metadataService) {
this.metadataService = metadataService; this.metadataService = metadataService;
...@@ -209,30 +209,33 @@ public class TypesResource { ...@@ -209,30 +209,33 @@ public class TypesResource {
} }
/** /**
* Gets the list of trait type names registered in the type system. * Return the list of type names in the type system which match the specified filter.
*
* @return list of type names
* @param typeCategory returns types whose category is the given typeCategory
* @param supertype returns types which contain the given supertype
* @param notsupertype returns types which do not contain the given supertype
* *
* @param type type should be the name of enum * Its possible to specify combination of these filters in one request and the conditions are combined with AND
* org.apache.atlas.typesystem.types.DataTypes.TypeCategory * For example, typeCategory = TRAIT && supertype contains 'X' && supertype !contains 'Y'
* Typically, would be one of all, TRAIT, CLASS, ENUM, STRUCT * If there is no filter, all the types are returned
* @return entity names response payload as json
*/ */
@GET @GET
@Produces(Servlets.JSON_MEDIA_TYPE) @Produces(Servlets.JSON_MEDIA_TYPE)
public Response getTypesByFilter(@Context HttpServletRequest request, public Response getTypesByFilter(@Context HttpServletRequest request, @QueryParam("type") String typeCategory,
@DefaultValue(TYPE_ALL) @QueryParam("type") String type) { @QueryParam("supertype") String supertype,
@QueryParam("notsupertype") String notsupertype) {
AtlasPerfTracer perf = null; AtlasPerfTracer perf = null;
try { try {
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) { if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "TypesResource.getTypesByFilter(" + type + ")"); perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "TypesResource.getTypesByFilter(" + typeCategory + ")");
} }
List<String> result; Map<TypeCache.TYPE_FILTER, String> filterMap = new HashMap<>();
if (TYPE_ALL.equals(type)) { addToFilterIfNotEmpty(filterMap, TypeCache.TYPE_FILTER.CATEGORY, typeCategory);
result = metadataService.getTypeNamesList(); addToFilterIfNotEmpty(filterMap, TypeCache.TYPE_FILTER.SUPERTYPE, supertype);
} else { addToFilterIfNotEmpty(filterMap, TypeCache.TYPE_FILTER.NOT_SUPERTYPE, notsupertype);
DataTypes.TypeCategory typeCategory = DataTypes.TypeCategory.valueOf(type); List<String> result = metadataService.getTypeNames(filterMap);
result = metadataService.getTypeNamesByCategory(typeCategory);
}
JSONObject response = new JSONObject(); JSONObject response = new JSONObject();
response.put(AtlasClient.RESULTS, new JSONArray(result)); response.put(AtlasClient.RESULTS, new JSONArray(result));
...@@ -241,9 +244,9 @@ public class TypesResource { ...@@ -241,9 +244,9 @@ public class TypesResource {
return Response.ok(response).build(); return Response.ok(response).build();
} catch (IllegalArgumentException | AtlasException ie) { } catch (IllegalArgumentException | AtlasException ie) {
LOG.error("Unsupported typeName while retrieving type list {}", type); LOG.error("Unsupported typeName while retrieving type list {}", typeCategory);
throw new WebApplicationException( throw new WebApplicationException(
Servlets.getErrorResponse(new Exception("Unsupported type " + type, ie), Response.Status.BAD_REQUEST)); Servlets.getErrorResponse(new Exception("Unsupported type " + typeCategory, ie), Response.Status.BAD_REQUEST));
} catch (Throwable e) { } catch (Throwable e) {
LOG.error("Unable to get types list", e); LOG.error("Unable to get types list", e);
throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR)); throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
...@@ -251,4 +254,11 @@ public class TypesResource { ...@@ -251,4 +254,11 @@ public class TypesResource {
AtlasPerfTracer.log(perf); AtlasPerfTracer.log(perf);
} }
} }
private void addToFilterIfNotEmpty(Map<TypeCache.TYPE_FILTER, String> filterMap, TypeCache.TYPE_FILTER filterType,
String filterValue) {
if (StringUtils.isNotEmpty(filterValue)) {
filterMap.put(filterType, filterValue);
}
}
} }
...@@ -22,7 +22,6 @@ import com.google.common.base.Preconditions; ...@@ -22,7 +22,6 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig;
import kafka.consumer.ConsumerTimeoutException; import kafka.consumer.ConsumerTimeoutException;
...@@ -51,18 +50,14 @@ import org.apache.atlas.typesystem.types.TypeUtils; ...@@ -51,18 +50,14 @@ import org.apache.atlas.typesystem.types.TypeUtils;
import org.apache.atlas.typesystem.types.utils.TypesUtil; import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.atlas.utils.AuthenticationUtil; import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.atlas.utils.ParamChecker; import org.apache.atlas.utils.ParamChecker;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.RandomStringUtils;
import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import java.util.List; import java.util.List;
...@@ -109,19 +104,8 @@ public abstract class BaseResourceIT { ...@@ -109,19 +104,8 @@ public abstract class BaseResourceIT {
} }
} }
protected void createType(String typesAsJSON) throws Exception { protected List<String> createType(String typesAsJSON) throws Exception {
WebResource resource = service.path("api/atlas/types"); return serviceClient.createType(TypesSerialization.fromJson(typesAsJSON));
ClientResponse clientResponse = resource.accept(Servlets.JSON_MEDIA_TYPE).type(Servlets.JSON_MEDIA_TYPE)
.method(HttpMethod.POST, ClientResponse.class, typesAsJSON);
Assert.assertEquals(clientResponse.getStatus(), Response.Status.CREATED.getStatusCode());
String responseAsString = clientResponse.getEntity(String.class);
Assert.assertNotNull(responseAsString);
JSONObject response = new JSONObject(responseAsString);
Assert.assertNotNull(response.get("types"));
Assert.assertNotNull(response.get(AtlasClient.REQUEST_ID));
} }
protected Id createInstance(Referenceable referenceable) throws Exception { protected Id createInstance(Referenceable referenceable) throws Exception {
......
...@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList; ...@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.WebResource;
import org.apache.atlas.AtlasClient; import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasServiceException; import org.apache.atlas.AtlasServiceException;
import org.apache.atlas.typesystem.TypesDef; import org.apache.atlas.typesystem.TypesDef;
...@@ -47,10 +46,11 @@ import org.testng.annotations.Test; ...@@ -47,10 +46,11 @@ import org.testng.annotations.Test;
import javax.ws.rs.HttpMethod; import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.apache.atlas.typesystem.types.utils.TypesUtil.createOptionalAttrDef;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail; import static org.testng.Assert.fail;
...@@ -126,7 +126,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT { ...@@ -126,7 +126,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
typeDefinition = TypesUtil.createClassTypeDef(typeDefinition.typeName, typeDefinition = TypesUtil.createClassTypeDef(typeDefinition.typeName,
ImmutableSet.<String>of(), ImmutableSet.<String>of(),
TypesUtil.createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE), TypesUtil.createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE),
TypesUtil.createOptionalAttrDef("description", DataTypes.STRING_TYPE)); createOptionalAttrDef("description", DataTypes.STRING_TYPE));
TypesDef typeDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), TypesDef typeDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(),
ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(), ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
ImmutableList.of(typeDefinition)); ImmutableList.of(typeDefinition));
...@@ -224,6 +224,22 @@ public class TypesJerseyResourceIT extends BaseResourceIT { ...@@ -224,6 +224,22 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
Assert.assertTrue(list.length() >= traitsAdded.length); Assert.assertTrue(list.length() >= traitsAdded.length);
} }
@Test
public void testListTypesByFilter() throws Exception {
AttributeDefinition attr = TypesUtil.createOptionalAttrDef("attr", DataTypes.STRING_TYPE);
String a = createType(TypesSerialization.toJson(
TypesUtil.createClassTypeDef("A" + randomString(), ImmutableSet.<String>of(), attr), false)).get(0);
String a1 = createType(TypesSerialization.toJson(
TypesUtil.createClassTypeDef("A1" + randomString(), ImmutableSet.of(a), attr), false)).get(0);
String b = createType(TypesSerialization.toJson(
TypesUtil.createClassTypeDef("B" + randomString(), ImmutableSet.<String>of(), attr), false)).get(0);
String c = createType(TypesSerialization.toJson(
TypesUtil.createClassTypeDef("C" + randomString(), ImmutableSet.of(a, b), attr), false)).get(0);
List<String> results = serviceClient.listTypes(DataTypes.TypeCategory.CLASS, a, b);
assertEquals(results, Arrays.asList(a1), "Results: " + results);
}
private String[] addTraits() throws Exception { private String[] addTraits() throws Exception {
String[] traitNames = {"class_trait", "secure_trait", "pii_trait", "ssn_trait", "salary_trait", "sox_trait",}; String[] traitNames = {"class_trait", "secure_trait", "pii_trait", "ssn_trait", "salary_trait", "sox_trait",};
...@@ -250,9 +266,9 @@ public class TypesJerseyResourceIT extends BaseResourceIT { ...@@ -250,9 +266,9 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
.createClassTypeDef("table", ImmutableSet.<String>of(), .createClassTypeDef("table", ImmutableSet.<String>of(),
TypesUtil.createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE), TypesUtil.createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE),
TypesUtil.createRequiredAttrDef("description", DataTypes.STRING_TYPE), TypesUtil.createRequiredAttrDef("description", DataTypes.STRING_TYPE),
TypesUtil.createOptionalAttrDef("columnNames", DataTypes.arrayTypeName(DataTypes.STRING_TYPE)), createOptionalAttrDef("columnNames", DataTypes.arrayTypeName(DataTypes.STRING_TYPE)),
TypesUtil.createOptionalAttrDef("created", DataTypes.DATE_TYPE), TypesUtil createOptionalAttrDef("created", DataTypes.DATE_TYPE),
.createOptionalAttrDef("parameters", createOptionalAttrDef("parameters",
DataTypes.mapTypeName(DataTypes.STRING_TYPE, DataTypes.STRING_TYPE)), DataTypes.mapTypeName(DataTypes.STRING_TYPE, DataTypes.STRING_TYPE)),
TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE),
new AttributeDefinition("database", "database", Multiplicity.REQUIRED, false, "database")); new AttributeDefinition("database", "database", Multiplicity.REQUIRED, false, "database"));
......
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