use of org.apache.atlas.RequestContext 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.RequestContext in project incubator-atlas by apache.
the class GraphBackedMetadataRepository method getEntityDefinitions.
@Override
@GraphTransaction
public List<ITypedReferenceableInstance> getEntityDefinitions(String... guids) throws RepositoryException, EntityNotFoundException {
if (LOG.isDebugEnabled()) {
LOG.debug("Retrieving entities with guids={}", Arrays.toString(guids));
}
RequestContext context = RequestContext.get();
ITypedReferenceableInstance[] result = new ITypedReferenceableInstance[guids.length];
// Map of the guids of instances not in the cache to their index(es) in the result.
// This is used to put the loaded instances into the location(s) corresponding
// to their guid in the result. Note that a set is needed since guids can
// appear more than once in the list.
Map<String, Set<Integer>> uncachedGuids = new HashMap<>();
for (int i = 0; i < guids.length; i++) {
String guid = guids[i];
// First, check the cache.
ITypedReferenceableInstance cached = context.getInstanceV1(guid);
if (cached != null) {
result[i] = cached;
} else {
Set<Integer> indices = uncachedGuids.get(guid);
if (indices == null) {
indices = new HashSet<>(1);
uncachedGuids.put(guid, indices);
}
indices.add(i);
}
}
List<String> guidsToFetch = new ArrayList<>(uncachedGuids.keySet());
Map<String, AtlasVertex> instanceVertices = graphHelper.getVerticesForGUIDs(guidsToFetch);
// search for missing entities
if (instanceVertices.size() != guidsToFetch.size()) {
Set<String> missingGuids = new HashSet<String>(guidsToFetch);
missingGuids.removeAll(instanceVertices.keySet());
if (!missingGuids.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to find guids={}", missingGuids);
}
throw new EntityNotFoundException("Could not find entities in the repository with guids: " + missingGuids.toString());
}
}
for (String guid : guidsToFetch) {
try {
ITypedReferenceableInstance entity = graphToInstanceMapper.mapGraphToTypedInstance(guid, instanceVertices.get(guid));
for (int index : uncachedGuids.get(guid)) {
result[index] = entity;
}
} catch (AtlasException e) {
throw new RepositoryException(e);
}
}
return Arrays.asList(result);
}
use of org.apache.atlas.RequestContext in project incubator-atlas by apache.
the class FullTextMapperV2 method getAndCacheEntity.
private AtlasEntityWithExtInfo getAndCacheEntity(String guid) throws AtlasBaseException {
RequestContext context = RequestContext.get();
AtlasEntityWithExtInfo entityWithExtInfo = context.getInstanceV2(guid);
if (entityWithExtInfo == null) {
entityWithExtInfo = entityGraphRetriever.toAtlasEntityWithExtInfo(guid);
if (entityWithExtInfo != null) {
context.cache(entityWithExtInfo);
if (LOG.isDebugEnabled()) {
LOG.debug("Cache miss -> GUID = {}", guid);
}
}
}
return entityWithExtInfo;
}
use of org.apache.atlas.RequestContext in project incubator-atlas by apache.
the class DeleteHandler method deleteEntities.
/**
* Deletes the specified entity vertices.
* Deletes any traits, composite entities, and structs owned by each entity.
* Also deletes all the references from/to the entity.
*
* @param instanceVertices
* @throws AtlasException
*/
public void deleteEntities(Collection<AtlasVertex> instanceVertices) throws AtlasException {
RequestContext requestContext = RequestContext.get();
Set<AtlasVertex> deletionCandidateVertices = new HashSet<>();
for (AtlasVertex instanceVertex : instanceVertices) {
String guid = GraphHelper.getGuid(instanceVertex);
Id.EntityState state = GraphHelper.getState(instanceVertex);
if (requestContext.getDeletedEntityIds().contains(guid) || state == Id.EntityState.DELETED) {
if (LOG.isDebugEnabled()) {
LOG.debug("Skipping deletion of {} as it is already deleted", guid);
}
continue;
}
// Get GUIDs and vertices for all deletion candidates.
Set<VertexInfo> compositeVertices = graphHelper.getCompositeVertices(instanceVertex);
// and gather deletion candidate vertices.
for (VertexInfo vertexInfo : compositeVertices) {
requestContext.recordEntityDelete(vertexInfo.getGuid(), vertexInfo.getTypeName());
deletionCandidateVertices.add(vertexInfo.getVertex());
}
}
// Delete traits and vertices.
for (AtlasVertex deletionCandidateVertex : deletionCandidateVertices) {
deleteAllTraits(deletionCandidateVertex);
deleteTypeVertex(deletionCandidateVertex, false);
}
}
use of org.apache.atlas.RequestContext in project incubator-atlas by apache.
the class GraphBackedMetadataRepository method updatePartial.
@Override
@GraphTransaction
public CreateUpdateEntitiesResult updatePartial(ITypedReferenceableInstance entity) throws RepositoryException {
if (LOG.isDebugEnabled()) {
LOG.debug("updating entity {}", entity);
}
try {
TypedInstanceToGraphMapper instanceToGraphMapper = new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler);
instanceToGraphMapper.mapTypedInstanceToGraph(TypedInstanceToGraphMapper.Operation.UPDATE_PARTIAL, entity);
RequestContext requestContext = RequestContext.get();
CreateUpdateEntitiesResult result = new CreateUpdateEntitiesResult();
GuidMapping mapping = instanceToGraphMapper.createGuidMapping();
result.setEntityResult(createEntityResultFromContext(requestContext));
result.setGuidMapping(mapping);
return result;
} catch (AtlasException e) {
throw new RepositoryException(e);
}
}
Aggregations