use of org.apache.atlas.typesystem.types.IDataType in project incubator-atlas by apache.
the class DeleteHandler method deleteTypeVertex.
/**
* Deleting any type vertex. Goes over the complex attributes and removes the references
* @param instanceVertex
* @throws AtlasException
*/
protected void deleteTypeVertex(AtlasVertex instanceVertex, boolean force) throws AtlasException {
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting {}", string(instanceVertex));
}
String typeName = GraphHelper.getTypeName(instanceVertex);
IDataType type = typeSystem.getDataType(IDataType.class, typeName);
FieldMapping fieldMapping = getFieldMapping(type);
for (AttributeInfo attributeInfo : fieldMapping.fields.values()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting attribute {} for {}", attributeInfo.name, string(instanceVertex));
}
String edgeLabel = GraphHelper.getEdgeLabel(type, attributeInfo);
switch(attributeInfo.dataType().getTypeCategory()) {
case CLASS:
//If its class attribute, delete the reference
deleteEdgeReference(instanceVertex, edgeLabel, DataTypes.TypeCategory.CLASS, attributeInfo.isComposite);
break;
case STRUCT:
//If its struct attribute, delete the reference
deleteEdgeReference(instanceVertex, edgeLabel, DataTypes.TypeCategory.STRUCT, false);
break;
case ARRAY:
//For array attribute, if the element is struct/class, delete all the references
IDataType elementType = ((DataTypes.ArrayType) attributeInfo.dataType()).getElemType();
DataTypes.TypeCategory elementTypeCategory = elementType.getTypeCategory();
if (elementTypeCategory == DataTypes.TypeCategory.STRUCT || elementTypeCategory == DataTypes.TypeCategory.CLASS) {
Iterator<AtlasEdge> edges = graphHelper.getOutGoingEdgesByLabel(instanceVertex, edgeLabel);
if (edges != null) {
while (edges.hasNext()) {
AtlasEdge edge = edges.next();
deleteEdgeReference(edge, elementType.getTypeCategory(), attributeInfo.isComposite, false);
}
}
}
break;
case MAP:
//For map attribute, if the value type is struct/class, delete all the references
DataTypes.MapType mapType = (DataTypes.MapType) attributeInfo.dataType();
DataTypes.TypeCategory valueTypeCategory = mapType.getValueType().getTypeCategory();
String propertyName = GraphHelper.getQualifiedFieldName(type, attributeInfo.name);
if (valueTypeCategory == DataTypes.TypeCategory.STRUCT || valueTypeCategory == DataTypes.TypeCategory.CLASS) {
List<String> keys = GraphHelper.getListProperty(instanceVertex, propertyName);
if (keys != null) {
for (String key : keys) {
String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key);
deleteEdgeReference(instanceVertex, mapEdgeLabel, valueTypeCategory, attributeInfo.isComposite);
}
}
}
}
}
deleteVertex(instanceVertex, force);
}
use of org.apache.atlas.typesystem.types.IDataType in project incubator-atlas by apache.
the class DeleteHandler method deleteEdgeBetweenVertices.
/**
* Deletes the edge between outvertex and inVertex. The edge is for attribute attributeName of outVertex
* @param outVertex
* @param inVertex
* @param attributeName
* @throws AtlasException
*/
protected void deleteEdgeBetweenVertices(AtlasVertex outVertex, AtlasVertex inVertex, String attributeName) throws AtlasException {
if (LOG.isDebugEnabled()) {
LOG.debug("Removing edge from {} to {} with attribute name {}", string(outVertex), string(inVertex), attributeName);
}
String typeName = GraphHelper.getTypeName(outVertex);
String outId = GraphHelper.getGuid(outVertex);
Id.EntityState state = GraphHelper.getState(outVertex);
if ((outId != null && RequestContext.get().isDeletedEntity(outId)) || state == Id.EntityState.DELETED) {
//If the reference vertex is marked for deletion, skip updating the reference
return;
}
IDataType type = typeSystem.getDataType(IDataType.class, typeName);
AttributeInfo attributeInfo = getFieldMapping(type).fields.get(attributeName);
String propertyName = GraphHelper.getQualifiedFieldName(type, attributeName);
String edgeLabel = EDGE_LABEL_PREFIX + propertyName;
AtlasEdge edge = null;
switch(attributeInfo.dataType().getTypeCategory()) {
case CLASS:
//If its class attribute, its the only edge between two vertices
if (attributeInfo.multiplicity.nullAllowed()) {
edge = graphHelper.getEdgeForLabel(outVertex, edgeLabel);
if (shouldUpdateReverseAttribute) {
GraphHelper.setProperty(outVertex, propertyName, null);
}
} else {
// Cannot unset a required attribute.
throw new NullRequiredAttributeException("Cannot unset required attribute " + GraphHelper.getQualifiedFieldName(type, attributeName) + " on " + GraphHelper.getVertexDetails(outVertex) + " edge = " + edgeLabel);
}
break;
case ARRAY:
//If its array attribute, find the right edge between the two vertices and update array property
List<String> elements = GraphHelper.getListProperty(outVertex, propertyName);
if (elements != null) {
//Make a copy, else list.remove reflects on titan.getProperty()
elements = new ArrayList<>(elements);
for (String elementEdgeId : elements) {
AtlasEdge elementEdge = graphHelper.getEdgeByEdgeId(outVertex, edgeLabel, elementEdgeId);
if (elementEdge == null) {
continue;
}
AtlasVertex elementVertex = elementEdge.getInVertex();
if (elementVertex.equals(inVertex)) {
edge = elementEdge;
//TODO element.size includes deleted items as well. should exclude
if (!attributeInfo.multiplicity.nullAllowed() && elements.size() <= attributeInfo.multiplicity.lower) {
// Deleting this edge would violate the attribute's lower bound.
throw new NullRequiredAttributeException("Cannot remove array element from required attribute " + GraphHelper.getQualifiedFieldName(type, attributeName) + " on " + GraphHelper.getVertexDetails(outVertex) + " " + GraphHelper.getEdgeDetails(elementEdge));
}
if (shouldUpdateReverseAttribute) {
//but when column is deleted, table will not reference the deleted column
if (LOG.isDebugEnabled()) {
LOG.debug("Removing edge {} from the array attribute {}", string(elementEdge), attributeName);
}
// Remove all occurrences of the edge ID from the list.
// This prevents dangling edge IDs (i.e. edge IDs for deleted edges)
// from the remaining in the list if there are duplicates.
elements.removeAll(Collections.singletonList(elementEdge.getId().toString()));
GraphHelper.setProperty(outVertex, propertyName, elements);
break;
}
}
}
}
break;
case MAP:
//If its map attribute, find the right edge between two vertices and update map property
List<String> keys = GraphHelper.getListProperty(outVertex, propertyName);
if (keys != null) {
//Make a copy, else list.remove reflects on titan.getProperty()
keys = new ArrayList<>(keys);
for (String key : keys) {
String keyPropertyName = GraphHelper.getQualifiedNameForMapKey(propertyName, key);
String mapEdgeId = GraphHelper.getSingleValuedProperty(outVertex, keyPropertyName, String.class);
AtlasEdge mapEdge = graphHelper.getEdgeByEdgeId(outVertex, keyPropertyName, mapEdgeId);
if (mapEdge != null) {
AtlasVertex mapVertex = mapEdge.getInVertex();
if (mapVertex.getId().toString().equals(inVertex.getId().toString())) {
//TODO keys.size includes deleted items as well. should exclude
if (attributeInfo.multiplicity.nullAllowed() || keys.size() > attributeInfo.multiplicity.lower) {
edge = mapEdge;
} else {
// Deleting this entry would violate the attribute's lower bound.
throw new NullRequiredAttributeException("Cannot remove map entry " + keyPropertyName + " from required attribute " + GraphHelper.getQualifiedFieldName(type, attributeName) + " on " + GraphHelper.getVertexDetails(outVertex) + " " + GraphHelper.getEdgeDetails(mapEdge));
}
if (shouldUpdateReverseAttribute) {
//remove this key
if (LOG.isDebugEnabled()) {
LOG.debug("Removing edge {}, key {} from the map attribute {}", string(mapEdge), key, attributeName);
}
keys.remove(key);
GraphHelper.setProperty(outVertex, propertyName, keys);
GraphHelper.setProperty(outVertex, keyPropertyName, null);
}
break;
}
}
}
}
break;
case STRUCT:
case TRAIT:
break;
default:
throw new IllegalStateException("There can't be an edge from " + GraphHelper.getVertexDetails(outVertex) + " to " + GraphHelper.getVertexDetails(inVertex) + " with attribute name " + attributeName + " which is not class/array/map attribute");
}
if (edge != null) {
deleteEdge(edge, false);
RequestContext requestContext = RequestContext.get();
GraphHelper.setProperty(outVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, requestContext.getRequestTime());
GraphHelper.setProperty(outVertex, Constants.MODIFIED_BY_KEY, requestContext.getUser());
requestContext.recordEntityUpdate(outId);
}
}
use of org.apache.atlas.typesystem.types.IDataType in project incubator-atlas by apache.
the class FullTextMapper method forAttribute.
private String forAttribute(IDataType type, Object value, boolean followReferences) throws AtlasException {
if (value == null) {
return null;
}
switch(type.getTypeCategory()) {
case PRIMITIVE:
return String.valueOf(value);
case ENUM:
return ((EnumValue) value).value;
case ARRAY:
StringBuilder fullText = new StringBuilder();
IDataType elemType = ((DataTypes.ArrayType) type).getElemType();
List list = (List) value;
for (Object element : list) {
String elemFullText = forAttribute(elemType, element, false);
if (StringUtils.isNotEmpty(elemFullText)) {
fullText = fullText.append(FULL_TEXT_DELIMITER).append(elemFullText);
}
}
return fullText.toString();
case MAP:
fullText = new StringBuilder();
IDataType keyType = ((DataTypes.MapType) type).getKeyType();
IDataType valueType = ((DataTypes.MapType) type).getValueType();
Map map = (Map) value;
for (Object entryObj : map.entrySet()) {
Map.Entry entry = (Map.Entry) entryObj;
String keyFullText = forAttribute(keyType, entry.getKey(), false);
if (StringUtils.isNotEmpty(keyFullText)) {
fullText = fullText.append(FULL_TEXT_DELIMITER).append(keyFullText);
}
String valueFullText = forAttribute(valueType, entry.getValue(), false);
if (StringUtils.isNotEmpty(valueFullText)) {
fullText = fullText.append(FULL_TEXT_DELIMITER).append(valueFullText);
}
}
return fullText.toString();
case CLASS:
if (followReferences) {
Id refId = ((ITypedReferenceableInstance) value).getId();
String refGuid = refId._getId();
AtlasVertex refVertex = typedInstanceToGraphMapper.lookupVertex(refId);
if (refVertex == null) {
refVertex = graphHelper.getVertexForGUID(refGuid);
}
return mapRecursive(refVertex, false);
}
break;
case STRUCT:
if (followReferences) {
return forInstance((ITypedInstance) value, true);
}
break;
default:
throw new IllegalStateException("Unhandled type category " + type.getTypeCategory());
}
return null;
}
use of org.apache.atlas.typesystem.types.IDataType in project incubator-atlas by apache.
the class GraphBackedSearchIndexer method onAdd.
/**
* This is upon adding a new type to Store.
*
* @param dataTypes data type
* @throws AtlasException
*/
@Override
public void onAdd(Collection<? extends IDataType> dataTypes) throws AtlasException {
AtlasGraphManagement management = provider.get().getManagementSystem();
for (IDataType dataType : dataTypes) {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating indexes for type name={}, definition={}", dataType.getName(), dataType.getClass());
}
try {
addIndexForType(management, dataType);
LOG.info("Index creation for type {} complete", dataType.getName());
} catch (Throwable throwable) {
LOG.error("Error creating index for type {}", dataType, throwable);
//Rollback indexes if any failure
rollback(management);
throw new IndexCreationException("Error while creating index for type " + dataType, throwable);
}
}
//Commit indexes
commit(management);
}
use of org.apache.atlas.typesystem.types.IDataType in project incubator-atlas by apache.
the class Gremlin3ExpressionFactory method generateHasExpression.
@Override
public GroovyExpression generateHasExpression(GraphPersistenceStrategies s, GroovyExpression parent, String propertyName, String symbol, GroovyExpression requiredValue, FieldInfo fInfo) throws AtlasException {
AttributeInfo attrInfo = fInfo.attrInfo();
IDataType attrType = attrInfo.dataType();
GroovyExpression propertNameExpr = new LiteralExpression(propertyName);
if (s.isPropertyValueConversionNeeded(attrType)) {
// for some types, the logical value cannot be stored directly in
// the underlying graph,
// and conversion logic is needed to convert the persistent form of
// the value
// to the actual value. In cases like this, we generate a conversion
// expression to
// do this conversion and use the filter step to perform the
// comparsion in the gremlin query
GroovyExpression itExpr = getItVariable();
GroovyExpression vertexExpr = new CastExpression(new FunctionCallExpression(itExpr, GET_METHOD), VERTEX_CLASS);
GroovyExpression propertyValueExpr = new FunctionCallExpression(vertexExpr, VALUE_METHOD, propertNameExpr);
GroovyExpression conversionExpr = s.generatePersisentToLogicalConversionExpression(propertyValueExpr, attrType);
GroovyExpression propertyIsPresentExpression = new FunctionCallExpression(new FunctionCallExpression(vertexExpr, PROPERTY_METHOD, propertNameExpr), IS_PRESENT_METHOD);
GroovyExpression valueMatchesExpr = new ComparisonExpression(conversionExpr, getGroovyOperator(symbol), requiredValue);
GroovyExpression filterCondition = new LogicalExpression(propertyIsPresentExpression, LogicalOperator.AND, valueMatchesExpr);
GroovyExpression filterFunction = new ClosureExpression(filterCondition);
return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, filterFunction);
} else {
GroovyExpression valueMatches = new FunctionCallExpression(getComparisonFunction(symbol), requiredValue);
return new FunctionCallExpression(TraversalStepType.FILTER, parent, HAS_METHOD, propertNameExpr, valueMatches);
}
}
Aggregations