Commit 056044a9 by Hemanth Yamijala

ATLAS-794 Business Catalog Update (jspeidel via yhemanth)

parent 5b627b5a
......@@ -27,23 +27,38 @@ import java.util.Map;
* Base user API request.
*/
public abstract class BaseRequest implements Request {
private final Map<String, Object> properties = new HashMap<>();
private final Map<String, Object> queryProperties = new HashMap<>();
private final Map<String, Object> updateProperties = new HashMap<>();
private final String queryString;
private final Collection<String> additionalSelectProperties = new HashSet<>();
protected BaseRequest(Map<String, Object> properties, String queryString) {
if (properties != null) {
this.properties.putAll((properties));
protected BaseRequest(Map<String, Object> queryProperties, String queryString) {
this(queryProperties, queryString, null);
}
protected BaseRequest(Map<String, Object> queryProperties, String queryString, Map<String, Object> updateProperties) {
if (queryProperties != null) {
this.queryProperties.putAll(queryProperties);
}
if (updateProperties != null) {
this.updateProperties.putAll(updateProperties);
}
this.queryString = queryString;
}
public Map<String, Object> getProperties() {
return properties;
public Map<String, Object> getQueryProperties() {
return queryProperties;
}
public Map<String, Object> getUpdateProperties() {
return updateProperties;
}
public <T> T getProperty(String name) {
return (T)properties.get(name);
return (T) queryProperties.get(name);
}
public String getQueryString() {
......@@ -67,16 +82,16 @@ public abstract class BaseRequest implements Request {
BaseRequest that = (BaseRequest) o;
return properties.equals(that.properties) &&
return queryProperties.equals(that.queryProperties) &&
updateProperties.equals(that.updateProperties) &&
additionalSelectProperties.equals(that.additionalSelectProperties) &&
queryString == null ?
that.queryString == null :
queryString.equals(that.queryString);
queryString == null ? that.queryString == null : queryString.equals(that.queryString);
}
@Override
public int hashCode() {
int result = properties.hashCode();
int result = queryProperties.hashCode();
result = 31 * result + updateProperties.hashCode();
result = 31 * result + (queryString != null ? queryString.hashCode() : 0);
result = 31 * result + additionalSelectProperties.hashCode();
return result;
......
......@@ -18,19 +18,24 @@
package org.apache.atlas.catalog;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.exception.InvalidPayloadException;
import org.apache.atlas.catalog.exception.ResourceNotFoundException;
import org.apache.atlas.catalog.query.QueryFactory;
import java.util.Collections;
/**
* Base class for resource providers.
*/
public abstract class BaseResourceProvider implements ResourceProvider {
protected AtlasTypeSystem typeSystem;
protected final AtlasTypeSystem typeSystem;
protected QueryFactory queryFactory = new QueryFactory();
protected final ResourceDefinition resourceDefinition;
protected BaseResourceProvider(AtlasTypeSystem typeSystem) {
protected BaseResourceProvider(AtlasTypeSystem typeSystem, ResourceDefinition resourceDefinition) {
this.typeSystem = typeSystem;
this.resourceDefinition = resourceDefinition;
}
protected void setQueryFactory(QueryFactory factory) {
......@@ -41,4 +46,9 @@ public abstract class BaseResourceProvider implements ResourceProvider {
public void deleteResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
throw new InvalidPayloadException("Delete is not supported for this resource type");
}
@Override
public void updateResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
throw new InvalidPayloadException("Update is not supported for this resource type");
}
}
......@@ -24,8 +24,12 @@ import java.util.Map;
* A request for a collection resource.
*/
public class CollectionRequest extends BaseRequest {
public CollectionRequest(Map<String, Object> properties, String queryString) {
super(properties, queryString);
public CollectionRequest(Map<String, Object> queryProperties, String queryString) {
super(queryProperties, queryString);
}
public CollectionRequest(Map<String, Object> queryProperties, String queryString, Map<String, Object> updateProperties) {
super(queryProperties, queryString, updateProperties);
}
@Override
......
......@@ -18,13 +18,11 @@
package org.apache.atlas.catalog;
import com.thinkaurelius.titan.core.TitanGraph;
import org.apache.atlas.AtlasException;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.exception.CatalogRuntimeException;
import org.apache.atlas.catalog.exception.ResourceAlreadyExistsException;
import org.apache.atlas.catalog.exception.ResourceNotFoundException;
import org.apache.atlas.repository.graph.TitanGraphProvider;
import org.apache.atlas.services.MetadataService;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.Referenceable;
......@@ -64,12 +62,12 @@ public class DefaultTypeSystem implements AtlasTypeSystem {
// ok if type already exists
}
try {
Referenceable entity = new Referenceable(typeName, request.getProperties());
Referenceable entity = new Referenceable(typeName, request.getQueryProperties());
ITypedReferenceableInstance typedInstance = metadataService.getTypedReferenceableInstance(entity);
metadataService.createEntities(Collections.singletonList(typedInstance).toArray(new ITypedReferenceableInstance[1]));
} catch (EntityExistsException e) {
throw new ResourceAlreadyExistsException(
"Attempted to create an entity which already exists: " + request.getProperties());
"Attempted to create an entity which already exists: " + request.getQueryProperties());
} catch (AtlasException e) {
throw new CatalogRuntimeException("An expected exception occurred creating an entity: " + e, e);
}
......
......@@ -19,7 +19,6 @@
package org.apache.atlas.catalog;
import org.apache.atlas.catalog.definition.EntityResourceDefinition;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.exception.*;
import org.apache.atlas.catalog.query.AtlasQuery;
......@@ -29,10 +28,9 @@ import java.util.*;
* Provider for entity resources.
*/
public class EntityResourceProvider extends BaseResourceProvider implements ResourceProvider {
private final static ResourceDefinition resourceDefinition = new EntityResourceDefinition();
public EntityResourceProvider(AtlasTypeSystem typeSystem) {
super(typeSystem);
super(typeSystem, new EntityResourceDefinition());
}
@Override
......
......@@ -19,7 +19,6 @@
package org.apache.atlas.catalog;
import org.apache.atlas.catalog.definition.EntityTagResourceDefinition;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.exception.*;
import org.apache.atlas.catalog.query.AtlasQuery;
......@@ -29,12 +28,10 @@ import java.util.*;
* Provider for entity tag resources.
*/
public class EntityTagResourceProvider extends BaseResourceProvider implements ResourceProvider {
private final static ResourceDefinition resourceDefinition = new EntityTagResourceDefinition();
private TermResourceProvider termResourceProvider;
public EntityTagResourceProvider(AtlasTypeSystem typeSystem) {
super(typeSystem);
super(typeSystem, new EntityTagResourceDefinition());
}
@Override
......@@ -64,8 +61,8 @@ public class EntityTagResourceProvider extends BaseResourceProvider implements R
public void createResource(Request request)
throws InvalidPayloadException, ResourceAlreadyExistsException, ResourceNotFoundException {
String entityId = String.valueOf(request.getProperties().remove("id"));
resourceDefinition.validate(request);
String entityId = String.valueOf(request.getQueryProperties().remove("id"));
resourceDefinition.validateCreatePayload(request);
Result termResult = getTermQueryResult(request.<String>getProperty("name"));
Map<String, Object> termProperties = termResult.getPropertyMaps().iterator().next();
//todo: use constant for property name
......
......@@ -24,8 +24,12 @@ import java.util.Map;
* A request for an instance resource.
*/
public class InstanceRequest extends BaseRequest {
public InstanceRequest(Map<String, Object> properties) {
super(properties, null);
public InstanceRequest(Map<String, Object> queryProperties) {
super(queryProperties, null);
}
public InstanceRequest(Map<String, Object> queryProperties, Map<String, Object> updateProperties) {
super(queryProperties, null, updateProperties);
}
@Override
......
......@@ -31,11 +31,20 @@ public interface Request {
enum Cardinality {INSTANCE, COLLECTION}
/**
* Get request properties.
* Get query properties of request.
* These are the properties which are used to build the query.
*
* @return request property map
* @return query property map
*/
Map<String, Object> getProperties();
Map<String, Object> getQueryProperties();
/**
* Get update properties of request.
* These properties are updated on all resources which are returned from the query.
*
* @return update property map
*/
Map<String, Object> getUpdateProperties();
/**
* Get the value of a specified property.
......
......@@ -82,4 +82,14 @@ public interface ResourceProvider {
* @throws ResourceNotFoundException if a parent of the resource to create doesn't exist
*/
Collection<String> createResources(Request request) throws CatalogException;
/**
* Update a single resource.
*
* @param request request instance containing the contents of the resource to update
*
* @throws ResourceNotFoundException if the resource doesn't exist
* @throws InvalidPayloadException if the request payload is invalid
*/
void updateResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException;
}
......@@ -18,7 +18,6 @@
package org.apache.atlas.catalog;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.definition.TaxonomyResourceDefinition;
import org.apache.atlas.catalog.exception.*;
import org.apache.atlas.catalog.query.AtlasQuery;
......@@ -30,10 +29,9 @@ import java.util.*;
*/
public class TaxonomyResourceProvider extends BaseResourceProvider implements ResourceProvider {
private final TermResourceProvider termResourceProvider;
private static final ResourceDefinition resourceDefinition = new TaxonomyResourceDefinition();
public TaxonomyResourceProvider(AtlasTypeSystem typeSystem) {
super(typeSystem);
super(typeSystem, new TaxonomyResourceDefinition());
termResourceProvider = new TermResourceProvider(typeSystem);
}
......@@ -53,15 +51,17 @@ public class TaxonomyResourceProvider extends BaseResourceProvider implements Re
return new Result(results);
}
@Override
public Result getResources(Request request) throws InvalidQueryException, ResourceNotFoundException {
AtlasQuery atlasQuery = queryFactory.createTaxonomyQuery(request);
return new Result(atlasQuery.execute());
}
@Override
public synchronized void createResource(Request request)
throws InvalidPayloadException, ResourceAlreadyExistsException {
resourceDefinition.validate(request);
resourceDefinition.validateCreatePayload(request);
ensureTaxonomyDoesntExist(request);
typeSystem.createEntity(resourceDefinition, request);
}
......@@ -73,15 +73,26 @@ public class TaxonomyResourceProvider extends BaseResourceProvider implements Re
@Override
public void deleteResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
request.addAdditionalSelectProperties(Collections.singleton("id"));
// will result in expected ResourceNotFoundException if taxonomy doesn't exist
Result taxonomyResult = getResourceById(request);
String taxonomyId = String.valueOf(taxonomyResult.getPropertyMaps().iterator().next().get("id"));
String taxonomyId = getResourceId(request);
getTermResourceProvider().deleteChildren(taxonomyId, new TermPath(request.<String>getProperty("name")));
typeSystem.deleteEntity(resourceDefinition, request);
}
@Override
public void updateResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
resourceDefinition.validateUpdatePayload(request);
AtlasQuery atlasQuery;
try {
atlasQuery = queryFactory.createTaxonomyQuery(request);
} catch (InvalidQueryException e) {
throw new CatalogRuntimeException("Unable to compile internal Term query: " + e, e);
}
if (atlasQuery.execute(request.getUpdateProperties()).isEmpty()) {
throw new ResourceNotFoundException(String.format("Taxonomy '%s' not found.",
request.getQueryProperties().get("name")));
}
}
private void ensureTaxonomyDoesntExist(Request request) throws ResourceAlreadyExistsException {
try {
getResourceById(request);
......@@ -92,6 +103,13 @@ public class TaxonomyResourceProvider extends BaseResourceProvider implements Re
}
}
private String getResourceId(Request request) throws ResourceNotFoundException {
request.addAdditionalSelectProperties(Collections.singleton("id"));
// will result in expected ResourceNotFoundException if taxonomy doesn't exist
Result result = getResourceById(request);
return String.valueOf(result.getPropertyMaps().iterator().next().get("id"));
}
protected TermResourceProvider getTermResourceProvider() {
return termResourceProvider;
}
......
......@@ -18,7 +18,6 @@
package org.apache.atlas.catalog;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.catalog.definition.TermResourceDefinition;
import org.apache.atlas.catalog.exception.*;
import org.apache.atlas.catalog.query.AtlasQuery;
......@@ -29,19 +28,18 @@ import java.util.*;
* Provider for Term resources.
*/
public class TermResourceProvider extends BaseResourceProvider implements ResourceProvider {
private final static ResourceDefinition resourceDefinition = new TermResourceDefinition();
private ResourceProvider taxonomyResourceProvider;
private ResourceProvider entityResourceProvider;
private ResourceProvider entityTagResourceProvider;
public TermResourceProvider(AtlasTypeSystem typeSystem) {
super(typeSystem);
super(typeSystem, new TermResourceDefinition());
}
@Override
public Result getResourceById(Request request) throws ResourceNotFoundException {
//todo: shouldn't need to add this here
request.getProperties().put("name", request.<TermPath>getProperty("termPath").getFullyQualifiedName());
request.getQueryProperties().put("name", request.<TermPath>getProperty("termPath").getFullyQualifiedName());
AtlasQuery atlasQuery;
try {
atlasQuery = queryFactory.createTermQuery(request);
......@@ -61,7 +59,7 @@ public class TermResourceProvider extends BaseResourceProvider implements Resour
TermPath termPath = request.getProperty("termPath");
String queryString = doQueryStringConversions(termPath, request.getQueryString());
Request queryRequest = new CollectionRequest(request.getProperties(), queryString);
Request queryRequest = new CollectionRequest(request.getQueryProperties(), queryString);
AtlasQuery atlasQuery = queryFactory.createTermQuery(queryRequest);
Collection<Map<String, Object>> result = atlasQuery.execute();
return new Result(result);
......@@ -70,10 +68,10 @@ public class TermResourceProvider extends BaseResourceProvider implements Resour
public void createResource(Request request)
throws InvalidPayloadException, ResourceAlreadyExistsException, ResourceNotFoundException {
TermPath termPath = (TermPath) request.getProperties().remove("termPath");
TermPath termPath = (TermPath) request.getQueryProperties().remove("termPath");
String qualifiedTermName = termPath.getFullyQualifiedName();
request.getProperties().put("name", qualifiedTermName);
resourceDefinition.validate(request);
request.getQueryProperties().put("name", qualifiedTermName);
resourceDefinition.validateCreatePayload(request);
// get taxonomy
Request taxonomyRequest = new InstanceRequest(
......@@ -84,7 +82,7 @@ public class TermResourceProvider extends BaseResourceProvider implements Resour
// ensure that parent exists if not a root level term
if (! termPath.getPath().equals("/")) {
Map<String, Object> parentProperties = new HashMap<>(request.getProperties());
Map<String, Object> parentProperties = new HashMap<>(request.getQueryProperties());
parentProperties.put("termPath", termPath.getParent());
getResourceById(new InstanceRequest(parentProperties));
}
......@@ -93,7 +91,7 @@ public class TermResourceProvider extends BaseResourceProvider implements Resour
request.<String>getProperty("description"));
typeSystem.createTraitInstance(String.valueOf(taxonomyPropertyMap.get("id")),
qualifiedTermName, request.getProperties());
qualifiedTermName, request.getQueryProperties());
}
@Override
......@@ -102,11 +100,44 @@ public class TermResourceProvider extends BaseResourceProvider implements Resour
}
@Override
public void updateResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
resourceDefinition.validateUpdatePayload(request);
String termName = request.<TermPath>getProperty("termPath").getFullyQualifiedName();
request.getQueryProperties().put("name", termName);
AtlasQuery atlasQuery;
try {
atlasQuery = queryFactory.createTermQuery(request);
} catch (InvalidQueryException e) {
throw new CatalogRuntimeException("Unable to compile internal Term query: " + e, e);
}
Map<String, Object> updateProperties = request.getUpdateProperties();
Collection<Map<String, Object>> results = atlasQuery.execute(updateProperties);
if (results.isEmpty()) {
throw new ResourceNotFoundException(String.format("Term '%s' not found.",
termName));
}
// only the term 'description' property is set on entity tags
if (updateProperties.containsKey("description")) {
// 'description' property is being updated so we need to update tags
String tagQueryString = String.format("name:%s", termName);
Request tagRequest = new CollectionRequest(
Collections.<String, Object>singletonMap("id", "*"), tagQueryString, null);
AtlasQuery tagQuery;
try {
tagQuery = queryFactory.createEntityTagQuery(tagRequest);
} catch (InvalidQueryException e) {
throw new CatalogRuntimeException("Unable to compile internal Entity Tag query: " + e, e);
}
tagQuery.execute(Collections.singletonMap("description", updateProperties.get("description")));
}
}
@Override
public void deleteResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
// will result in expected ResourceNotFoundException if term doesn't exist
getResourceById(request);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
String taxonomyId = getTaxonomyId(termPath);
deleteChildren(taxonomyId, termPath);
deleteTerm(taxonomyId, termPath);
......
......@@ -66,6 +66,10 @@ public class VertexWrapper {
return val;
}
public void setProperty(String name, Object value) {
vertex.setProperty(propertyMapper.toFullyQualifiedName(name, vertexType), value);
}
public Collection<String> getPropertyKeys() {
Collection<String> propertyKeys = new TreeSet<>(resourceComparator);
......
......@@ -58,8 +58,8 @@ public abstract class BaseResourceDefinition implements ResourceDefinition {
}
@Override
public void validate(Request request) throws InvalidPayloadException {
Collection<String> propKeys = new HashSet<>(request.getProperties().keySet());
public void validateCreatePayload(Request request) throws InvalidPayloadException {
Collection<String> propKeys = new HashSet<>(request.getQueryProperties().keySet());
Collection<String> missingProperties = new HashSet<>();
for (AttributeInfo property : properties.values()) {
String name = property.name;
......@@ -77,6 +77,19 @@ public abstract class BaseResourceDefinition implements ResourceDefinition {
}
@Override
public void validateUpdatePayload(Request request) throws InvalidPayloadException {
Collection<String> updateKeys = new HashSet<>(request.getUpdateProperties().keySet());
Collection<String> validProperties = new HashSet<>(properties.keySet());
// currently updating 'name' property for any resource is unsupported
validProperties.remove("name");
updateKeys.removeAll(validProperties);
if (! updateKeys.isEmpty()) {
throw new InvalidPayloadException(Collections.<String>emptySet(), updateKeys);
}
}
@Override
public Collection<AttributeDefinition> getPropertyDefinitions() {
return propertyDefs.values();
}
......
......@@ -60,7 +60,7 @@ public class EntityResourceDefinition extends BaseResourceDefinition {
}
@Override
public void validate(Request request) throws InvalidPayloadException {
public void validateCreatePayload(Request request) throws InvalidPayloadException {
// no op for entities as we don't currently create entities and
// each entity type is different
}
......
......@@ -39,14 +39,24 @@ public interface ResourceDefinition {
* @return the resources type name
*/
String getTypeName();
/**
* Validate a user request.
* Validate a user create request payload.
*
* @param request user request
* @param request user create request
*
* @throws InvalidPayloadException if the request payload is invalid in any way
*/
void validateCreatePayload(Request request) throws InvalidPayloadException;
/**
* Validate a user update request payload.
*
* @param request user update request
*
* @throws InvalidPayloadException if the request payload is invalid in any way
*/
void validate(Request request) throws InvalidPayloadException;
void validateUpdatePayload(Request request) throws InvalidPayloadException;
/**
* Get the name of the resources id property.
......
......@@ -50,9 +50,9 @@ public class TaxonomyResourceDefinition extends BaseResourceDefinition {
}
@Override
public void validate(Request request) throws InvalidPayloadException {
super.validate(request);
if (String.valueOf(request.getProperties().get("name")).contains(".")) {
public void validateCreatePayload(Request request) throws InvalidPayloadException {
super.validateCreatePayload(request);
if (String.valueOf(request.getQueryProperties().get("name")).contains(".")) {
throw new InvalidPayloadException("The \"name\" property may not contain the character '.'");
}
}
......
......@@ -57,8 +57,8 @@ public class TermResourceDefinition extends BaseResourceDefinition {
}
@Override
public void validate(Request request) throws InvalidPayloadException {
super.validate(request);
public void validateCreatePayload(Request request) throws InvalidPayloadException {
super.validateCreatePayload(request);
String name = request.getProperty("name");
// name will be in the fully qualified form: taxonomyName.termName
......@@ -66,8 +66,8 @@ public class TermResourceDefinition extends BaseResourceDefinition {
throw new InvalidPayloadException("Term name must be in the form 'taxonomyName.termName.subTermName'");
}
if (! request.getProperties().containsKey("available_as_tag")) {
request.getProperties().put("available_as_tag", true);
if (! request.getQueryProperties().containsKey("available_as_tag")) {
request.getQueryProperties().put("available_as_tag", true);
}
}
......
......@@ -33,8 +33,6 @@ public class AtlasEntityQuery extends BaseQuery {
}
protected Pipe getQueryPipe() {
//todo: the property 'entityText' isn't currently indexed
//todo: we could use Constants.ENTITY_TYPE_PROPERTY_KEY initially but trait instances also contain this property
return new GremlinPipeline().has(Constants.ENTITY_TEXT_PROPERTY_KEY).
hasNot(Constants.ENTITY_TYPE_PROPERTY_KEY, "Taxonomy");
}
......
......@@ -47,7 +47,13 @@ public class AtlasEntityTagQuery extends BaseQuery {
@Override
protected Pipe getQueryPipe() {
GremlinPipeline p = new GremlinPipeline().has(Constants.GUID_PROPERTY_KEY, guid).outE();
GremlinPipeline p;
if (guid.equals("*")) {
p = new GremlinPipeline().has(Constants.ENTITY_TEXT_PROPERTY_KEY).
hasNot(Constants.ENTITY_TYPE_PROPERTY_KEY, "Taxonomy").outE();
} else {
p = new GremlinPipeline().has(Constants.GUID_PROPERTY_KEY, guid).outE();
}
//todo: this is basically the same pipeline used in TagRelation.asPipe()
p.add(new FilterFunctionPipe<>(new PipeFunction<Edge, Boolean>() {
@Override
......@@ -63,12 +69,18 @@ public class AtlasEntityTagQuery extends BaseQuery {
//todo: duplication of effort with resource definition
@Override
protected void addHref(Map<String, Object> propertyMap) {
Map<String, Object> map = new HashMap<>(propertyMap);
protected void addHref(VertexWrapper vWrapper, Map<String, Object> filteredPropertyMap) {
Map<String, Object> map = new HashMap<>(filteredPropertyMap);
if (guid.equals("*")) {
map.put(EntityTagResourceDefinition.ENTITY_GUID_PROPERTY, vWrapper.getVertex().getEdges(Direction.IN).
iterator().next().getVertex(Direction.OUT).getProperty(Constants.GUID_PROPERTY_KEY));
} else {
map.put(EntityTagResourceDefinition.ENTITY_GUID_PROPERTY, guid);
}
String href = resourceDefinition.resolveHref(map);
if (href != null) {
propertyMap.put("href", href);
filteredPropertyMap.put("href", href);
}
}
}
......@@ -34,4 +34,14 @@ public interface AtlasQuery {
* @throws ResourceNotFoundException if an explicitly specified resource doesn't exist
*/
Collection<Map<String, Object>> execute() throws ResourceNotFoundException;
/**
* Execute the query and update the results with the provided properties.
*
* @param updateProperties properties name/values to update on query results
*
* @return collection of property maps, one per matching resource
* @throws ResourceNotFoundException if an explicitly specified resource doesn't exist
*/
Collection<Map<String, Object>> execute(Map<String, Object> updateProperties) throws ResourceNotFoundException;
}
......@@ -39,7 +39,13 @@ public class AtlasTermQuery extends BaseQuery {
@Override
protected Pipe getQueryPipe() {
return new GremlinPipeline().has("Taxonomy.name", termPath.getTaxonomyName()).out().
GremlinPipeline p;
if (termPath.getTaxonomyName().equals("*")) {
p = new GremlinPipeline().has("Taxonomy.name").out();
} else {
p = new GremlinPipeline().has("Taxonomy.name", termPath.getTaxonomyName()).out().
has(Constants.ENTITY_TYPE_PROPERTY_KEY, Text.PREFIX, termPath.getFullyQualifiedName());
}
return p;
}
}
......@@ -56,31 +56,47 @@ public abstract class BaseQuery implements AtlasQuery {
public Collection<Map<String, Object>> execute() throws ResourceNotFoundException {
Collection<Map<String, Object>> resultMaps = new ArrayList<>();
try {
for (Vertex vertex : executeQuery()) {
resultMaps.add(processPropertyMap(wrapVertex(vertex)));
}
getGraph().commit();
} catch (Throwable t) {
getGraph().rollback();
throw t;
}
return resultMaps;
}
private List<Vertex> executeQuery() {
GremlinPipeline pipeline = buildPipeline().as("root");
@Override
public Collection<Map<String, Object>> execute(Map<String, Object> updateProperties)
throws ResourceNotFoundException {
Pipe expressionPipe = queryExpression.asPipe();
Collection<Map<String, Object>> resultMaps = new ArrayList<>();
try {
// AlwaysQuery returns null for pipe
List<Vertex> vertices = expressionPipe == null ? pipeline.toList() :
pipeline.add(expressionPipe).back("root").toList();
// Even non-mutating queries can result in objects being created in
// the graph such as new fields or property keys. So, it is important
// to commit the implicit query after execution, otherwise the uncommitted
// transaction will still be associated with the thread when it is re-pooled.
for (Vertex vertex : executeQuery()) {
VertexWrapper vWrapper = wrapVertex(vertex);
for (Map.Entry<String, Object> property : updateProperties.entrySet()) {
vWrapper.setProperty(property.getKey(), property.getValue());
vWrapper.setProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, System.currentTimeMillis());
}
resultMaps.add(processPropertyMap(vWrapper));
}
getGraph().commit();
return vertices;
} catch (Throwable e) {
getGraph().rollback();
throw e;
}
return resultMaps;
}
private List<Vertex> executeQuery() {
GremlinPipeline pipeline = buildPipeline().as("root");
Pipe expressionPipe = queryExpression.asPipe();
// AlwaysQuery returns null for pipe
return expressionPipe == null ? pipeline.toList() :
pipeline.add(expressionPipe).back("root").toList();
}
protected GremlinPipeline buildPipeline() {
......@@ -89,7 +105,6 @@ public abstract class BaseQuery implements AtlasQuery {
if (queryPipe != null) {
pipeline.add(queryPipe);
}
//todo: may be more efficient to move the notDeleted pipe after the expression pipe
pipeline.add(getNotDeletedPipe());
return pipeline;
}
......@@ -108,17 +123,17 @@ public abstract class BaseQuery implements AtlasQuery {
protected Map<String, Object> processPropertyMap(VertexWrapper vertex) {
Map<String, Object> propertyMap = resourceDefinition.filterProperties(
request, vertex.getPropertyMap());
addHref(propertyMap);
addHref(vertex, propertyMap);
return request.getCardinality() == Request.Cardinality.INSTANCE ?
applyProjections(vertex, propertyMap) :
propertyMap;
}
protected void addHref(Map<String, Object> propertyMap) {
String href = resourceDefinition.resolveHref(propertyMap);
protected void addHref(VertexWrapper vWrapper, Map<String, Object> filteredPropertyMap) {
String href = resourceDefinition.resolveHref(filteredPropertyMap);
if (href != null) {
propertyMap.put("href", href);
filteredPropertyMap.put("href", href);
}
}
......
......@@ -88,6 +88,7 @@ public class QueryFactory {
if (queryString != null && !queryString.isEmpty()) {
QueryParser queryParser = new QueryParser(Version.LUCENE_48, "name", new KeywordAnalyzer());
queryParser.setLowercaseExpandedTerms(false);
queryParser.setAllowLeadingWildcard(true);
Query query;
try {
query = queryParser.parse((String) escape(queryString));
......
......@@ -36,7 +36,7 @@ public class CollectionRequestTest {
Request request = new CollectionRequest(null, query);
assertEquals(Request.Cardinality.COLLECTION, request.getCardinality());
assertTrue(request.getProperties().isEmpty());
assertTrue(request.getQueryProperties().isEmpty());
assertNull(request.getProperty("foo"));
assertTrue(request.getAdditionalSelectProperties().isEmpty());
}
......@@ -50,7 +50,7 @@ public class CollectionRequestTest {
Request request = new CollectionRequest(properties, query);
assertEquals(Request.Cardinality.COLLECTION, request.getCardinality());
assertEquals(properties, request.getProperties());
assertEquals(properties, request.getQueryProperties());
assertEquals("fooValue", request.getProperty("foo"));
assertTrue(request.<Boolean>getProperty("someBoolean"));
assertNull(request.getProperty("other"));
......
......@@ -68,7 +68,7 @@ public class EntityResourceProviderTest {
Request request = requestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(requestProperties, request.getProperties());
assertEquals(requestProperties, request.getQueryProperties());
verify(typeSystem, queryFactory, query);
}
......@@ -138,7 +138,7 @@ public class EntityResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals("name:entity*", request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(0, request.getProperties().size());
assertEquals(0, request.getQueryProperties().size());
verify(typeSystem, queryFactory, query);
}
......@@ -169,7 +169,7 @@ public class EntityResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals("name:entity*", request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(0, request.getProperties().size());
assertEquals(0, request.getQueryProperties().size());
verify(typeSystem, queryFactory, query);
}
......
......@@ -74,8 +74,8 @@ public class EntityTagResourceProviderTest {
Request request = requestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(2, request.getProperties().size());
assertEquals("taxonomyName.termName", request.getProperties().get("name"));
assertEquals(2, request.getQueryProperties().size());
assertEquals("taxonomyName.termName", request.getQueryProperties().get("name"));
assertEquals(Request.Cardinality.INSTANCE, request.getCardinality());
verify(typeSystem, queryFactory, query);
......@@ -236,7 +236,7 @@ public class EntityTagResourceProviderTest {
provider.createResource(userRequest);
Request termRequest = termRequestCapture.getValue();
Map<String, Object> termRequestProps = termRequest.getProperties();
Map<String, Object> termRequestProps = termRequest.getQueryProperties();
assertEquals(1, termRequestProps.size());
TermPath termPath = (TermPath) termRequestProps.get("termPath");
assertEquals("testTaxonomy.termName", termPath.getFullyQualifiedName());
......@@ -408,7 +408,7 @@ public class EntityTagResourceProviderTest {
Request termRequest1 = termRequestCapture1.getValue();
assertNull(termRequest1.getQueryString());
assertEquals(Request.Cardinality.INSTANCE, termRequest1.getCardinality());
Map<String, Object> termRequestProps = termRequest1.getProperties();
Map<String, Object> termRequestProps = termRequest1.getQueryProperties();
assertEquals(1, termRequestProps.size());
TermPath termPath = (TermPath) termRequestProps.get("termPath");
assertEquals("testTaxonomy.termName1", termPath.getFullyQualifiedName());
......@@ -416,7 +416,7 @@ public class EntityTagResourceProviderTest {
Request termRequest2 = termRequestCapture2.getValue();
assertNull(termRequest2.getQueryString());
assertEquals(Request.Cardinality.INSTANCE, termRequest2.getCardinality());
Map<String, Object> termRequestProps2 = termRequest2.getProperties();
Map<String, Object> termRequestProps2 = termRequest2.getQueryProperties();
assertEquals(1, termRequestProps2.size());
TermPath termPath2 = (TermPath) termRequestProps2.get("termPath");
assertEquals("testTaxonomy.termName2", termPath2.getFullyQualifiedName());
......
......@@ -41,7 +41,7 @@ public class InstanceRequestTest {
Request request = new InstanceRequest(properties);
assertEquals(Request.Cardinality.INSTANCE, request.getCardinality());
assertEquals(properties, request.getProperties());
assertEquals(properties, request.getQueryProperties());
assertEquals("fooValue", request.getProperty("foo"));
assertTrue(request.<Boolean>getProperty("someBoolean"));
assertNull(request.getProperty("other"));
......
......@@ -40,7 +40,7 @@ import static org.testng.Assert.assertTrue;
*/
public class TaxonomyResourceProviderTest {
@Test
public void testGetResource() throws Exception {
public void testGetResourceById() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
......@@ -73,13 +73,13 @@ public class TaxonomyResourceProviderTest {
Request request = requestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(requestProperties, request.getProperties());
assertEquals(requestProperties, request.getQueryProperties());
verify(typeSystem, queryFactory, query);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testGetResource_404() throws Exception {
public void testGetResourceById_404() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
......@@ -143,7 +143,7 @@ public class TaxonomyResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals("name:taxonomy*", request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(0, request.getProperties().size());
assertEquals(0, request.getQueryProperties().size());
verify(typeSystem, queryFactory, query);
}
......@@ -174,7 +174,7 @@ public class TaxonomyResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals("name:taxonomy*", request.getQueryString());
assertEquals(0, request.getAdditionalSelectProperties().size());
assertEquals(0, request.getProperties().size());
assertEquals(0, request.getQueryProperties().size());
verify(typeSystem, queryFactory, query);
}
......@@ -262,7 +262,7 @@ public class TaxonomyResourceProviderTest {
Request request = requestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(requestProperties, request.getProperties());
assertEquals(requestProperties, request.getQueryProperties());
verify(typeSystem, queryFactory, query);
}
......@@ -323,13 +323,13 @@ public class TaxonomyResourceProviderTest {
assertNull(getRequest.getQueryString());
assertEquals(getRequest.getAdditionalSelectProperties().size(), 1);
assertTrue(getRequest.getAdditionalSelectProperties().contains("id"));
assertEquals(getRequest.getProperties().get("name"), "testTaxonomy");
assertEquals(getRequest.getQueryProperties().get("name"), "testTaxonomy");
Request deleteRequest = deleteRequestCapture.getValue();
assertNull(deleteRequest.getQueryString());
assertEquals(deleteRequest.getAdditionalSelectProperties().size(), 1);
assertTrue(deleteRequest.getAdditionalSelectProperties().contains("id"));
assertEquals(deleteRequest.getProperties().get("name"), "testTaxonomy");
assertEquals(deleteRequest.getQueryProperties().get("name"), "testTaxonomy");
ResourceDefinition resourceDefinition = resourceDefinitionCapture.getValue();
assertTrue(resourceDefinition instanceof TaxonomyResourceDefinition);
......@@ -360,6 +360,102 @@ public class TaxonomyResourceProviderTest {
provider.deleteResourceById(userRequest);
}
@Test
public void testUpdateResourceById() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
Capture<Request> taxonomyRequestCapture = newCapture();
Map<String, Object> requestProperties = new HashMap<>();
requestProperties.put("name", "testTaxonomy");
Map<String, Object> requestUpdateProperties = new HashMap<>();
requestUpdateProperties.put("description", "updatedValue");
Request userRequest = new InstanceRequest(requestProperties, requestUpdateProperties);
Collection<Map<String, Object>> queryResult = new ArrayList<>();
Map<String, Object> queryResultRow = new HashMap<>();
queryResult.add(queryResultRow);
queryResultRow.put("name", "testTaxonomy");
// mock expectations
// term update
expect(queryFactory.createTaxonomyQuery(capture(taxonomyRequestCapture))).andReturn(query);
expect(query.execute(requestUpdateProperties)).andReturn(queryResult);
replay(typeSystem, queryFactory, query);
// instantiate resource provider and invoke method being tested
TaxonomyResourceProvider provider = new TaxonomyResourceProvider(typeSystem);
provider.setQueryFactory(queryFactory);
provider.updateResourceById(userRequest);
Request request = taxonomyRequestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(request.getQueryProperties().size(), 1);
assertEquals(request.getQueryProperties().get("name"), "testTaxonomy");
assertEquals(request.getUpdateProperties().size(), 1);
assertEquals(request.getUpdateProperties().get("description"), "updatedValue");
verify(typeSystem, queryFactory, query);
}
@Test(expectedExceptions = InvalidPayloadException.class)
public void testUpdateResourceById_attemptNameChange() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
Capture<Request> taxonomyRequestCapture = newCapture();
Map<String, Object> requestProperties = new HashMap<>();
requestProperties.put("name", "testTaxonomy");
Map<String, Object> requestUpdateProperties = new HashMap<>();
requestUpdateProperties.put("name", "notCurrentlySupported");
Request userRequest = new InstanceRequest(requestProperties, requestUpdateProperties);
Collection<Map<String, Object>> queryResult = new ArrayList<>();
Map<String, Object> queryResultRow = new HashMap<>();
queryResult.add(queryResultRow);
queryResultRow.put("name", "testTaxonomy");
// mock expectations
// term update
expect(queryFactory.createTaxonomyQuery(capture(taxonomyRequestCapture))).andReturn(query);
expect(query.execute(requestUpdateProperties)).andReturn(queryResult);
replay(typeSystem, queryFactory, query);
// instantiate resource provider and invoke method being tested
TaxonomyResourceProvider provider = new TaxonomyResourceProvider(typeSystem);
provider.setQueryFactory(queryFactory);
provider.updateResourceById(userRequest);
verify(typeSystem, queryFactory, query);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testUpdateResourceById_404() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
Capture<Request> taxonomyRequestCapture = newCapture();
Map<String, Object> requestProperties = new HashMap<>();
requestProperties.put("name", "testTaxonomy");
Map<String, Object> requestUpdateProperties = new HashMap<>();
requestUpdateProperties.put("description", "updated");
Request userRequest = new InstanceRequest(requestProperties, requestUpdateProperties);
// mock expectations
// term update
expect(queryFactory.createTaxonomyQuery(capture(taxonomyRequestCapture))).andReturn(query);
expect(query.execute(requestUpdateProperties)).andReturn(Collections.<Map<String, Object>>emptyList());
replay(typeSystem, queryFactory, query);
// instantiate resource provider and invoke method being tested
TaxonomyResourceProvider provider = new TaxonomyResourceProvider(typeSystem);
provider.setQueryFactory(queryFactory);
provider.updateResourceById(userRequest);
verify(typeSystem, queryFactory, query);
}
private static class TestTaxonomyResourceProvider extends TaxonomyResourceProvider {
private final TermResourceProvider termResourceProvider;
......
......@@ -25,7 +25,6 @@ import org.apache.atlas.catalog.exception.ResourceNotFoundException;
import org.apache.atlas.catalog.query.AtlasQuery;
import org.apache.atlas.catalog.query.QueryFactory;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.testng.annotations.Test;
......@@ -41,7 +40,7 @@ import static org.testng.Assert.assertTrue;
*/
public class TermResourceProviderTest {
@Test
public void testGetResource() throws Exception {
public void testGetResourceById() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
......@@ -83,15 +82,15 @@ public class TermResourceProviderTest {
Request request = requestCapture.getValue();
assertNull(request.getQueryString());
assertEquals(request.getAdditionalSelectProperties().size(), 0);
assertEquals(request.getProperties().size(), 2);
assertEquals(request.getProperties().get("termPath"), termPath);
assertEquals(request.getProperties().get("name"), termPath.getFullyQualifiedName());
assertEquals(request.getQueryProperties().size(), 2);
assertEquals(request.getQueryProperties().get("termPath"), termPath);
assertEquals(request.getQueryProperties().get("name"), termPath.getFullyQualifiedName());
verify(typeSystem, queryFactory, query);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testGetResource_404() throws Exception {
public void testGetResourceById_404() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
......@@ -172,7 +171,7 @@ public class TermResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals(request.getQueryString(), "name:taxonomy*");
assertEquals(request.getAdditionalSelectProperties().size(), 0);
assertEquals(request.getProperties().size(), 1);
assertEquals(request.getQueryProperties().size(), 1);
verify(typeSystem, queryFactory, query);
}
......@@ -208,7 +207,7 @@ public class TermResourceProviderTest {
Request request = requestCapture.getValue();
assertEquals(request.getQueryString(), "name:taxonomy*");
assertEquals(request.getAdditionalSelectProperties().size(), 0);
assertEquals(request.getProperties().size(), 1);
assertEquals(request.getQueryProperties().size(), 1);
verify(typeSystem, queryFactory, query);
}
......@@ -273,7 +272,7 @@ public class TermResourceProviderTest {
provider.createResource(userRequest);
Request taxonomyRequest = taxonomyRequestCapture.getValue();
Map<String, Object> taxonomyRequestProps = taxonomyRequest.getProperties();
Map<String, Object> taxonomyRequestProps = taxonomyRequest.getQueryProperties();
assertEquals(taxonomyRequestProps.size(), 1);
assertEquals(taxonomyRequestProps.get("name"), "testTaxonomy");
assertEquals(taxonomyRequest.getAdditionalSelectProperties().size(), 1);
......@@ -459,7 +458,7 @@ public class TermResourceProviderTest {
provider.deleteResourceById(userRequest);
Request taxonomyRequest = taxonomyRequestCapture.getValue();
assertEquals(taxonomyRequest.getProperties().get("name"), "testTaxonomy");
assertEquals(taxonomyRequest.getQueryProperties().get("name"), "testTaxonomy");
assertEquals(taxonomyRequest.getAdditionalSelectProperties().size(), 1);
assertTrue(taxonomyRequest.getAdditionalSelectProperties().contains("id"));
......@@ -468,6 +467,57 @@ public class TermResourceProviderTest {
verify(taxonomyResourceProvider, entityResourceProvider, entityTagResourceProvider, typeSystem, queryFactory, query);
}
@Test
public void testUpdateResourceById() throws Exception {
AtlasTypeSystem typeSystem = createStrictMock(AtlasTypeSystem.class);
QueryFactory queryFactory = createStrictMock(QueryFactory.class);
AtlasQuery query = createStrictMock(AtlasQuery.class);
Capture<Request> termRequestCapture = newCapture();
Capture<Request> tagRequestCapture = newCapture();
TermPath termPath = new TermPath("testTaxonomy", "termName");
Map<String, Object> requestProperties = new HashMap<>();
requestProperties.put("termPath", termPath);
Map<String, Object> requestUpdateProperties = new HashMap<>();
requestUpdateProperties.put("description", "updatedValue");
Request userRequest = new InstanceRequest(requestProperties, requestUpdateProperties);
Collection<Map<String, Object>> queryResult = new ArrayList<>();
Map<String, Object> queryResultRow = new HashMap<>();
queryResult.add(queryResultRow);
queryResultRow.put("name", "testTaxonomy.termName");
// mock expectations
// term update
expect(queryFactory.createTermQuery(capture(termRequestCapture))).andReturn(query);
expect(query.execute(requestUpdateProperties)).andReturn(queryResult);
// tag updates
expect(queryFactory.createEntityTagQuery(capture(tagRequestCapture))).andReturn(query);
// query response isn't used so just returning null
expect(query.execute(requestUpdateProperties)).andReturn(null);
replay(typeSystem, queryFactory, query);
TermResourceProvider provider = new TermResourceProvider(typeSystem);
provider.setQueryFactory(queryFactory);
provider.updateResourceById(userRequest);
Request request = termRequestCapture.getValue();
assertNull(request.getQueryString());
assertTrue(request.getAdditionalSelectProperties().isEmpty());
assertEquals(request.getQueryProperties().size(), 2);
assertEquals(request.getQueryProperties().get("termPath"), termPath);
assertEquals(request.getQueryProperties().get("name"), termPath.getFullyQualifiedName());
Request tagRequest = tagRequestCapture.getValue();
assertEquals(tagRequest.getQueryString(), "name:testTaxonomy.termName");
assertEquals(tagRequest.getQueryProperties().size(), 1);
assertEquals(tagRequest.getQueryProperties().get("id"), "*");
verify(typeSystem, queryFactory, query);
}
private static class TestTermResourceProvider extends TermResourceProvider {
private ResourceProvider testTaxonomyResourceProvider;
......
......@@ -308,4 +308,25 @@ public class VertexWrapperTest {
assertTrue(vWrapper.isPropertyRemoved("foo"));
assertFalse(vWrapper.isPropertyRemoved("bar"));
}
@Test
public void testSetProperty() {
String testType = "testType";
String cleanPropName = "prop1";
String qualifiedPropName = "test.prop1";
String propValue = "newValue";
Vertex v = createStrictMock(Vertex.class);
PropertyMapper propertyMapper = createStrictMock(PropertyMapper.class);
expect(v.<String>getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY)).andReturn(testType);
expect(propertyMapper.toFullyQualifiedName(cleanPropName, testType)).andReturn(qualifiedPropName);
v.setProperty(qualifiedPropName, propValue);
replay(v, propertyMapper);
VertexWrapper vWrapper = new VertexWrapper(
v, propertyMapper, Collections.<String, PropertyValueFormatter>emptyMap());
vWrapper.setProperty(cleanPropName, propValue);
verify(v, propertyMapper);
}
}
......@@ -66,7 +66,7 @@ public class EntityResourceDefinitionTest {
Request request = new InstanceRequest(Collections.<String, Object>emptyMap());
ResourceDefinition entityDefinition = new EntityResourceDefinition();
entityDefinition.validate(request);
entityDefinition.validateCreatePayload(request);
}
// Because we don't currently support entity creation, no properties are registered
......
......@@ -68,7 +68,7 @@ public class EntityTagResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition entityTagDefinition = new EntityTagResourceDefinition();
entityTagDefinition.validate(request);
entityTagDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -77,7 +77,7 @@ public class EntityTagResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition entityTagDefinition = new EntityTagResourceDefinition();
entityTagDefinition.validate(request);
entityTagDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -89,7 +89,7 @@ public class EntityTagResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition entityTagDefinition = new EntityTagResourceDefinition();
entityTagDefinition.validate(request);
entityTagDefinition.validateCreatePayload(request);
}
@Test
......
......@@ -68,7 +68,7 @@ public class TaxonomyResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition taxonomyDefinition = new TaxonomyResourceDefinition();
taxonomyDefinition.validate(request);
taxonomyDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -79,7 +79,7 @@ public class TaxonomyResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition taxonomyDefinition = new TaxonomyResourceDefinition();
taxonomyDefinition.validate(request);
taxonomyDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -91,7 +91,7 @@ public class TaxonomyResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition taxonomyDefinition = new TaxonomyResourceDefinition();
taxonomyDefinition.validate(request);
taxonomyDefinition.validateCreatePayload(request);
}
@Test
......
......@@ -69,7 +69,7 @@ public class TermResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition termDefinition = new TermResourceDefinition();
termDefinition.validate(request);
termDefinition.validateCreatePayload(request);
}
@Test
......@@ -80,7 +80,7 @@ public class TermResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition termDefinition = new TermResourceDefinition();
termDefinition.validate(request);
termDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -93,7 +93,7 @@ public class TermResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition termDefinition = new TermResourceDefinition();
termDefinition.validate(request);
termDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -104,7 +104,7 @@ public class TermResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition termDefinition = new TermResourceDefinition();
termDefinition.validate(request);
termDefinition.validateCreatePayload(request);
}
@Test(expectedExceptions = InvalidPayloadException.class)
......@@ -116,7 +116,7 @@ public class TermResourceDefinitionTest {
Request request = new InstanceRequest(properties);
ResourceDefinition termDefinition = new TermResourceDefinition();
termDefinition.validate(request);
termDefinition.validateCreatePayload(request);
}
@Test
......
......@@ -25,12 +25,15 @@ import com.tinkerpop.pipes.Pipe;
import org.apache.atlas.catalog.Request;
import org.apache.atlas.catalog.VertexWrapper;
import org.apache.atlas.catalog.definition.ResourceDefinition;
import org.apache.atlas.repository.Constants;
import org.easymock.Capture;
import org.testng.annotations.Test;
import java.util.*;
import static org.easymock.EasyMock.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/**
......@@ -102,10 +105,6 @@ public class AtlasEntityQueryTest {
vertex1, vertex1Wrapper);
}
@Test
public void testExecute_Collection_rollbackOnException() throws Exception {
TitanGraph graph = createStrictMock(TitanGraph.class);
......@@ -150,6 +149,80 @@ public class AtlasEntityQueryTest {
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline);
}
@Test
public void testExecute_Collection_update() throws Exception {
TitanGraph graph = createStrictMock(TitanGraph.class);
QueryExpression expression = createStrictMock(QueryExpression.class);
ResourceDefinition resourceDefinition = createStrictMock(ResourceDefinition.class);
Request request = createStrictMock(Request.class);
GremlinPipeline initialPipeline = createStrictMock(GremlinPipeline.class);
Pipe queryPipe = createStrictMock(Pipe.class);
Pipe expressionPipe = createStrictMock(Pipe.class);
Pipe notDeletedPipe = createStrictMock(Pipe.class);
GremlinPipeline rootPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline queryPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline expressionPipeline = createStrictMock(GremlinPipeline.class);
GremlinPipeline notDeletedPipeline = createStrictMock(GremlinPipeline.class);
Vertex vertex1 = createStrictMock(Vertex.class);
VertexWrapper vertex1Wrapper = createStrictMock(VertexWrapper.class);
Capture<Long> modifiedTimestampCapture = newCapture();
List<Vertex> results = new ArrayList<>();
results.add(vertex1);
Map<String, Object> vertex1PropertyMap = new HashMap<>();
vertex1PropertyMap.put("prop1", "prop1.value1");
vertex1PropertyMap.put("prop2", "prop2.value1");
Map<String, Object> filteredVertex1PropertyMap = new HashMap<>();
filteredVertex1PropertyMap.put("prop1", "prop1.value1");
Map<String, Object> updateProperties = new HashMap<>();
updateProperties.put("prop3", "newValue");
// mock expectations
expect(initialPipeline.add(queryPipe)).andReturn(queryPipeline);
expect(initialPipeline.add(notDeletedPipe)).andReturn(notDeletedPipeline);
expect(initialPipeline.as("root")).andReturn(rootPipeline);
expect(expression.asPipe()).andReturn(expressionPipe);
expect(rootPipeline.add(expressionPipe)).andReturn(expressionPipeline);
expect(expressionPipeline.back("root")).andReturn(rootPipeline);
expect(rootPipeline.toList()).andReturn(results);
graph.commit();
vertex1Wrapper.setProperty("prop3", "newValue");
vertex1Wrapper.setProperty(eq(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY), capture(modifiedTimestampCapture));
expect(vertex1Wrapper.getPropertyMap()).andReturn(vertex1PropertyMap);
expect(resourceDefinition.filterProperties(request, vertex1PropertyMap)).andReturn(filteredVertex1PropertyMap);
expect(resourceDefinition.resolveHref(filteredVertex1PropertyMap)).andReturn("/foo/bar");
expect(request.getCardinality()).andReturn(Request.Cardinality.COLLECTION);
replay(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
// end mock expectations
AtlasEntityQuery query = new TestAtlasEntityQuery(expression, resourceDefinition, request,
initialPipeline, queryPipe, notDeletedPipe, graph, vertex1Wrapper);
long startTime = System.currentTimeMillis();
// invoke method being tested
Collection<Map<String, Object>> queryResults = query.execute(updateProperties);
long endTime = System.currentTimeMillis();
assertEquals(queryResults.size(), 1);
Map<String, Object> queryResultMap = queryResults.iterator().next();
assertEquals(queryResultMap.size(), 2);
assertEquals(queryResultMap.get("prop1"), "prop1.value1");
assertEquals(queryResultMap.get("href"), "/foo/bar");
long modifiedTimestamp = modifiedTimestampCapture.getValue();
assertTrue(modifiedTimestamp >= startTime && modifiedTimestamp <= endTime);
verify(graph, expression, resourceDefinition, request, initialPipeline, queryPipe, expressionPipe,
notDeletedPipe, rootPipeline, queryPipeline, expressionPipeline, notDeletedPipeline,
vertex1, vertex1Wrapper);
}
private class TestAtlasEntityQuery extends AtlasEntityQuery {
private final GremlinPipeline initialPipeline;
private final Pipe queryPipe;
......
......@@ -22,6 +22,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset
ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags)
ALL CHANGES:
ATLAS-794 Business Catalog Update (jspeidel via yhemanth)
ATLAS-837 Enhance Sqoop addon to handle export operation (venkatnrangan via shwethags)
ATLAS-869 Make LDAP/AD properties to be configurable. (nixonrodrigues via yhemanth)
ATLAS-730 Change titan hbase table name (svimal2106 via sumasai )
......
......@@ -73,6 +73,15 @@ public abstract class BaseService {
}
}
protected void updateResource(ResourceProvider provider, Request request) throws CatalogException {
initializeGraphTransaction();
try {
provider.updateResourceById(request);
} catch (RuntimeException e) {
throw wrapRuntimeException(e);
}
}
protected void deleteResource(ResourceProvider provider, Request request) throws CatalogException {
initializeGraphTransaction();
try {
......
......@@ -90,6 +90,23 @@ public class TaxonomyService extends BaseService {
new Results(ui.getRequestUri().toString(), 201)).build();
}
@PUT
@Path("{taxonomyName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
public Response updateTaxonomy(String body,
@Context HttpHeaders headers,
@Context UriInfo ui,
@PathParam("taxonomyName") String taxonomyName) throws CatalogException {
Map<String, Object> queryProperties = new HashMap<>();
queryProperties.put("name", taxonomyName);
Map<String, Object> updateProperties = parsePayload(body);
updateResource(taxonomyResourceProvider, new InstanceRequest(queryProperties, updateProperties));
return Response.status(Response.Status.OK).entity(
new Results(ui.getRequestUri().toString(), 200)).build();
}
@DELETE
@Path("{taxonomyName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
......@@ -207,6 +224,46 @@ public class TaxonomyService extends BaseService {
new Results(ui.getRequestUri().toString(), 201)).build();
}
@PUT
@Path("{taxonomyName}/terms/{termName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
public Response updateTerm(String body,
@Context HttpHeaders headers,
@Context UriInfo ui,
@PathParam("taxonomyName") String taxonomyName,
@PathParam("termName") String termName) throws CatalogException {
Map<String, Object> queryProperties = new HashMap<>();
queryProperties.put("termPath", new TermPath(taxonomyName, termName));
Map<String, Object> updateProperties = parsePayload(body);
updateResource(termResourceProvider, new InstanceRequest(queryProperties, updateProperties));
return Response.status(Response.Status.OK).entity(
new Results(ui.getRequestUri().toString(), 200)).build();
}
@PUT
@Path("{taxonomyName}/terms/{termName}/{remainder:.*}")
@Produces(Servlets.JSON_MEDIA_TYPE)
public Response updateSubTerm(String body,
@Context HttpHeaders headers,
@Context UriInfo ui,
@PathParam("taxonomyName") String taxonomyName,
@PathParam("termName") String termName,
@PathParam("remainder") String remainder) throws CatalogException {
Map<String, Object> queryProperties = new HashMap<>();
queryProperties.put("termPath", new TermPath(taxonomyName, String.format("%s%s", termName,
remainder.replaceAll("/?terms/?([.]*)", "$1."))));
Map<String, Object> updateProperties = parsePayload(body);
updateResource(termResourceProvider, new InstanceRequest(queryProperties, updateProperties));
return Response.status(Response.Status.OK).entity(
new Results(ui.getRequestUri().toString(), 200)).build();
}
@DELETE
@Path("{taxonomyName}/terms/{termName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
......
......@@ -65,7 +65,7 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
Map<String, Object> requestProperties = request.getProperties();
Map<String, Object> requestProperties = request.getQueryProperties();
assertEquals(requestProperties.size(), 1);
assertEquals(requestProperties.get("name"), taxonomyName);
......@@ -105,7 +105,7 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertTrue(request.getProperties().isEmpty());
assertTrue(request.getQueryProperties().isEmpty());
assertEquals(request.getQueryString(), "name:testTaxonomy");
assertEquals(response.getStatus(), 200);
......@@ -137,9 +137,9 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 2);
assertEquals(request.getProperties().get("name"), "testTaxonomy");
assertEquals(request.getProperties().get("description"), "test description");
assertEquals(request.getQueryProperties().size(), 2);
assertEquals(request.getQueryProperties().get("name"), "testTaxonomy");
assertEquals(request.getQueryProperties().get("description"), "test description");
assertNull(request.getQueryString());
assertEquals(response.getStatus(), 201);
......@@ -172,8 +172,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
assertEquals(request.getProperties().get("name"), "testTaxonomy");
assertEquals(request.getQueryProperties().size(), 1);
assertEquals(request.getQueryProperties().get("name"), "testTaxonomy");
assertNull(request.getQueryString());
assertEquals(response.getStatus(), 200);
......@@ -212,9 +212,9 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
Map<String, Object> requestProperties = request.getProperties();
Map<String, Object> requestProperties = request.getQueryProperties();
assertEquals(requestProperties.size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTaxonomy.termName");
assertEquals(response.getStatus(), 200);
......@@ -253,8 +253,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 1);
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy");
assertEquals(request.getQueryString(), "name:testTaxonomy.testTerm");
......@@ -301,8 +301,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 1);
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm.testTerm2");
assertNull(request.getQueryString());
......@@ -352,8 +352,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 1);
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm.testTerm2.");
assertEquals(request.getQueryString(), "name:testTaxonomy.testTerm.testTerm2.testTerm3");
......@@ -389,9 +389,9 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 2);
assertEquals(request.getProperties().get("description"), "test description");
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 2);
assertEquals(request.getQueryProperties().get("description"), "test description");
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm");
assertNull(request.getQueryString());
......@@ -428,9 +428,9 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 2);
assertEquals(request.getProperties().get("description"), "test description");
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 2);
assertEquals(request.getQueryProperties().get("description"), "test description");
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm.testTerm2");
assertNull(request.getQueryString());
......@@ -464,8 +464,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 1);
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm");
assertNull(request.getQueryString());
......@@ -499,8 +499,8 @@ public class TaxonomyServiceTest {
assertTrue(service.wasTransactionInitialized());
Request request = requestCapture.getValue();
assertEquals(request.getProperties().size(), 1);
TermPath termPath = (TermPath) request.getProperties().get("termPath");
assertEquals(request.getQueryProperties().size(), 1);
TermPath termPath = (TermPath) request.getQueryProperties().get("termPath");
assertEquals(termPath.getFullyQualifiedName(), "testTaxonomy.testTerm.testTerm2");
assertNull(request.getQueryString());
......
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