Commit d64112d6 by Shwetha GS

ATLAS-957 Atlas is not capturing topologies that have $ in the data payload (shwethags)

parent 7cc34713
...@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES: ...@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
ALL CHANGES: ALL CHANGES:
ATLAS-957 Atlas is not capturing topologies that have $ in the data payload (shwethags)
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-1027 Atlas hooks should use properties from atlas-application.properties, instead of component's configuration (mneethiraj via sumasai) ATLAS-1027 Atlas hooks should use properties from atlas-application.properties, instead of component's configuration (mneethiraj via sumasai)
ATLAS-1030 Add instrumentation to measure performance: REST API (mneethiraj via sumasai) ATLAS-1030 Add instrumentation to measure performance: REST API (mneethiraj via sumasai)
......
...@@ -140,9 +140,9 @@ public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategi ...@@ -140,9 +140,9 @@ public class DefaultGraphPersistenceStrategy implements GraphPersistenceStrategi
TypeSystem.IdType idType = TypeSystem.getInstance().getIdType(); TypeSystem.IdType idType = TypeSystem.getInstance().getIdType();
if (dataType.getName().equals(idType.getName())) { if (dataType.getName().equals(idType.getName())) {
structInstance.set(idType.typeNameAttrName(), structVertex.getProperty(typeAttributeName())); structInstance.set(idType.typeNameAttrName(), GraphHelper.getProperty(structVertex, typeAttributeName()));
structInstance.set(idType.idAttrName(), structVertex.getProperty(idAttributeName())); structInstance.set(idType.idAttrName(), GraphHelper.getProperty(structVertex, idAttributeName()));
structInstance.set(idType.stateAttrName(), structVertex.getProperty(stateAttributeName())); structInstance.set(idType.stateAttrName(), GraphHelper.getProperty(structVertex, stateAttributeName()));
} else { } else {
metadataRepository.getGraphToInstanceMapper() metadataRepository.getGraphToInstanceMapper()
.mapVertexToInstance(structVertex, structInstance, structType.fieldMapping().fields); .mapVertexToInstance(structVertex, structInstance, structType.fieldMapping().fields);
......
...@@ -36,6 +36,7 @@ import org.apache.atlas.query.QueryParser; ...@@ -36,6 +36,7 @@ import org.apache.atlas.query.QueryParser;
import org.apache.atlas.query.QueryProcessor; import org.apache.atlas.query.QueryProcessor;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.MetadataRepository; import org.apache.atlas.repository.MetadataRepository;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.graph.GraphProvider; import org.apache.atlas.repository.graph.GraphProvider;
import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONException;
...@@ -94,11 +95,11 @@ public class GraphBackedDiscoveryService implements DiscoveryService { ...@@ -94,11 +95,11 @@ public class GraphBackedDiscoveryService implements DiscoveryService {
Vertex vertex = result.getElement(); Vertex vertex = result.getElement();
JSONObject row = new JSONObject(); JSONObject row = new JSONObject();
String guid = vertex.getProperty(Constants.GUID_PROPERTY_KEY); String guid = GraphHelper.getIdFromVertex(vertex);
if (guid != null) { //Filter non-class entities if (guid != null) { //Filter non-class entities
try { try {
row.put("guid", guid); row.put("guid", guid);
row.put(AtlasClient.TYPENAME, vertex.<String>getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY)); row.put(AtlasClient.TYPENAME, GraphHelper.getTypeName(vertex));
row.put(SCORE, result.getScore()); row.put(SCORE, result.getScore());
} catch (JSONException e) { } catch (JSONException e) {
LOG.error("Unable to create response", e); LOG.error("Unable to create response", e);
......
...@@ -154,7 +154,7 @@ public abstract class DeleteHandler { ...@@ -154,7 +154,7 @@ public abstract class DeleteHandler {
if (valueTypeCategory == DataTypes.TypeCategory.STRUCT || if (valueTypeCategory == DataTypes.TypeCategory.STRUCT ||
valueTypeCategory == DataTypes.TypeCategory.CLASS) { valueTypeCategory == DataTypes.TypeCategory.CLASS) {
List<String> keys = instanceVertex.getProperty(propertyName); List<String> keys = GraphHelper.getProperty(instanceVertex, propertyName);
if (keys != null) { if (keys != null) {
for (String key : keys) { for (String key : keys) {
String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key); String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key);
...@@ -286,7 +286,7 @@ public abstract class DeleteHandler { ...@@ -286,7 +286,7 @@ public abstract class DeleteHandler {
case ARRAY: case ARRAY:
//If its array attribute, find the right edge between the two vertices and update array property //If its array attribute, find the right edge between the two vertices and update array property
List<String> elements = outVertex.getProperty(propertyName); List<String> elements = GraphHelper.getProperty(outVertex, propertyName);
if (elements != null) { if (elements != null) {
elements = new ArrayList<>(elements); //Make a copy, else list.remove reflects on titan.getProperty() elements = new ArrayList<>(elements); //Make a copy, else list.remove reflects on titan.getProperty()
for (String elementEdgeId : elements) { for (String elementEdgeId : elements) {
...@@ -327,12 +327,12 @@ public abstract class DeleteHandler { ...@@ -327,12 +327,12 @@ public abstract class DeleteHandler {
case MAP: case MAP:
//If its map attribute, find the right edge between two vertices and update map property //If its map attribute, find the right edge between two vertices and update map property
List<String> keys = outVertex.getProperty(propertyName); List<String> keys = GraphHelper.getProperty(outVertex, propertyName);
if (keys != null) { if (keys != null) {
keys = new ArrayList<>(keys); //Make a copy, else list.remove reflects on titan.getProperty() keys = new ArrayList<>(keys); //Make a copy, else list.remove reflects on titan.getProperty()
for (String key : keys) { for (String key : keys) {
String keyPropertyName = GraphHelper.getQualifiedNameForMapKey(propertyName, key); String keyPropertyName = GraphHelper.getQualifiedNameForMapKey(propertyName, key);
String mapEdgeId = outVertex.getProperty(keyPropertyName); String mapEdgeId = GraphHelper.getProperty(outVertex, keyPropertyName);
Edge mapEdge = graphHelper.getEdgeByEdgeId(outVertex, keyPropertyName, mapEdgeId); Edge mapEdge = graphHelper.getEdgeByEdgeId(outVertex, keyPropertyName, mapEdgeId);
Vertex mapVertex = mapEdge.getVertex(Direction.IN); Vertex mapVertex = mapEdge.getVertex(Direction.IN);
if (mapVertex.getId().toString().equals(inVertex.getId().toString())) { if (mapVertex.getId().toString().equals(inVertex.getId().toString())) {
......
...@@ -19,7 +19,6 @@ package org.apache.atlas.repository.graph; ...@@ -19,7 +19,6 @@ package org.apache.atlas.repository.graph;
import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.Vertex;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.typesystem.ITypedInstance; import org.apache.atlas.typesystem.ITypedInstance;
import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.types.AttributeInfo; import org.apache.atlas.typesystem.types.AttributeInfo;
...@@ -51,7 +50,7 @@ public class FullTextMapper { ...@@ -51,7 +50,7 @@ public class FullTextMapper {
} }
public String mapRecursive(Vertex instanceVertex, boolean followReferences) throws AtlasException { public String mapRecursive(Vertex instanceVertex, boolean followReferences) throws AtlasException {
String guid = instanceVertex.getProperty(Constants.GUID_PROPERTY_KEY); String guid = GraphHelper.getIdFromVertex(instanceVertex);
ITypedReferenceableInstance typedReference; ITypedReferenceableInstance typedReference;
if (instanceCache.containsKey(guid)) { if (instanceCache.containsKey(guid)) {
typedReference = instanceCache.get(guid); typedReference = instanceCache.get(guid);
......
...@@ -115,7 +115,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -115,7 +115,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
if (aInfo.name.startsWith(Constants.INTERNAL_PROPERTY_KEY_PREFIX)) { if (aInfo.name.startsWith(Constants.INTERNAL_PROPERTY_KEY_PREFIX)) {
return aInfo.name; return aInfo.name;
} }
return GraphHelper.getQualifiedFieldName(dataType, aInfo.name); return GraphHelper.encodePropertyKey(GraphHelper.getQualifiedFieldName(dataType, aInfo.name));
} }
public String getFieldNameInVertex(IDataType<?> dataType, String attrName) throws AtlasException { public String getFieldNameInVertex(IDataType<?> dataType, String attrName) throws AtlasException {
...@@ -168,7 +168,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -168,7 +168,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
Constants.ENTITY_TYPE_PROPERTY_KEY, entityType, Constants.ENTITY_TYPE_PROPERTY_KEY, entityType,
Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name()); Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
String guid = instanceVertex.getProperty(Constants.GUID_PROPERTY_KEY); String guid = GraphHelper.getIdFromVertex(instanceVertex);
return graphToInstanceMapper.mapGraphToTypedInstance(guid, instanceVertex); return graphToInstanceMapper.mapGraphToTypedInstance(guid, instanceVertex);
} }
...@@ -185,7 +185,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -185,7 +185,7 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
ArrayList<String> entityList = new ArrayList<>(); ArrayList<String> entityList = new ArrayList<>();
while (results.hasNext()) { while (results.hasNext()) {
Vertex vertex = results.next(); Vertex vertex = results.next();
entityList.add(vertex.<String>getProperty(Constants.GUID_PROPERTY_KEY)); entityList.add(GraphHelper.getIdFromVertex(vertex));
} }
return entityList; return entityList;
......
...@@ -227,7 +227,7 @@ public class GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChang ...@@ -227,7 +227,7 @@ public class GraphBackedSearchIndexer implements SearchIndexer, ActiveStateChang
} }
private void createIndexForAttribute(TitanManagement management, String typeName, AttributeInfo field) { private void createIndexForAttribute(TitanManagement management, String typeName, AttributeInfo field) {
final String propertyName = typeName + "." + field.name; final String propertyName = GraphHelper.encodePropertyKey(typeName + "." + field.name);
switch (field.dataType().getTypeCategory()) { switch (field.dataType().getTypeCategory()) {
case PRIMITIVE: case PRIMITIVE:
Cardinality cardinality = getCardinality(field.multiplicity); Cardinality cardinality = getCardinality(field.multiplicity);
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
package org.apache.atlas.repository.graph; package org.apache.atlas.repository.graph;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.thinkaurelius.titan.core.TitanGraph; import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.TitanProperty; import com.thinkaurelius.titan.core.TitanProperty;
import com.thinkaurelius.titan.core.TitanVertex; import com.thinkaurelius.titan.core.TitanVertex;
...@@ -41,11 +44,13 @@ import org.apache.atlas.typesystem.types.DataTypes; ...@@ -41,11 +44,13 @@ import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.HierarchicalType; 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.TypeSystem; import org.apache.atlas.typesystem.types.TypeSystem;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
...@@ -215,7 +220,7 @@ public final class GraphHelper { ...@@ -215,7 +220,7 @@ public final class GraphHelper {
LOG.debug("Found {}", string(edge)); LOG.debug("Found {}", string(edge));
return edge; return edge;
} else { } else {
Long modificationTime = edge.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY); Long modificationTime = getProperty(edge, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
if (modificationTime != null && modificationTime >= latestDeletedEdgeTime) { if (modificationTime != null && modificationTime >= latestDeletedEdgeTime) {
latestDeletedEdgeTime = modificationTime; latestDeletedEdgeTime = modificationTime;
latestDeletedEdge = edge; latestDeletedEdge = edge;
...@@ -244,21 +249,36 @@ public final class GraphHelper { ...@@ -244,21 +249,36 @@ public final class GraphHelper {
public static <T extends Element> void setProperty(T element, String propertyName, Object value) { public static <T extends Element> void setProperty(T element, String propertyName, Object value) {
String elementStr = string(element); String elementStr = string(element);
LOG.debug("Setting property {} = \"{}\" to {}", propertyName, value, elementStr); String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
Object existValue = element.getProperty(propertyName); LOG.debug("Setting property {} = \"{}\" to {}", actualPropertyName, value, elementStr);
Object existValue = element.getProperty(actualPropertyName);
if(value == null || (value instanceof Collection && ((Collection) value).isEmpty())) { if(value == null || (value instanceof Collection && ((Collection) value).isEmpty())) {
if(existValue != null) { if(existValue != null) {
LOG.info("Removing property - {} value from {}", propertyName, elementStr); LOG.info("Removing property - {} value from {}", actualPropertyName, elementStr);
element.removeProperty(propertyName); element.removeProperty(actualPropertyName);
} }
} else { } else {
if (!value.equals(existValue)) { if (!value.equals(existValue)) {
element.setProperty(propertyName, value); element.setProperty(actualPropertyName, value);
LOG.debug("Set property {} = \"{}\" to {}", propertyName, value, elementStr); LOG.debug("Set property {} = \"{}\" to {}", actualPropertyName, value, elementStr);
} }
} }
} }
public static <T extends Element, O> O getProperty(T element, String propertyName) {
String elementStr = string(element);
String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
LOG.debug("Reading property {} from {}", actualPropertyName, elementStr);
return element.getProperty(actualPropertyName);
}
public static Iterable<TitanProperty> getProperties(TitanVertex vertex, String propertyName) {
String elementStr = string(vertex);
String actualPropertyName = GraphHelper.encodePropertyKey(propertyName);
LOG.debug("Reading property {} from {}", actualPropertyName, elementStr);
return vertex.getProperties(actualPropertyName);
}
private static <T extends Element> String string(T element) { private static <T extends Element> String string(T element) {
if (element instanceof Vertex) { if (element instanceof Vertex) {
return string((Vertex) element); return string((Vertex) element);
...@@ -339,8 +359,8 @@ public final class GraphHelper { ...@@ -339,8 +359,8 @@ public final class GraphHelper {
} }
public static Id getIdFromVertex(String dataTypeName, Vertex vertex) { public static Id getIdFromVertex(String dataTypeName, Vertex vertex) {
return new Id(vertex.<String>getProperty(Constants.GUID_PROPERTY_KEY), return new Id(getIdFromVertex(vertex),
vertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY), dataTypeName); vertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY), dataTypeName, getStateAsString(vertex));
} }
public static String getIdFromVertex(Vertex vertex) { public static String getIdFromVertex(Vertex vertex) {
...@@ -425,4 +445,39 @@ public final class GraphHelper { ...@@ -425,4 +445,39 @@ public final class GraphHelper {
return String.format("edge[id=%s]", edge.getId().toString()); return String.format("edge[id=%s]", edge.getId().toString());
} }
} }
@VisibleForTesting
//Keys copied from com.thinkaurelius.titan.graphdb.types.StandardRelationTypeMaker
//Titan checks that these chars are not part of any keys. So, encoding...
public static BiMap<String, String> RESERVED_CHARS_ENCODE_MAP =
HashBiMap.create(new HashMap<String, String>() {{
put("{", "_o");
put("}", "_c");
put("\"", "_q");
put("$", "_d");
put("%", "_p");
}});
public static String encodePropertyKey(String key) {
if (StringUtils.isBlank(key)) {
return key;
}
for (String str : RESERVED_CHARS_ENCODE_MAP.keySet()) {
key = key.replace(str, RESERVED_CHARS_ENCODE_MAP.get(str));
}
return key;
}
public static String decodePropertyKey(String key) {
if (StringUtils.isBlank(key)) {
return key;
}
for (String encodedStr : RESERVED_CHARS_ENCODE_MAP.values()) {
key = key.replace(encodedStr, RESERVED_CHARS_ENCODE_MAP.inverse().get(encodedStr));
}
return key;
}
} }
\ No newline at end of file
...@@ -47,6 +47,7 @@ import java.util.HashMap; ...@@ -47,6 +47,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.apache.atlas.repository.graph.GraphHelper.getIdFromVertex;
import static org.apache.atlas.repository.graph.GraphHelper.string; import static org.apache.atlas.repository.graph.GraphHelper.string;
@Singleton @Singleton
...@@ -66,11 +67,12 @@ public final class GraphToTypedInstanceMapper { ...@@ -66,11 +67,12 @@ public final class GraphToTypedInstanceMapper {
throws AtlasException { throws AtlasException {
LOG.debug("Mapping graph root vertex {} to typed instance for guid {}", instanceVertex, guid); LOG.debug("Mapping graph root vertex {} to typed instance for guid {}", instanceVertex, guid);
String typeName = instanceVertex.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY); String typeName = GraphHelper.getProperty(instanceVertex, Constants.ENTITY_TYPE_PROPERTY_KEY);
List<String> traits = GraphHelper.getTraitNames(instanceVertex); List<String> traits = GraphHelper.getTraitNames(instanceVertex);
String state = GraphHelper.getStateAsString(instanceVertex); String state = GraphHelper.getStateAsString(instanceVertex);
Id id = new Id(guid, instanceVertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY), typeName, state); Id id = new Id(guid, (Integer) GraphHelper.getProperty(instanceVertex, Constants.VERSION_PROPERTY_KEY),
typeName, state);
LOG.debug("Created id {} for instance type {}", id, typeName); LOG.debug("Created id {} for instance type {}", id, typeName);
ClassType classType = typeSystem.getDataType(ClassType.class, typeName); ClassType classType = typeSystem.getDataType(ClassType.class, typeName);
...@@ -115,13 +117,12 @@ public final class GraphToTypedInstanceMapper { ...@@ -115,13 +117,12 @@ public final class GraphToTypedInstanceMapper {
break; // add only if vertex has this attribute break; // add only if vertex has this attribute
case ENUM: case ENUM:
if (instanceVertex.getProperty(vertexPropertyName) == null) { Object propertyValue = GraphHelper.getProperty(instanceVertex, vertexPropertyName);
if (propertyValue == null) {
return; return;
} }
typedInstance.set(attributeInfo.name, typedInstance.set(attributeInfo.name, dataType.convert(propertyValue, Multiplicity.REQUIRED));
dataType.convert(instanceVertex.<String>getProperty(vertexPropertyName),
Multiplicity.REQUIRED));
break; break;
case ARRAY: case ARRAY:
...@@ -168,17 +169,14 @@ public final class GraphToTypedInstanceMapper { ...@@ -168,17 +169,14 @@ public final class GraphToTypedInstanceMapper {
if (edge != null) { if (edge != null) {
final Vertex referenceVertex = edge.getVertex(Direction.IN); final Vertex referenceVertex = edge.getVertex(Direction.IN);
final String guid = referenceVertex.getProperty(Constants.GUID_PROPERTY_KEY); final String guid = GraphHelper.getIdFromVertex(referenceVertex);
LOG.debug("Found vertex {} for label {} with guid {}", referenceVertex, relationshipLabel, guid); LOG.debug("Found vertex {} for label {} with guid {}", referenceVertex, relationshipLabel, guid);
if (attributeInfo.isComposite) { if (attributeInfo.isComposite) {
//Also, when you retrieve a type's instance, you get the complete object graph of the composites //Also, when you retrieve a type's instance, you get the complete object graph of the composites
LOG.debug("Found composite, mapping vertex to instance"); LOG.debug("Found composite, mapping vertex to instance");
return mapGraphToTypedInstance(guid, referenceVertex); return mapGraphToTypedInstance(guid, referenceVertex);
} else { } else {
String state = GraphHelper.getStateAsString(referenceVertex); Id referenceId = getIdFromVertex(dataType.getName(), referenceVertex);
Id referenceId =
new Id(guid, referenceVertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY),
dataType.getName(), state);
LOG.debug("Found non-composite, adding id {} ", referenceId); LOG.debug("Found non-composite, adding id {} ", referenceId);
return referenceId; return referenceId;
} }
...@@ -191,7 +189,7 @@ public final class GraphToTypedInstanceMapper { ...@@ -191,7 +189,7 @@ public final class GraphToTypedInstanceMapper {
private void mapVertexToArrayInstance(Vertex instanceVertex, ITypedInstance typedInstance, private void mapVertexToArrayInstance(Vertex instanceVertex, ITypedInstance typedInstance,
AttributeInfo attributeInfo, String propertyName) throws AtlasException { AttributeInfo attributeInfo, String propertyName) throws AtlasException {
LOG.debug("mapping vertex {} to array {}", instanceVertex, attributeInfo.name); LOG.debug("mapping vertex {} to array {}", instanceVertex, attributeInfo.name);
List list = instanceVertex.getProperty(propertyName); List list = GraphHelper.getProperty(instanceVertex, propertyName);
if (list == null || list.size() == 0) { if (list == null || list.size() == 0) {
return; return;
} }
...@@ -240,7 +238,7 @@ public final class GraphToTypedInstanceMapper { ...@@ -240,7 +238,7 @@ public final class GraphToTypedInstanceMapper {
private void mapVertexToMapInstance(Vertex instanceVertex, ITypedInstance typedInstance, private void mapVertexToMapInstance(Vertex instanceVertex, ITypedInstance typedInstance,
AttributeInfo attributeInfo, final String propertyName) throws AtlasException { AttributeInfo attributeInfo, final String propertyName) throws AtlasException {
LOG.debug("mapping vertex {} to array {}", instanceVertex, attributeInfo.name); LOG.debug("mapping vertex {} to array {}", instanceVertex, attributeInfo.name);
List<String> keys = instanceVertex.getProperty(propertyName); List<String> keys = GraphHelper.getProperty(instanceVertex, propertyName);
if (keys == null || keys.size() == 0) { if (keys == null || keys.size() == 0) {
return; return;
} }
...@@ -251,7 +249,7 @@ public final class GraphToTypedInstanceMapper { ...@@ -251,7 +249,7 @@ public final class GraphToTypedInstanceMapper {
for (String key : keys) { for (String key : keys) {
final String keyPropertyName = propertyName + "." + key; final String keyPropertyName = propertyName + "." + key;
final String edgeLabel = GraphHelper.EDGE_LABEL_PREFIX + keyPropertyName; final String edgeLabel = GraphHelper.EDGE_LABEL_PREFIX + keyPropertyName;
final Object keyValue = instanceVertex.getProperty(keyPropertyName); final Object keyValue = GraphHelper.getProperty(instanceVertex, keyPropertyName);
Object mapValue = mapVertexToCollectionEntry(instanceVertex, attributeInfo, valueType, keyValue, edgeLabel); Object mapValue = mapVertexToCollectionEntry(instanceVertex, attributeInfo, valueType, keyValue, edgeLabel);
if (mapValue != null) { if (mapValue != null) {
values.put(key, mapValue); values.put(key, mapValue);
...@@ -312,33 +310,33 @@ public final class GraphToTypedInstanceMapper { ...@@ -312,33 +310,33 @@ public final class GraphToTypedInstanceMapper {
AttributeInfo attributeInfo) throws AtlasException { AttributeInfo attributeInfo) throws AtlasException {
LOG.debug("Adding primitive {} from vertex {}", attributeInfo, instanceVertex); LOG.debug("Adding primitive {} from vertex {}", attributeInfo, instanceVertex);
final String vertexPropertyName = GraphHelper.getQualifiedFieldName(typedInstance, attributeInfo); final String vertexPropertyName = GraphHelper.getQualifiedFieldName(typedInstance, attributeInfo);
if (instanceVertex.getProperty(vertexPropertyName) == null) { Object propertyValue = GraphHelper.getProperty(instanceVertex, vertexPropertyName);
if (propertyValue == null) {
return; return;
} }
if (attributeInfo.dataType() == DataTypes.STRING_TYPE) { if (attributeInfo.dataType() == DataTypes.STRING_TYPE) {
typedInstance.setString(attributeInfo.name, instanceVertex.<String>getProperty(vertexPropertyName)); typedInstance.setString(attributeInfo.name, (String) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.SHORT_TYPE) { } else if (attributeInfo.dataType() == DataTypes.SHORT_TYPE) {
typedInstance.setShort(attributeInfo.name, instanceVertex.<Short>getProperty(vertexPropertyName)); typedInstance.setShort(attributeInfo.name, (Short) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.INT_TYPE) { } else if (attributeInfo.dataType() == DataTypes.INT_TYPE) {
typedInstance.setInt(attributeInfo.name, instanceVertex.<Integer>getProperty(vertexPropertyName)); typedInstance.setInt(attributeInfo.name, (Integer) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.BIGINTEGER_TYPE) { } else if (attributeInfo.dataType() == DataTypes.BIGINTEGER_TYPE) {
typedInstance.setBigInt(attributeInfo.name, instanceVertex.<BigInteger>getProperty(vertexPropertyName)); typedInstance.setBigInt(attributeInfo.name, (BigInteger) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.BOOLEAN_TYPE) { } else if (attributeInfo.dataType() == DataTypes.BOOLEAN_TYPE) {
typedInstance.setBoolean(attributeInfo.name, instanceVertex.<Boolean>getProperty(vertexPropertyName)); typedInstance.setBoolean(attributeInfo.name, (Boolean) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.BYTE_TYPE) { } else if (attributeInfo.dataType() == DataTypes.BYTE_TYPE) {
typedInstance.setByte(attributeInfo.name, instanceVertex.<Byte>getProperty(vertexPropertyName)); typedInstance.setByte(attributeInfo.name, (Byte) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.LONG_TYPE) { } else if (attributeInfo.dataType() == DataTypes.LONG_TYPE) {
typedInstance.setLong(attributeInfo.name, instanceVertex.<Long>getProperty(vertexPropertyName)); typedInstance.setLong(attributeInfo.name, (Long) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.FLOAT_TYPE) { } else if (attributeInfo.dataType() == DataTypes.FLOAT_TYPE) {
typedInstance.setFloat(attributeInfo.name, instanceVertex.<Float>getProperty(vertexPropertyName)); typedInstance.setFloat(attributeInfo.name, (Float) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.DOUBLE_TYPE) { } else if (attributeInfo.dataType() == DataTypes.DOUBLE_TYPE) {
typedInstance.setDouble(attributeInfo.name, instanceVertex.<Double>getProperty(vertexPropertyName)); typedInstance.setDouble(attributeInfo.name, (Double) propertyValue);
} else if (attributeInfo.dataType() == DataTypes.BIGDECIMAL_TYPE) { } else if (attributeInfo.dataType() == DataTypes.BIGDECIMAL_TYPE) {
typedInstance typedInstance.setBigDecimal(attributeInfo.name, (BigDecimal) propertyValue);
.setBigDecimal(attributeInfo.name, instanceVertex.<BigDecimal>getProperty(vertexPropertyName));
} else if (attributeInfo.dataType() == DataTypes.DATE_TYPE) { } else if (attributeInfo.dataType() == DataTypes.DATE_TYPE) {
final Long dateVal = instanceVertex.<Long>getProperty(vertexPropertyName); final Long dateVal = (Long) propertyValue;
typedInstance.setDate(attributeInfo.name, new Date(dateVal)); typedInstance.setDate(attributeInfo.name, new Date(dateVal));
} }
} }
...@@ -359,11 +357,7 @@ public final class GraphToTypedInstanceMapper { ...@@ -359,11 +357,7 @@ public final class GraphToTypedInstanceMapper {
return instance; return instance;
case CLASS: case CLASS:
//TODO isComposite handling for class loads //TODO isComposite handling for class loads
final String guid = referredVertex.getProperty(Constants.GUID_PROPERTY_KEY); return GraphHelper.getIdFromVertex(referredType.getName(), referredVertex);
Id referenceId =
new Id(guid, referredVertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY),
referredType.getName());
return referenceId;
default: default:
throw new UnsupportedOperationException("Loading " + referredType.getTypeCategory() + " is not supported"); throw new UnsupportedOperationException("Loading " + referredType.getTypeCategory() + " is not supported");
} }
......
...@@ -324,7 +324,7 @@ public final class TypedInstanceToGraphMapper { ...@@ -324,7 +324,7 @@ public final class TypedInstanceToGraphMapper {
} }
String propertyName = GraphHelper.getQualifiedFieldName(typedInstance, attributeInfo); String propertyName = GraphHelper.getQualifiedFieldName(typedInstance, attributeInfo);
List<String> currentElements = instanceVertex.getProperty(propertyName); List<String> currentElements = GraphHelper.getProperty(instanceVertex, propertyName);
IDataType elementType = ((DataTypes.ArrayType) attributeInfo.dataType()).getElemType(); IDataType elementType = ((DataTypes.ArrayType) attributeInfo.dataType()).getElemType();
List<Object> newElementsCreated = new ArrayList<>(); List<Object> newElementsCreated = new ArrayList<>();
...@@ -403,11 +403,11 @@ public final class TypedInstanceToGraphMapper { ...@@ -403,11 +403,11 @@ public final class TypedInstanceToGraphMapper {
Map<String, String> currentMap = new HashMap<>(); Map<String, String> currentMap = new HashMap<>();
Map<String, Object> newMap = new HashMap<>(); Map<String, Object> newMap = new HashMap<>();
List<String> currentKeys = instanceVertex.getProperty(propertyName); List<String> currentKeys = GraphHelper.getProperty(instanceVertex, propertyName);
if (currentKeys != null && !currentKeys.isEmpty()) { if (currentKeys != null && !currentKeys.isEmpty()) {
for (String key : currentKeys) { for (String key : currentKeys) {
String propertyNameForKey = GraphHelper.getQualifiedNameForMapKey(propertyName, key); String propertyNameForKey = GraphHelper.getQualifiedNameForMapKey(propertyName, key);
String propertyValueForKey = instanceVertex.getProperty(propertyNameForKey).toString(); String propertyValueForKey = GraphHelper.getProperty(instanceVertex, propertyNameForKey).toString();
currentMap.put(key, propertyValueForKey); currentMap.put(key, propertyValueForKey);
} }
} }
...@@ -562,7 +562,7 @@ public final class TypedInstanceToGraphMapper { ...@@ -562,7 +562,7 @@ public final class TypedInstanceToGraphMapper {
// Update attributes // Update attributes
final MessageDigest digester = MD5Utils.getDigester(); final MessageDigest digester = MD5Utils.getDigester();
String newSignature = newAttributeValue.getSignatureHash(digester); String newSignature = newAttributeValue.getSignatureHash(digester);
String curSignature = structInstanceVertex.getProperty(SIGNATURE_HASH_PROPERTY_KEY); String curSignature = GraphHelper.getProperty(structInstanceVertex, SIGNATURE_HASH_PROPERTY_KEY);
if (!newSignature.equals(curSignature)) { if (!newSignature.equals(curSignature)) {
//Update struct vertex instance only if there is a change //Update struct vertex instance only if there is a change
...@@ -622,7 +622,7 @@ public final class TypedInstanceToGraphMapper { ...@@ -622,7 +622,7 @@ public final class TypedInstanceToGraphMapper {
if (id.isUnassigned()) { if (id.isUnassigned()) {
Vertex classVertex = idToVertexMap.get(id); Vertex classVertex = idToVertexMap.get(id);
String guid = classVertex.getProperty(Constants.GUID_PROPERTY_KEY); String guid = GraphHelper.getIdFromVertex(classVertex);
id = new Id(guid, 0, typedReference.getTypeName()); id = new Id(guid, 0, typedReference.getTypeName());
} }
return id; return id;
......
...@@ -26,7 +26,6 @@ import com.thinkaurelius.titan.core.TitanGraph; ...@@ -26,7 +26,6 @@ import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.Vertex;
import org.apache.atlas.AtlasException; import org.apache.atlas.AtlasException;
import org.apache.atlas.GraphTransaction; import org.apache.atlas.GraphTransaction;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
...@@ -59,6 +58,8 @@ import java.util.Iterator; ...@@ -59,6 +58,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static org.apache.atlas.repository.graph.GraphHelper.setProperty;
@Singleton @Singleton
public class GraphBackedTypeStore implements ITypeStore { public class GraphBackedTypeStore implements ITypeStore {
public static final String VERTEX_TYPE = "typeSystem"; public static final String VERTEX_TYPE = "typeSystem";
...@@ -106,20 +107,15 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -106,20 +107,15 @@ public class GraphBackedTypeStore implements ITypeStore {
} }
} }
private void addProperty(Vertex vertex, String propertyName, Object value) {
LOG.debug("Setting property {} = \"{}\" to vertex {}", propertyName, value, vertex);
vertex.setProperty(propertyName, value);
}
private void storeInGraph(EnumType dataType) { private void storeInGraph(EnumType dataType) {
Vertex vertex = createVertex(dataType.getTypeCategory(), dataType.getName(), dataType.getDescription()); Vertex vertex = createVertex(dataType.getTypeCategory(), dataType.getName(), dataType.getDescription());
List<String> values = new ArrayList<>(dataType.values().size()); List<String> values = new ArrayList<>(dataType.values().size());
for (EnumValue enumValue : dataType.values()) { for (EnumValue enumValue : dataType.values()) {
String key = getPropertyKey(dataType.getName(), enumValue.value); String key = getPropertyKey(dataType.getName(), enumValue.value);
addProperty(vertex, key, enumValue.ordinal); setProperty(vertex, key, enumValue.ordinal);
values.add(enumValue.value); values.add(enumValue.value);
} }
addProperty(vertex, getPropertyKey(dataType.getName()), values); setProperty(vertex, getPropertyKey(dataType.getName()), values);
} }
private String getPropertyKey(String name) { private String getPropertyKey(String name) {
...@@ -142,7 +138,7 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -142,7 +138,7 @@ public class GraphBackedTypeStore implements ITypeStore {
for (AttributeInfo attribute : attributes) { for (AttributeInfo attribute : attributes) {
String propertyKey = getPropertyKey(typeName, attribute.name); String propertyKey = getPropertyKey(typeName, attribute.name);
try { try {
addProperty(vertex, propertyKey, attribute.toJson()); setProperty(vertex, propertyKey, attribute.toJson());
} catch (JSONException e) { } catch (JSONException e) {
throw new StorageException(typeName, e); throw new StorageException(typeName, e);
} }
...@@ -150,7 +146,7 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -150,7 +146,7 @@ public class GraphBackedTypeStore implements ITypeStore {
addReferencesForAttribute(typeSystem, vertex, attribute); addReferencesForAttribute(typeSystem, vertex, attribute);
} }
} }
addProperty(vertex, getPropertyKey(typeName), attrNames); setProperty(vertex, getPropertyKey(typeName), attrNames);
//Add edges for hierarchy //Add edges for hierarchy
if (superTypes != null) { if (superTypes != null) {
...@@ -272,10 +268,10 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -272,10 +268,10 @@ public class GraphBackedTypeStore implements ITypeStore {
String typeName = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY); String typeName = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY);
String typeDescription = vertex.getProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY); String typeDescription = vertex.getProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY);
List<EnumValue> enumValues = new ArrayList<>(); List<EnumValue> enumValues = new ArrayList<>();
List<String> values = vertex.getProperty(getPropertyKey(typeName)); List<String> values = graphHelper.getProperty(vertex, getPropertyKey(typeName));
for (String value : values) { for (String value : values) {
String valueProperty = getPropertyKey(typeName, value); String valueProperty = getPropertyKey(typeName, value);
enumValues.add(new EnumValue(value, vertex.<Integer>getProperty(valueProperty))); enumValues.add(new EnumValue(value, (Integer) graphHelper.getProperty(vertex, valueProperty)));
} }
return new EnumTypeDefinition(typeName, typeDescription, enumValues.toArray(new EnumValue[enumValues.size()])); return new EnumTypeDefinition(typeName, typeDescription, enumValues.toArray(new EnumValue[enumValues.size()]));
} }
...@@ -292,12 +288,12 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -292,12 +288,12 @@ public class GraphBackedTypeStore implements ITypeStore {
private AttributeDefinition[] getAttributes(Vertex vertex, String typeName) throws AtlasException { private AttributeDefinition[] getAttributes(Vertex vertex, String typeName) throws AtlasException {
List<AttributeDefinition> attributes = new ArrayList<>(); List<AttributeDefinition> attributes = new ArrayList<>();
List<String> attrNames = vertex.getProperty(getPropertyKey(typeName)); List<String> attrNames = graphHelper.getProperty(vertex, getPropertyKey(typeName));
if (attrNames != null) { if (attrNames != null) {
for (String attrName : attrNames) { for (String attrName : attrNames) {
try { try {
String propertyKey = getPropertyKey(typeName, attrName); String propertyKey = getPropertyKey(typeName, attrName);
attributes.add(AttributeInfo.fromJson((String) vertex.getProperty(propertyKey))); attributes.add(AttributeInfo.fromJson((String) graphHelper.getProperty(vertex, propertyKey)));
} catch (JSONException e) { } catch (JSONException e) {
throw new AtlasException(e); throw new AtlasException(e);
} }
...@@ -306,10 +302,6 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -306,10 +302,6 @@ public class GraphBackedTypeStore implements ITypeStore {
return attributes.toArray(new AttributeDefinition[attributes.size()]); return attributes.toArray(new AttributeDefinition[attributes.size()]);
} }
private String toString(Vertex vertex) {
return PROPERTY_PREFIX + vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY);
}
/** /**
* Find vertex for the given type category and name, else create new vertex * Find vertex for the given type category and name, else create new vertex
* @param category * @param category
...@@ -333,14 +325,14 @@ public class GraphBackedTypeStore implements ITypeStore { ...@@ -333,14 +325,14 @@ public class GraphBackedTypeStore implements ITypeStore {
if (vertex == null) { if (vertex == null) {
LOG.debug("Adding vertex {}{}", PROPERTY_PREFIX, typeName); LOG.debug("Adding vertex {}{}", PROPERTY_PREFIX, typeName);
vertex = titanGraph.addVertex(null); vertex = titanGraph.addVertex(null);
addProperty(vertex, Constants.VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE); // Mark as type vertex setProperty(vertex, Constants.VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE); // Mark as type vertex
addProperty(vertex, Constants.TYPE_CATEGORY_PROPERTY_KEY, category); setProperty(vertex, Constants.TYPE_CATEGORY_PROPERTY_KEY, category);
addProperty(vertex, Constants.TYPENAME_PROPERTY_KEY, typeName); setProperty(vertex, Constants.TYPENAME_PROPERTY_KEY, typeName);
} }
if (typeDescription != null) { if (typeDescription != null) {
String oldDescription = getPropertyKey(Constants.TYPEDESCRIPTION_PROPERTY_KEY); String oldDescription = getPropertyKey(Constants.TYPEDESCRIPTION_PROPERTY_KEY);
if (!typeDescription.equals(oldDescription)) { if (!typeDescription.equals(oldDescription)) {
addProperty(vertex, Constants.TYPEDESCRIPTION_PROPERTY_KEY, typeDescription); setProperty(vertex, Constants.TYPEDESCRIPTION_PROPERTY_KEY, typeDescription);
} }
} else { } else {
LOG.debug(" type description is null "); LOG.debug(" type description is null ");
......
...@@ -18,15 +18,16 @@ ...@@ -18,15 +18,16 @@
package org.apache.atlas.query package org.apache.atlas.query
import org.apache.atlas.query.TypeUtils.FieldInfo; import org.apache.atlas.query.TypeUtils.FieldInfo
import org.apache.atlas.query.Expressions._ import org.apache.atlas.query.Expressions._
import org.apache.atlas.typesystem.types.{TypeSystem, DataTypes} import org.apache.atlas.typesystem.types.{DataTypes, TypeSystem}
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory import org.apache.atlas.typesystem.types.DataTypes.TypeCategory
import org.joda.time.format.ISODateTimeFormat import org.joda.time.format.ISODateTimeFormat
import scala.collection.mutable import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import org.apache.atlas.typesystem.types.IDataType import org.apache.atlas.typesystem.types.IDataType
import org.apache.commons.lang.StringEscapeUtils
trait IntSequence { trait IntSequence {
def next: Int def next: Int
...@@ -111,6 +112,7 @@ trait SelectExpressionHandling { ...@@ -111,6 +112,7 @@ trait SelectExpressionHandling {
/** /**
* For each Output Column in the SelectExpression compute the ArrayList(Src) this maps to and the position within * For each Output Column in the SelectExpression compute the ArrayList(Src) this maps to and the position within
* this list. * this list.
*
* @param sel * @param sel
* @return * @return
*/ */
...@@ -200,11 +202,17 @@ class GremlinTranslator(expr: Expression, ...@@ -200,11 +202,17 @@ class GremlinTranslator(expr: Expression,
} }
def typeTestExpression(typeName : String) : String = { def typeTestExpression(typeName : String) : String = {
val stats = gPersistenceBehavior.typeTestExpression(typeName, counter) val stats = gPersistenceBehavior.typeTestExpression(escape(typeName), counter)
preStatements ++= stats.init preStatements ++= stats.init
stats.last stats.last
} }
def escape(str: String): String = {
if (str != null) {
return str.replace("\"", "\\\"").replace("$", "\\$");
}
str
}
private def genQuery(expr: Expression, inSelect: Boolean): String = expr match { private def genQuery(expr: Expression, inSelect: Boolean): String = expr match {
case ClassExpression(clsName) => case ClassExpression(clsName) =>
...@@ -239,9 +247,9 @@ class GremlinTranslator(expr: Expression, ...@@ -239,9 +247,9 @@ class GremlinTranslator(expr: Expression,
} }
} }
case c@ComparisonExpression(symb, f@FieldExpression(fieldName, fInfo, ch), l) => { case c@ComparisonExpression(symb, f@FieldExpression(fieldName, fInfo, ch), l) => {
val qualifiedPropertyName = s"${gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)}"; val qualifiedPropertyName = s"${gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)}"
val persistentExprValue = translateValueToPersistentForm(fInfo, l); val persistentExprValue = translateValueToPersistentForm(fInfo, l)
return generateAndPrependExpr(ch, inSelect, s"""has("${qualifiedPropertyName}", ${gPersistenceBehavior.gremlinCompOp(c)}, $persistentExprValue)"""); return generateAndPrependExpr(ch, inSelect, s"""has("${qualifiedPropertyName}", ${gPersistenceBehavior.gremlinCompOp(c)}, $persistentExprValue)""")
} }
case fil@FilterExpression(child, condExpr) => { case fil@FilterExpression(child, condExpr) => {
s"${genQuery(child, inSelect)}.${genQuery(condExpr, inSelect)}" s"${genQuery(child, inSelect)}.${genQuery(condExpr, inSelect)}"
...@@ -329,9 +337,9 @@ class GremlinTranslator(expr: Expression, ...@@ -329,9 +337,9 @@ class GremlinTranslator(expr: Expression,
def translateValueToPersistentForm(fInfo: FieldInfo, l: Expression): Any = { def translateValueToPersistentForm(fInfo: FieldInfo, l: Expression): Any = {
val dataType = fInfo.attrInfo.dataType; val dataType = fInfo.attrInfo.dataType;
val QUOTE = "\"";
if (dataType == DataTypes.DATE_TYPE) { if (dataType == DataTypes.DATE_TYPE) {
val QUOTE = "\"";
try { try {
//Accepts both date, datetime formats //Accepts both date, datetime formats
val dateStr = l.toString.stripPrefix(QUOTE).stripSuffix(QUOTE) val dateStr = l.toString.stripPrefix(QUOTE).stripSuffix(QUOTE)
...@@ -360,9 +368,10 @@ class GremlinTranslator(expr: Expression, ...@@ -360,9 +368,10 @@ class GremlinTranslator(expr: Expression,
} }
else if(dataType == DataTypes.DOUBLE_TYPE) { else if(dataType == DataTypes.DOUBLE_TYPE) {
return s"""${l}d""" return s"""${l}d"""
} } else if(dataType == DataTypes.STRING_TYPE) {
else { return string(escape(l.toString.stripPrefix(QUOTE).stripSuffix(QUOTE)));
return l } else {
l
} }
} }
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.repository.graph;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
public class GraphHelperTest {
@DataProvider(name = "encodeDecodeTestData")
private Object[][] createTestData() {
return new Object[][]{
{"hivedb$", "hivedb_d"},
{"hivedb", "hivedb"},
{"{hivedb}", "_ohivedb_c"},
{"%hivedb}", "_phivedb_c"},
{"\"hivedb\"", "_qhivedb_q"},
{"\"$%{}", "_q_d_p_o_c"},
{"", ""},
{" ", " "},
{"\n\r", "\n\r"},
{null, null}
};
}
@Test(dataProvider = "encodeDecodeTestData")
public void testEncodeDecode(String str, String expectedEncodedStr) throws Exception {
String encodedStr = GraphHelper.encodePropertyKey(str);
assertEquals(encodedStr, expectedEncodedStr);
String decodedStr = GraphHelper.decodePropertyKey(encodedStr);
assertEquals(decodedStr, str);
}
}
...@@ -24,12 +24,12 @@ import com.google.inject.Inject; ...@@ -24,12 +24,12 @@ import com.google.inject.Inject;
import com.thinkaurelius.titan.core.TitanGraph; import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.util.TitanCleanup; import com.thinkaurelius.titan.core.util.TitanCleanup;
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.RepositoryMetadataModule; import org.apache.atlas.RepositoryMetadataModule;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
import org.apache.atlas.TestUtils; import org.apache.atlas.TestUtils;
import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
import org.apache.atlas.listener.EntityChangeListener; import org.apache.atlas.listener.EntityChangeListener;
import org.apache.atlas.repository.audit.EntityAuditRepository; import org.apache.atlas.repository.audit.EntityAuditRepository;
import org.apache.atlas.repository.audit.HBaseBasedAuditRepository; import org.apache.atlas.repository.audit.HBaseBasedAuditRepository;
...@@ -47,10 +47,12 @@ import org.apache.atlas.typesystem.exception.TypeNotFoundException; ...@@ -47,10 +47,12 @@ import org.apache.atlas.typesystem.exception.TypeNotFoundException;
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.persistence.Id; import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.types.AttributeDefinition;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.EnumValue; import org.apache.atlas.typesystem.types.EnumValue;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition; import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.Multiplicity;
import org.apache.atlas.typesystem.types.TypeSystem; import org.apache.atlas.typesystem.types.TypeSystem;
import org.apache.atlas.typesystem.types.ValueConversionException; import org.apache.atlas.typesystem.types.ValueConversionException;
import org.apache.atlas.typesystem.types.utils.TypesUtil; import org.apache.atlas.typesystem.types.utils.TypesUtil;
...@@ -78,7 +80,11 @@ import static org.apache.atlas.TestUtils.PII; ...@@ -78,7 +80,11 @@ import static org.apache.atlas.TestUtils.PII;
import static org.apache.atlas.TestUtils.TABLE_TYPE; import static org.apache.atlas.TestUtils.TABLE_TYPE;
import static org.apache.atlas.TestUtils.createColumnEntity; import static org.apache.atlas.TestUtils.createColumnEntity;
import static org.apache.atlas.TestUtils.createDBEntity; import static org.apache.atlas.TestUtils.createDBEntity;
import static org.apache.atlas.TestUtils.createInstance;
import static org.apache.atlas.TestUtils.createTableEntity; import static org.apache.atlas.TestUtils.createTableEntity;
import static org.apache.atlas.TestUtils.randomString;
import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef;
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.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull; import static org.testng.Assert.assertNull;
...@@ -96,6 +102,9 @@ public class DefaultMetadataServiceTest { ...@@ -96,6 +102,9 @@ public class DefaultMetadataServiceTest {
@Inject @Inject
private EntityAuditRepository auditRepository; private EntityAuditRepository auditRepository;
@Inject
private GraphBackedDiscoveryService discoveryService;
private Referenceable db = createDBEntity(); private Referenceable db = createDBEntity();
private Referenceable table; private Referenceable table;
...@@ -121,9 +130,9 @@ public class DefaultMetadataServiceTest { ...@@ -121,9 +130,9 @@ public class DefaultMetadataServiceTest {
metadataService.createType(TypesSerialization.toJson(typesDef)); metadataService.createType(TypesSerialization.toJson(typesDef));
} }
String dbGUid = createInstance(db); String dbGUid = TestUtils.createInstance(metadataService, db);
table = createTableEntity(dbGUid); table = createTableEntity(dbGUid);
String tableGuid = createInstance(table); String tableGuid = TestUtils.createInstance(metadataService, table);
String tableDefinitionJson = String tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
table = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); table = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
...@@ -151,19 +160,6 @@ public class DefaultMetadataServiceTest { ...@@ -151,19 +160,6 @@ public class DefaultMetadataServiceTest {
} }
} }
private String createInstance(Referenceable entity) throws Exception {
RequestContext.createContext();
String entityjson = InstanceSerialization.toJson(entity, true);
JSONArray entitiesJson = new JSONArray();
entitiesJson.put(entityjson);
List<String> guids = metadataService.createEntities(entitiesJson.toString());
if (guids != null && guids.size() > 0) {
return guids.get(guids.size() - 1);
}
return null;
}
private AtlasClient.EntityResult updateInstance(Referenceable entity) throws Exception { private AtlasClient.EntityResult updateInstance(Referenceable entity) throws Exception {
RequestContext.createContext(); RequestContext.createContext();
ParamChecker.notNull(entity, "Entity"); ParamChecker.notNull(entity, "Entity");
...@@ -180,7 +176,7 @@ public class DefaultMetadataServiceTest { ...@@ -180,7 +176,7 @@ public class DefaultMetadataServiceTest {
String dbName = RandomStringUtils.randomAlphanumeric(10); String dbName = RandomStringUtils.randomAlphanumeric(10);
entity.set(NAME, dbName); entity.set(NAME, dbName);
entity.set("description", "us db"); entity.set("description", "us db");
createInstance(entity); TestUtils.createInstance(metadataService, entity);
Assert.fail(TypeNotFoundException.class.getSimpleName() + " was expected but none thrown."); Assert.fail(TypeNotFoundException.class.getSimpleName() + " was expected but none thrown.");
} }
...@@ -188,23 +184,79 @@ public class DefaultMetadataServiceTest { ...@@ -188,23 +184,79 @@ public class DefaultMetadataServiceTest {
public void testCreateEntityWithUniqueAttribute() throws Exception { public void testCreateEntityWithUniqueAttribute() throws Exception {
//name is the unique attribute //name is the unique attribute
Referenceable entity = createDBEntity(); Referenceable entity = createDBEntity();
String id = createInstance(entity); String id = TestUtils.createInstance(metadataService, entity);
assertAuditEvents(id, EntityAuditEvent.EntityAuditAction.ENTITY_CREATE); assertAuditEvents(id, EntityAuditEvent.EntityAuditAction.ENTITY_CREATE);
//using the same name should succeed, but not create another entity //using the same name should succeed, but not create another entity
String newId = createInstance(entity); String newId = TestUtils.createInstance(metadataService, entity);
assertNull(newId); assertNull(newId);
//Same entity, but different qualified name should succeed //Same entity, but different qualified name should succeed
entity.set(NAME, TestUtils.randomString()); entity.set(NAME, TestUtils.randomString());
newId = createInstance(entity); newId = TestUtils.createInstance(metadataService, entity);
Assert.assertNotEquals(newId, id); Assert.assertNotEquals(newId, id);
} }
@Test @Test
//Titan doesn't allow some reserved chars in property keys. Verify that atlas encodes these
//See GraphHelper.encodePropertyKey()
public void testSpecialCharacters() throws Exception {
//Verify that type can be created with reserved characters in typename, attribute name
String strAttrName = randomStrWithReservedChars();
String arrayAttrName = randomStrWithReservedChars();
String mapAttrName = randomStrWithReservedChars();
HierarchicalTypeDefinition<ClassType> typeDefinition =
createClassTypeDef(randomStrWithReservedChars(), ImmutableSet.<String>of(),
createOptionalAttrDef(strAttrName, DataTypes.STRING_TYPE),
new AttributeDefinition(arrayAttrName, DataTypes.arrayTypeName(DataTypes.STRING_TYPE.getName()),
Multiplicity.OPTIONAL, false, null),
new AttributeDefinition(mapAttrName,
DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(), DataTypes.STRING_TYPE.getName()),
Multiplicity.OPTIONAL, false, null));
metadataService.createType(TypesSerialization.toJson(typeDefinition, false));
//verify that entity can be created with reserved characters in string value, array value and map key and value
Referenceable entity = new Referenceable(typeDefinition.typeName);
entity.set(strAttrName, randomStrWithReservedChars());
entity.set(arrayAttrName, new String[]{randomStrWithReservedChars()});
entity.set(mapAttrName, new HashMap<String, String>() {{
put(randomStrWithReservedChars(), randomStrWithReservedChars());
}});
String id = createInstance(metadataService, entity);
//Verify that get entity definition returns actual values with reserved characters
Referenceable instance =
InstanceSerialization.fromJsonReferenceable(metadataService.getEntityDefinition(id), true);
assertReferenceableEquals(instance, entity);
//Verify that search with reserved characters works - for string attribute
String responseJson = discoveryService.searchByDSL(
String.format("`%s` where `%s` = '%s'", typeDefinition.typeName, strAttrName, entity.get(strAttrName)));
JSONObject response = new JSONObject(responseJson);
assertEquals(response.getJSONArray("rows").length(), 1);
}
//equals excluding the id
private void assertReferenceableEquals(Referenceable actual, Referenceable expected) {
List<String> traits = actual.getTraits();
Map<String, IStruct> traitsMap = new HashMap<>();
for (String trait : traits) {
traitsMap.put(trait, actual.getTrait(trait));
}
Referenceable newActual = new Referenceable(expected.getId(), actual.getTypeName(), actual.getValuesMap(),
traits, traitsMap);
assertEquals(InstanceSerialization.toJson(newActual, true), InstanceSerialization.toJson(expected, true));
}
private String randomStrWithReservedChars() {
return randomString() + "\"${}%";
}
@Test
public void testAddDeleteTrait() throws Exception { public void testAddDeleteTrait() throws Exception {
Referenceable entity = createDBEntity(); Referenceable entity = createDBEntity();
String id = createInstance(entity); String id = TestUtils.createInstance(metadataService, entity);
//add trait //add trait
Struct tag = new Struct(TestUtils.PII); Struct tag = new Struct(TestUtils.PII);
...@@ -218,7 +270,7 @@ public class DefaultMetadataServiceTest { ...@@ -218,7 +270,7 @@ public class DefaultMetadataServiceTest {
String traitDefinition = metadataService.getTraitDefinition(id, PII); String traitDefinition = metadataService.getTraitDefinition(id, PII);
Struct traitResult = InstanceSerialization.fromJsonStruct(traitDefinition, true); Struct traitResult = InstanceSerialization.fromJsonStruct(traitDefinition, true);
Assert.assertNotNull(traitResult); Assert.assertNotNull(traitResult);
Assert.assertEquals(traitResult.getValuesMap().size(), 0); assertEquals(traitResult.getValuesMap().size(), 0);
//delete trait //delete trait
metadataService.deleteTrait(id, PII); metadataService.deleteTrait(id, PII);
...@@ -237,7 +289,7 @@ public class DefaultMetadataServiceTest { ...@@ -237,7 +289,7 @@ public class DefaultMetadataServiceTest {
public void testEntityAudit() throws Exception { public void testEntityAudit() throws Exception {
//create entity //create entity
Referenceable entity = createDBEntity(); Referenceable entity = createDBEntity();
String id = createInstance(entity); String id = TestUtils.createInstance(metadataService, entity);
assertAuditEvents(id, EntityAuditEvent.EntityAuditAction.ENTITY_CREATE); assertAuditEvents(id, EntityAuditEvent.EntityAuditAction.ENTITY_CREATE);
Struct tag = new Struct(TestUtils.PII); Struct tag = new Struct(TestUtils.PII);
...@@ -279,7 +331,7 @@ public class DefaultMetadataServiceTest { ...@@ -279,7 +331,7 @@ public class DefaultMetadataServiceTest {
@Test @Test
public void testCreateEntityWithUniqueAttributeWithReference() throws Exception { public void testCreateEntityWithUniqueAttributeWithReference() throws Exception {
Referenceable db = createDBEntity(); Referenceable db = createDBEntity();
String dbId = createInstance(db); String dbId = TestUtils.createInstance(metadataService, db);
//Assert that there is just 1 audit events and thats for entity create //Assert that there is just 1 audit events and thats for entity create
assertAuditEvents(dbId, 1); assertAuditEvents(dbId, 1);
...@@ -292,14 +344,14 @@ public class DefaultMetadataServiceTest { ...@@ -292,14 +344,14 @@ public class DefaultMetadataServiceTest {
table.set("tableType", "MANAGED"); table.set("tableType", "MANAGED");
table.set("database", new Id(dbId, 0, TestUtils.DATABASE_TYPE)); table.set("database", new Id(dbId, 0, TestUtils.DATABASE_TYPE));
table.set("databaseComposite", db); table.set("databaseComposite", db);
createInstance(table); TestUtils.createInstance(metadataService, table);
//table create should re-use the db instance created earlier //table create should re-use the db instance created earlier
String tableDefinitionJson = String tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Referenceable actualDb = (Referenceable) tableDefinition.get("databaseComposite"); Referenceable actualDb = (Referenceable) tableDefinition.get("databaseComposite");
Assert.assertEquals(actualDb.getId().id, dbId); assertEquals(actualDb.getId().id, dbId);
//Assert that as part table create, db is not created and audit event is not added to db //Assert that as part table create, db is not created and audit event is not added to db
assertAuditEvents(dbId, 1); assertAuditEvents(dbId, 1);
...@@ -318,7 +370,7 @@ public class DefaultMetadataServiceTest { ...@@ -318,7 +370,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
List<String> actualColumns = (List) tableDefinition.get("columnNames"); List<String> actualColumns = (List) tableDefinition.get("columnNames");
Assert.assertEquals(actualColumns, colNameList); assertEquals(actualColumns, colNameList);
} }
@Test @Test
...@@ -350,7 +402,7 @@ public class DefaultMetadataServiceTest { ...@@ -350,7 +402,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2); assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
Assert.assertTrue(partsMap.get("part1").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part1"))); Assert.assertTrue(partsMap.get("part1").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part1")));
//update map - remove a key and add another key //update map - remove a key and add another key
...@@ -366,7 +418,7 @@ public class DefaultMetadataServiceTest { ...@@ -366,7 +418,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2); assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0")); Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0"));
Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2"))); Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2")));
...@@ -378,7 +430,7 @@ public class DefaultMetadataServiceTest { ...@@ -378,7 +430,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2); assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0")); Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0"));
Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2"))); Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2")));
...@@ -471,7 +523,7 @@ public class DefaultMetadataServiceTest { ...@@ -471,7 +523,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
List<String> actualColumns = (List) tableDefinition.get("columnNames"); List<String> actualColumns = (List) tableDefinition.get("columnNames");
Assert.assertEquals(actualColumns, colNameList); assertEquals(actualColumns, colNameList);
//update array of primitives //update array of primitives
final List<String> updatedColNameList = ImmutableList.of("col2", "col3"); final List<String> updatedColNameList = ImmutableList.of("col2", "col3");
...@@ -484,7 +536,7 @@ public class DefaultMetadataServiceTest { ...@@ -484,7 +536,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
actualColumns = (List) tableDefinition.get("columnNames"); actualColumns = (List) tableDefinition.get("columnNames");
Assert.assertEquals(actualColumns, updatedColNameList); assertEquals(actualColumns, updatedColNameList);
} }
private AtlasClient.EntityResult updateEntityPartial(String guid, Referenceable entity) throws AtlasException { private AtlasClient.EntityResult updateEntityPartial(String guid, Referenceable entity) throws AtlasException {
...@@ -625,7 +677,7 @@ public class DefaultMetadataServiceTest { ...@@ -625,7 +677,7 @@ public class DefaultMetadataServiceTest {
table.set("serde1", serdeInstance); table.set("serde1", serdeInstance);
String newtableId = updateInstance(table).getUpdateEntities().get(0); String newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
String tableDefinitionJson = String tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -659,7 +711,7 @@ public class DefaultMetadataServiceTest { ...@@ -659,7 +711,7 @@ public class DefaultMetadataServiceTest {
sdReferenceable.set(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, TestUtils.randomString()); sdReferenceable.set(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, TestUtils.randomString());
sdReferenceable.set("compressed", "false"); sdReferenceable.set("compressed", "false");
sdReferenceable.set("location", "hdfs://tmp/hive-user"); sdReferenceable.set("location", "hdfs://tmp/hive-user");
String sdGuid = createInstance(sdReferenceable); String sdGuid = TestUtils.createInstance(metadataService, sdReferenceable);
Referenceable sdRef2 = new Referenceable(sdGuid, TestUtils.STORAGE_DESC_TYPE, null); Referenceable sdRef2 = new Referenceable(sdGuid, TestUtils.STORAGE_DESC_TYPE, null);
...@@ -669,7 +721,7 @@ public class DefaultMetadataServiceTest { ...@@ -669,7 +721,7 @@ public class DefaultMetadataServiceTest {
partRef.set("table", table); partRef.set("table", table);
partRef.set("sd", sdRef2); partRef.set("sd", sdRef2);
String partGuid = createInstance(partRef); String partGuid = TestUtils.createInstance(metadataService, partRef);
Assert.assertNotNull(partGuid); Assert.assertNotNull(partGuid);
} }
...@@ -680,7 +732,7 @@ public class DefaultMetadataServiceTest { ...@@ -680,7 +732,7 @@ public class DefaultMetadataServiceTest {
databaseInstance.set(NAME, TestUtils.randomString()); databaseInstance.set(NAME, TestUtils.randomString());
databaseInstance.set("description", "new database"); databaseInstance.set("description", "new database");
String dbId = createInstance(databaseInstance); String dbId = TestUtils.createInstance(metadataService, databaseInstance);
/*Update reference property with Id */ /*Update reference property with Id */
metadataService.updateEntityAttributeByGuid(tableId._getId(), "database", dbId); metadataService.updateEntityAttributeByGuid(tableId._getId(), "database", dbId);
...@@ -689,7 +741,7 @@ public class DefaultMetadataServiceTest { ...@@ -689,7 +741,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(tableId._getId()); metadataService.getEntityDefinition(tableId._getId());
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Assert.assertEquals(dbId, (((Id) tableDefinition.get("database"))._getId())); assertEquals(dbId, (((Id) tableDefinition.get("database"))._getId()));
/* Update with referenceable - TODO - Fails . Need to fix this */ /* Update with referenceable - TODO - Fails . Need to fix this */
/*final String dbName = TestUtils.randomString(); /*final String dbName = TestUtils.randomString();
...@@ -729,7 +781,7 @@ public class DefaultMetadataServiceTest { ...@@ -729,7 +781,7 @@ public class DefaultMetadataServiceTest {
table.set("partitions", partitions); table.set("partitions", partitions);
String newtableId = updateInstance(table).getUpdateEntities().get(0); String newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
String tableDefinitionJson = String tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -745,7 +797,7 @@ public class DefaultMetadataServiceTest { ...@@ -745,7 +797,7 @@ public class DefaultMetadataServiceTest {
partitions.add(partition3); partitions.add(partition3);
table.set("partitions", partitions); table.set("partitions", partitions);
newtableId = updateInstance(table).getUpdateEntities().get(0); newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -759,7 +811,7 @@ public class DefaultMetadataServiceTest { ...@@ -759,7 +811,7 @@ public class DefaultMetadataServiceTest {
partitions.remove(1); partitions.remove(1);
table.set("partitions", partitions); table.set("partitions", partitions);
newtableId = updateInstance(table).getUpdateEntities().get(0); newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -772,7 +824,7 @@ public class DefaultMetadataServiceTest { ...@@ -772,7 +824,7 @@ public class DefaultMetadataServiceTest {
//Update struct value within array of struct //Update struct value within array of struct
partitions.get(0).set(NAME, "part4"); partitions.get(0).set(NAME, "part4");
newtableId = updateInstance(table).getUpdateEntities().get(0); newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -788,7 +840,7 @@ public class DefaultMetadataServiceTest { ...@@ -788,7 +840,7 @@ public class DefaultMetadataServiceTest {
partitions.add(partition4); partitions.add(partition4);
table.set("partitions", partitions); table.set("partitions", partitions);
newtableId = updateInstance(table).getUpdateEntities().get(0); newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -802,7 +854,7 @@ public class DefaultMetadataServiceTest { ...@@ -802,7 +854,7 @@ public class DefaultMetadataServiceTest {
// Remove all elements. Should set array attribute to null // Remove all elements. Should set array attribute to null
partitions.clear(); partitions.clear();
newtableId = updateInstance(table).getUpdateEntities().get(0); newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -826,7 +878,7 @@ public class DefaultMetadataServiceTest { ...@@ -826,7 +878,7 @@ public class DefaultMetadataServiceTest {
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
Assert.assertEquals(tableDefinition.get("description"), "random table"); assertEquals(tableDefinition.get("description"), "random table");
table.setNull("description"); table.setNull("description");
updateInstance(table); updateInstance(table);
...@@ -845,7 +897,7 @@ public class DefaultMetadataServiceTest { ...@@ -845,7 +897,7 @@ public class DefaultMetadataServiceTest {
table.setNull("created"); table.setNull("created");
String newtableId = updateInstance(table).getUpdateEntities().get(0); String newtableId = updateInstance(table).getUpdateEntities().get(0);
Assert.assertEquals(newtableId, tableId._getId()); assertEquals(newtableId, tableId._getId());
tableDefinitionJson = tableDefinitionJson =
metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME)); metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, NAME, (String) table.get(NAME));
...@@ -860,20 +912,20 @@ public class DefaultMetadataServiceTest { ...@@ -860,20 +912,20 @@ public class DefaultMetadataServiceTest {
Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true); Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
EnumValue tableType = (EnumValue) tableDefinition.get("tableType"); EnumValue tableType = (EnumValue) tableDefinition.get("tableType");
Assert.assertEquals(tableType, new EnumValue("MANAGED", 1)); assertEquals(tableType, new EnumValue("MANAGED", 1));
} }
@Test @Test
public void testGetEntityByUniqueAttribute() throws Exception { public void testGetEntityByUniqueAttribute() throws Exception {
Referenceable entity = createDBEntity(); Referenceable entity = createDBEntity();
createInstance(entity); TestUtils.createInstance(metadataService, entity);
//get entity by valid qualified name //get entity by valid qualified name
String entityJson = metadataService.getEntityDefinition(TestUtils.DATABASE_TYPE, NAME, String entityJson = metadataService.getEntityDefinition(TestUtils.DATABASE_TYPE, NAME,
(String) entity.get(NAME)); (String) entity.get(NAME));
Assert.assertNotNull(entityJson); Assert.assertNotNull(entityJson);
Referenceable referenceable = InstanceSerialization.fromJsonReferenceable(entityJson, true); Referenceable referenceable = InstanceSerialization.fromJsonReferenceable(entityJson, true);
Assert.assertEquals(referenceable.get(NAME), entity.get(NAME)); assertEquals(referenceable.get(NAME), entity.get(NAME));
//get entity by invalid qualified name //get entity by invalid qualified name
try { try {
...@@ -897,13 +949,13 @@ public class DefaultMetadataServiceTest { ...@@ -897,13 +949,13 @@ public class DefaultMetadataServiceTest {
public void testDeleteEntities() throws Exception { public void testDeleteEntities() throws Exception {
// Create a table entity, with 3 composite column entities // Create a table entity, with 3 composite column entities
Referenceable dbEntity = createDBEntity(); Referenceable dbEntity = createDBEntity();
String dbGuid = createInstance(dbEntity); String dbGuid = TestUtils.createInstance(metadataService, dbEntity);
Referenceable table1Entity = createTableEntity(dbGuid); Referenceable table1Entity = createTableEntity(dbGuid);
Referenceable col1 = createColumnEntity(); Referenceable col1 = createColumnEntity();
Referenceable col2 = createColumnEntity(); Referenceable col2 = createColumnEntity();
Referenceable col3 = createColumnEntity(); Referenceable col3 = createColumnEntity();
table1Entity.set(COLUMNS_ATTR_NAME, ImmutableList.of(col1, col2, col3)); table1Entity.set(COLUMNS_ATTR_NAME, ImmutableList.of(col1, col2, col3));
createInstance(table1Entity); TestUtils.createInstance(metadataService, table1Entity);
// Retrieve the table entities from the repository, // Retrieve the table entities from the repository,
// to get their guids and the composite column guids. // to get their guids and the composite column guids.
...@@ -946,7 +998,7 @@ public class DefaultMetadataServiceTest { ...@@ -946,7 +998,7 @@ public class DefaultMetadataServiceTest {
// Verify that the listener was notified about the deleted entities. // Verify that the listener was notified about the deleted entities.
List<String> deletedEntitiesFromListener = listener.getDeletedEntities(); List<String> deletedEntitiesFromListener = listener.getDeletedEntities();
Assert.assertNotNull(deletedEntitiesFromListener); Assert.assertNotNull(deletedEntitiesFromListener);
Assert.assertEquals(deletedEntitiesFromListener.size(), entityResult.getDeletedEntities().size()); assertEquals(deletedEntitiesFromListener.size(), entityResult.getDeletedEntities().size());
Assert.assertTrue(deletedEntitiesFromListener.containsAll(entityResult.getDeletedEntities())); Assert.assertTrue(deletedEntitiesFromListener.containsAll(entityResult.getDeletedEntities()));
} }
...@@ -964,13 +1016,13 @@ public class DefaultMetadataServiceTest { ...@@ -964,13 +1016,13 @@ public class DefaultMetadataServiceTest {
public void testDeleteEntityByUniqueAttribute() throws Exception { public void testDeleteEntityByUniqueAttribute() throws Exception {
// Create a table entity, with 3 composite column entities // Create a table entity, with 3 composite column entities
Referenceable dbEntity = createDBEntity(); Referenceable dbEntity = createDBEntity();
String dbGuid = createInstance(dbEntity); String dbGuid = TestUtils.createInstance(metadataService, dbEntity);
Referenceable table1Entity = createTableEntity(dbGuid); Referenceable table1Entity = createTableEntity(dbGuid);
Referenceable col1 = createColumnEntity(); Referenceable col1 = createColumnEntity();
Referenceable col2 = createColumnEntity(); Referenceable col2 = createColumnEntity();
Referenceable col3 = createColumnEntity(); Referenceable col3 = createColumnEntity();
table1Entity.set(COLUMNS_ATTR_NAME, ImmutableList.of(col1, col2, col3)); table1Entity.set(COLUMNS_ATTR_NAME, ImmutableList.of(col1, col2, col3));
createInstance(table1Entity); TestUtils.createInstance(metadataService, table1Entity);
// to get their guids and the composite column guids. // to get their guids and the composite column guids.
String entityJson = metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, String entityJson = metadataService.getEntityDefinition(TestUtils.TABLE_TYPE,
...@@ -1005,12 +1057,12 @@ public class DefaultMetadataServiceTest { ...@@ -1005,12 +1057,12 @@ public class DefaultMetadataServiceTest {
// Verify that the listener was notified about the deleted entities. // Verify that the listener was notified about the deleted entities.
List<String> deletedEntitiesFromListener = listener.getDeletedEntities(); List<String> deletedEntitiesFromListener = listener.getDeletedEntities();
Assert.assertNotNull(deletedEntitiesFromListener); Assert.assertNotNull(deletedEntitiesFromListener);
Assert.assertEquals(deletedEntitiesFromListener.size(), deletedGuids.size()); assertEquals(deletedEntitiesFromListener.size(), deletedGuids.size());
Assert.assertTrue(deletedEntitiesFromListener.containsAll(deletedGuids)); Assert.assertTrue(deletedEntitiesFromListener.containsAll(deletedGuids));
} }
@Test @Test
public void testTypeUpdateWithReservedAttributes() throws AtlasException, JSONException { public void testTypeUpdateFailureShouldRollBack() throws AtlasException, JSONException {
String typeName = "test_type_"+ RandomStringUtils.randomAlphanumeric(10); String typeName = "test_type_"+ RandomStringUtils.randomAlphanumeric(10);
HierarchicalTypeDefinition<ClassType> typeDef = TypesUtil.createClassTypeDef( HierarchicalTypeDefinition<ClassType> typeDef = TypesUtil.createClassTypeDef(
typeName, ImmutableSet.<String>of(), typeName, ImmutableSet.<String>of(),
...@@ -1022,17 +1074,20 @@ public class DefaultMetadataServiceTest { ...@@ -1022,17 +1074,20 @@ public class DefaultMetadataServiceTest {
HierarchicalTypeDefinition<ClassType> updatedTypeDef = TypesUtil.createClassTypeDef( HierarchicalTypeDefinition<ClassType> updatedTypeDef = TypesUtil.createClassTypeDef(
typeName, ImmutableSet.<String>of(), typeName, ImmutableSet.<String>of(),
TypesUtil.createUniqueRequiredAttrDef("test_type_attribute", DataTypes.STRING_TYPE), TypesUtil.createUniqueRequiredAttrDef("test_type_attribute", DataTypes.STRING_TYPE),
TypesUtil.createOptionalAttrDef("test_type_invalid_attribute$", DataTypes.STRING_TYPE)); TypesUtil.createRequiredAttrDef("test_type_invalid_attribute$", DataTypes.STRING_TYPE));
TypesDef updatedTypesDef = new TypesDef(updatedTypeDef, false); TypesDef updatedTypesDef = new TypesDef(updatedTypeDef, false);
try { try {
metadataService.updateType(TypesSerialization.toJson(updatedTypesDef)); metadataService.updateType(TypesSerialization.toJson(updatedTypesDef));
Assert.fail("Should not be able to update type with reserved character"); fail("Expected AtlasException");
} catch (AtlasException ae) { } catch (AtlasException e) {
// pass.. expected //expected
} }
//type definition should reflect old type
String typeDefinition = metadataService.getTypeDefinition(typeName); String typeDefinition = metadataService.getTypeDefinition(typeName);
Assert.assertNotNull(typeDefinition); typesDef = TypesSerialization.fromJson(typeDefinition);
assertEquals(typesDef.classTypes().head().attributeDefinitions.length, 1);
} }
@Test @Test
......
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