http://git-wip-us.apache.org/repos/asf/atlas/blob/3d5b4880/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java deleted file mode 100644 index b683c6b..0000000 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java +++ /dev/null @@ -1,836 +0,0 @@ - -/** - * 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.store.graph.v1; - -import org.apache.atlas.AtlasErrorCode; -import org.apache.atlas.annotation.GraphTransaction; -import org.apache.atlas.exception.AtlasBaseException; -import org.apache.atlas.model.TypeCategory; -import org.apache.atlas.model.instance.AtlasClassification; -import org.apache.atlas.model.instance.AtlasEntity.Status; -import org.apache.atlas.model.instance.AtlasObjectId; -import org.apache.atlas.model.instance.AtlasRelationship; -import org.apache.atlas.model.instance.AtlasRelationship.AtlasRelationshipWithExtInfo; -import org.apache.atlas.model.typedef.AtlasRelationshipDef; -import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags; -import org.apache.atlas.model.typedef.AtlasRelationshipEndDef; -import org.apache.atlas.repository.Constants; -import org.apache.atlas.repository.RepositoryException; -import org.apache.atlas.repository.graph.GraphHelper; -import org.apache.atlas.repository.graphdb.AtlasEdge; -import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; -import org.apache.atlas.repository.graphdb.AtlasVertex; -import org.apache.atlas.repository.store.graph.AtlasRelationshipStore; -import org.apache.atlas.type.AtlasEntityType; -import org.apache.atlas.type.AtlasRelationshipType; -import org.apache.atlas.type.AtlasStructType.AtlasAttribute; -import org.apache.atlas.type.AtlasTypeRegistry; -import org.apache.atlas.type.AtlasTypeUtil; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; - -import static org.apache.atlas.model.instance.AtlasEntity.Status.ACTIVE; -import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED; -import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.ONE_TO_TWO; -import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.TWO_TO_ONE; -import static org.apache.atlas.repository.graph.GraphHelper.getBlockedClassificationIds; -import static org.apache.atlas.repository.graph.GraphHelper.getClassificationEntityGuid; -import static org.apache.atlas.repository.graph.GraphHelper.getClassificationName; -import static org.apache.atlas.repository.graph.GraphHelper.getClassificationVertices; -import static org.apache.atlas.repository.graph.GraphHelper.getOutGoingEdgesByLabel; -import static org.apache.atlas.repository.graph.GraphHelper.getPropagateTags; -import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getIdFromVertex; -import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getState; -import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getTypeName; - -@Component -public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { - private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipStoreV1.class); - - private static final Long DEFAULT_RELATIONSHIP_VERSION = 0L; - - private final AtlasTypeRegistry typeRegistry; - private final EntityGraphRetriever entityRetriever; - private final DeleteHandlerV1 deleteHandler; - private final GraphHelper graphHelper = GraphHelper.getInstance(); - private final AtlasEntityChangeNotifier entityChangeNotifier; - - @Inject - public AtlasRelationshipStoreV1(AtlasTypeRegistry typeRegistry, DeleteHandlerV1 deleteHandler, AtlasEntityChangeNotifier entityChangeNotifier) { - this.typeRegistry = typeRegistry; - this.entityRetriever = new EntityGraphRetriever(typeRegistry); - this.deleteHandler = deleteHandler; - this.entityChangeNotifier = entityChangeNotifier; - } - - @Override - @GraphTransaction - public AtlasRelationship create(AtlasRelationship relationship) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> create({})", relationship); - } - - AtlasVertex end1Vertex = getVertexFromEndPoint(relationship.getEnd1()); - AtlasVertex end2Vertex = getVertexFromEndPoint(relationship.getEnd2()); - - validateRelationship(end1Vertex, end2Vertex, relationship.getTypeName(), relationship.getAttributes()); - - AtlasEdge edge = createRelationship(end1Vertex, end2Vertex, relationship); - - AtlasRelationship ret = edge != null ? entityRetriever.mapEdgeToAtlasRelationship(edge) : null; - - if (LOG.isDebugEnabled()) { - LOG.debug("<== create({}): {}", relationship, ret); - } - - // notify entities for added/removed classification propagation - entityChangeNotifier.notifyPropagatedEntities(); - - return ret; - } - - @Override - @GraphTransaction - public AtlasRelationship update(AtlasRelationship relationship) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> update({})", relationship); - } - - String guid = relationship.getGuid(); - - if (StringUtils.isEmpty(guid)) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid); - } - - AtlasEdge edge = graphHelper.getEdgeForGUID(guid); - String edgeType = AtlasGraphUtilsV1.getTypeName(edge); - AtlasVertex end1Vertex = edge.getOutVertex(); - AtlasVertex end2Vertex = edge.getInVertex(); - - // update shouldn't change endType - if (StringUtils.isNotEmpty(relationship.getTypeName()) && !StringUtils.equalsIgnoreCase(edgeType, relationship.getTypeName())) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_UPDATE_TYPE_CHANGE_NOT_ALLOWED, guid, edgeType, relationship.getTypeName()); - } - - // update shouldn't change ends - if (relationship.getEnd1() != null) { - String updatedEnd1Guid = relationship.getEnd1().getGuid(); - - if (updatedEnd1Guid == null) { - AtlasVertex updatedEnd1Vertex = getVertexFromEndPoint(relationship.getEnd1()); - - updatedEnd1Guid = updatedEnd1Vertex == null ? null : AtlasGraphUtilsV1.getIdFromVertex(updatedEnd1Vertex); - } - - if (updatedEnd1Guid != null) { - String end1Guid = AtlasGraphUtilsV1.getIdFromVertex(end1Vertex); - - if (!StringUtils.equalsIgnoreCase(relationship.getEnd1().getGuid(), end1Guid)) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_UPDATE_END_CHANGE_NOT_ALLOWED, edgeType, guid, end1Guid, relationship.getEnd1().getGuid()); - } - } - } - - // update shouldn't change ends - if (relationship.getEnd2() != null) { - String updatedEnd2Guid = relationship.getEnd2().getGuid(); - - if (updatedEnd2Guid == null) { - AtlasVertex updatedEnd2Vertex = getVertexFromEndPoint(relationship.getEnd2()); - - updatedEnd2Guid = updatedEnd2Vertex == null ? null : AtlasGraphUtilsV1.getIdFromVertex(updatedEnd2Vertex); - } - - if (updatedEnd2Guid != null) { - String end2Guid = AtlasGraphUtilsV1.getIdFromVertex(end2Vertex); - - if (!StringUtils.equalsIgnoreCase(relationship.getEnd2().getGuid(), end2Guid)) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_UPDATE_END_CHANGE_NOT_ALLOWED, AtlasGraphUtilsV1.getTypeName(edge), guid, end2Guid, relationship.getEnd2().getGuid()); - } - } - } - - - validateRelationship(end1Vertex, end2Vertex, edgeType, relationship.getAttributes()); - - AtlasRelationship ret = updateRelationship(edge, relationship); - - // notify entities for added/removed classification propagation - entityChangeNotifier.notifyPropagatedEntities(); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== update({}): {}", relationship, ret); - } - - return ret; - } - - @Override - @GraphTransaction - public AtlasRelationship getById(String guid) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> getById({})", guid); - } - - AtlasEdge edge = graphHelper.getEdgeForGUID(guid); - AtlasRelationship ret = entityRetriever.mapEdgeToAtlasRelationship(edge); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== getById({}): {}", guid, ret); - } - - return ret; - } - - @Override - @GraphTransaction - public AtlasRelationshipWithExtInfo getExtInfoById(String guid) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> getExtInfoById({})", guid); - } - - AtlasEdge edge = graphHelper.getEdgeForGUID(guid); - AtlasRelationshipWithExtInfo ret = entityRetriever.mapEdgeToAtlasRelationshipWithExtInfo(edge); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== getExtInfoById({}): {}", guid, ret); - } - - return ret; - } - - @Override - @GraphTransaction - public void deleteById(String guid) throws AtlasBaseException { - deleteById(guid, false); - } - - @Override - @GraphTransaction - public void deleteById(String guid, boolean forceDelete) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> deleteById({}, {})", guid, forceDelete); - } - - if (StringUtils.isEmpty(guid)) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_CRUD_INVALID_PARAMS, " empty/null guid"); - } - - AtlasEdge edge = graphHelper.getEdgeForGUID(guid); - - if (edge == null) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid); - } - - if (getState(edge) == DELETED) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_DELETED, guid); - } - - deleteHandler.deleteRelationships(Collections.singleton(edge), forceDelete); - - // notify entities for added/removed classification propagation - entityChangeNotifier.notifyPropagatedEntities(); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== deleteById({}): {}", guid); - } - } - - @Override - public AtlasEdge getOrCreate(AtlasVertex end1Vertex, AtlasVertex end2Vertex, AtlasRelationship relationship) throws AtlasBaseException { - AtlasEdge ret = getRelationshipEdge(end1Vertex, end2Vertex, relationship.getTypeName()); - - if (ret == null) { - validateRelationship(end1Vertex, end2Vertex, relationship.getTypeName(), relationship.getAttributes()); - - ret = createRelationship(end1Vertex, end2Vertex, relationship); - } - - return ret; - } - - @Override - public AtlasRelationship getOrCreate(AtlasRelationship relationship) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> getOrCreate({})", relationship); - } - - validateRelationship(relationship); - - AtlasVertex end1Vertex = getVertexFromEndPoint(relationship.getEnd1()); - AtlasVertex end2Vertex = getVertexFromEndPoint(relationship.getEnd2()); - AtlasRelationship ret = null; - - // check if relationship exists - AtlasEdge relationshipEdge = getRelationshipEdge(end1Vertex, end2Vertex, relationship.getTypeName()); - - if (relationshipEdge == null) { - validateRelationship(relationship); - - relationshipEdge = createRelationship(end1Vertex, end2Vertex, relationship); - } - - if (relationshipEdge != null){ - ret = entityRetriever.mapEdgeToAtlasRelationship(relationshipEdge); - } - - if (LOG.isDebugEnabled()) { - LOG.debug("<== getOrCreate({}): {}", relationship, ret); - } - - return ret; - } - - private AtlasEdge createRelationship(AtlasVertex end1Vertex, AtlasVertex end2Vertex, AtlasRelationship relationship) throws AtlasBaseException { - AtlasEdge ret = null; - - try { - ret = getRelationshipEdge(end1Vertex, end2Vertex, relationship.getTypeName()); - - if (ret == null) { - ret = createRelationshipEdge(end1Vertex, end2Vertex, relationship); - - AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName()); - - if (MapUtils.isNotEmpty(relationType.getAllAttributes())) { - for (AtlasAttribute attr : relationType.getAllAttributes().values()) { - String attrName = attr.getName(); - String attrVertexProperty = attr.getVertexPropertyName(); - Object attrValue = relationship.getAttribute(attrName); - - AtlasGraphUtilsV1.setProperty(ret, attrVertexProperty, attrValue); - } - } - } else { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_EXISTS, relationship.getTypeName(), - AtlasGraphUtilsV1.getIdFromVertex(end1Vertex), AtlasGraphUtilsV1.getIdFromVertex(end2Vertex)); - } - } catch (RepositoryException e) { - throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, e); - } - - return ret; - } - - private AtlasRelationship updateRelationship(AtlasEdge relationshipEdge, AtlasRelationship relationship) throws AtlasBaseException { - AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName()); - - updateTagPropagations(relationshipEdge, relationship); - - if (MapUtils.isNotEmpty(relationType.getAllAttributes())) { - for (AtlasAttribute attr : relationType.getAllAttributes().values()) { - String attrName = attr.getName(); - String attrVertexProperty = attr.getVertexPropertyName(); - - if (relationship.hasAttribute(attrName)) { - AtlasGraphUtilsV1.setProperty(relationshipEdge, attrVertexProperty, relationship.getAttribute(attrName)); - } - } - } - - return entityRetriever.mapEdgeToAtlasRelationship(relationshipEdge); - } - - private void handleBlockedClassifications(AtlasEdge edge, Set<AtlasClassification> blockedPropagatedClassifications) throws AtlasBaseException { - if (blockedPropagatedClassifications != null) { - List<AtlasVertex> propagatedClassificationVertices = getClassificationVertices(edge); - List<String> currentClassificationIds = getBlockedClassificationIds(edge); - List<AtlasVertex> currentBlockedPropagatedClassificationVertices = getBlockedClassificationVertices(propagatedClassificationVertices, currentClassificationIds); - List<AtlasVertex> updatedBlockedPropagatedClassificationVertices = new ArrayList<>(); - List<String> updatedClassificationIds = new ArrayList<>(); - - for (AtlasClassification classification : blockedPropagatedClassifications) { - AtlasVertex classificationVertex = validateBlockedPropagatedClassification(propagatedClassificationVertices, classification); - - // ignore invalid blocked propagated classification - if (classificationVertex == null) { - continue; - } - - updatedBlockedPropagatedClassificationVertices.add(classificationVertex); - - String classificationId = classificationVertex.getIdForDisplay(); - - updatedClassificationIds.add(classificationId); - } - - addToBlockedClassificationIds(edge, updatedClassificationIds); - - // remove propagated tag for added entry - List<AtlasVertex> addedBlockedClassifications = (List<AtlasVertex>) CollectionUtils.subtract(updatedBlockedPropagatedClassificationVertices, currentBlockedPropagatedClassificationVertices); - - for (AtlasVertex classificationVertex : addedBlockedClassifications) { - List<AtlasVertex> removePropagationFromVertices = graphHelper.getPropagatedEntityVertices(classificationVertex); - - deleteHandler.removeTagPropagation(classificationVertex, removePropagationFromVertices); - } - - // add propagated tag for removed entry - List<AtlasVertex> removedBlockedClassifications = (List<AtlasVertex>) CollectionUtils.subtract(currentBlockedPropagatedClassificationVertices, updatedBlockedPropagatedClassificationVertices); - - for (AtlasVertex classificationVertex : removedBlockedClassifications) { - List<AtlasVertex> addPropagationToVertices = graphHelper.getPropagatedEntityVertices(classificationVertex); - - deleteHandler.addTagPropagation(classificationVertex, addPropagationToVertices); - } - } - } - - private List<AtlasVertex> getBlockedClassificationVertices(List<AtlasVertex> classificationVertices, List<String> blockedClassificationIds) { - List<AtlasVertex> ret = new ArrayList<>(); - - if (CollectionUtils.isNotEmpty(blockedClassificationIds)) { - for (AtlasVertex classificationVertex : classificationVertices) { - String classificationId = classificationVertex.getIdForDisplay(); - - if (blockedClassificationIds.contains(classificationId)) { - ret.add(classificationVertex); - } - } - } - - return ret; - } - - // propagated classifications should contain blocked propagated classification - private AtlasVertex validateBlockedPropagatedClassification(List<AtlasVertex> classificationVertices, AtlasClassification classification) { - AtlasVertex ret = null; - - for (AtlasVertex vertex : classificationVertices) { - String classificationName = getClassificationName(vertex); - String entityGuid = getClassificationEntityGuid(vertex); - - if (classificationName.equals(classification.getTypeName()) && entityGuid.equals(classification.getEntityGuid())) { - ret = vertex; - break; - } - } - - return ret; - } - - private void addToBlockedClassificationIds(AtlasEdge edge, List<String> classificationIds) { - if (edge != null) { - if (classificationIds.isEmpty()) { - edge.removeProperty(Constants.RELATIONSHIPTYPE_BLOCKED_PROPAGATED_CLASSIFICATIONS_KEY); - } else { - edge.setListProperty(Constants.RELATIONSHIPTYPE_BLOCKED_PROPAGATED_CLASSIFICATIONS_KEY, classificationIds); - } - } - } - - private void updateTagPropagations(AtlasEdge edge, AtlasRelationship relationship) throws AtlasBaseException { - PropagateTags oldTagPropagation = getPropagateTags(edge); - PropagateTags newTagPropagation = relationship.getPropagateTags(); - - if (newTagPropagation != oldTagPropagation) { - List<AtlasVertex> currentClassificationVertices = getClassificationVertices(edge); - Map<AtlasVertex, List<AtlasVertex>> currentClassificationsMap = graphHelper.getClassificationPropagatedEntitiesMapping(currentClassificationVertices); - - // Update propagation edge - AtlasGraphUtilsV1.setProperty(edge, Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, newTagPropagation.name()); - - List<AtlasVertex> updatedClassificationVertices = getClassificationVertices(edge); - List<AtlasVertex> classificationVerticesUnion = (List<AtlasVertex>) CollectionUtils.union(currentClassificationVertices, updatedClassificationVertices); - Map<AtlasVertex, List<AtlasVertex>> updatedClassificationsMap = graphHelper.getClassificationPropagatedEntitiesMapping(classificationVerticesUnion); - - // compute add/remove propagations list - Map<AtlasVertex, List<AtlasVertex>> addPropagationsMap = new HashMap<>(); - Map<AtlasVertex, List<AtlasVertex>> removePropagationsMap = new HashMap<>(); - - if (MapUtils.isEmpty(currentClassificationsMap) && MapUtils.isNotEmpty(updatedClassificationsMap)) { - addPropagationsMap.putAll(updatedClassificationsMap); - - } else if (MapUtils.isNotEmpty(currentClassificationsMap) && MapUtils.isEmpty(updatedClassificationsMap)) { - removePropagationsMap.putAll(currentClassificationsMap); - - } else { - for (AtlasVertex classificationVertex : updatedClassificationsMap.keySet()) { - List<AtlasVertex> currentPropagatingEntities = currentClassificationsMap.containsKey(classificationVertex) ? currentClassificationsMap.get(classificationVertex) : Collections.emptyList(); - List<AtlasVertex> updatedPropagatingEntities = updatedClassificationsMap.containsKey(classificationVertex) ? updatedClassificationsMap.get(classificationVertex) : Collections.emptyList(); - - List<AtlasVertex> entitiesAdded = (List<AtlasVertex>) CollectionUtils.subtract(updatedPropagatingEntities, currentPropagatingEntities); - List<AtlasVertex> entitiesRemoved = (List<AtlasVertex>) CollectionUtils.subtract(currentPropagatingEntities, updatedPropagatingEntities); - - if (CollectionUtils.isNotEmpty(entitiesAdded)) { - addPropagationsMap.put(classificationVertex, entitiesAdded); - } - - if (CollectionUtils.isNotEmpty(entitiesRemoved)) { - removePropagationsMap.put(classificationVertex, entitiesRemoved); - } - } - } - - for (AtlasVertex classificationVertex : addPropagationsMap.keySet()) { - deleteHandler.addTagPropagation(classificationVertex, addPropagationsMap.get(classificationVertex)); - } - - for (AtlasVertex classificationVertex : removePropagationsMap.keySet()) { - deleteHandler.removeTagPropagation(classificationVertex, removePropagationsMap.get(classificationVertex)); - } - } else { - // update blocked propagated classifications only if there is no change is tag propagation (don't update both) - handleBlockedClassifications(edge, relationship.getBlockedPropagatedClassifications()); - } - } - - private void validateRelationship(AtlasRelationship relationship) throws AtlasBaseException { - if (relationship == null) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "AtlasRelationship is null"); - } - - String relationshipName = relationship.getTypeName(); - String end1TypeName = getTypeNameFromObjectId(relationship.getEnd1()); - String end2TypeName = getTypeNameFromObjectId(relationship.getEnd2()); - AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipName); - - if (relationshipType == null) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_VALUE, "unknown relationship type'" + relationshipName + "'"); - } - - if (relationship.getEnd1() == null || relationship.getEnd2() == null) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "end1/end2 is null"); - } - - boolean validEndTypes = false; - - if (relationshipType.getEnd1Type().isTypeOrSuperTypeOf(end1TypeName)) { - validEndTypes = relationshipType.getEnd2Type().isTypeOrSuperTypeOf(end2TypeName); - } else if (relationshipType.getEnd2Type().isTypeOrSuperTypeOf(end1TypeName)) { - validEndTypes = relationshipType.getEnd1Type().isTypeOrSuperTypeOf(end2TypeName); - } - - if (!validEndTypes) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_END_TYPE, relationshipName, relationshipType.getEnd2Type().getTypeName(), end1TypeName); - } - - validateEnds(relationship); - - validateAndNormalize(relationship); - } - - private void validateRelationship(AtlasVertex end1Vertex, AtlasVertex end2Vertex, String relationshipName, Map<String, Object> attributes) throws AtlasBaseException { - AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipName); - - if (relationshipType == null) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_VALUE, "unknown relationship type'" + relationshipName + "'"); - } - - if (end1Vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_END_IS_NULL, relationshipType.getEnd1Type().getTypeName()); - } - - if (end2Vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_END_IS_NULL, relationshipType.getEnd2Type().getTypeName()); - } - - String end1TypeName = AtlasGraphUtilsV1.getTypeName(end1Vertex); - String end2TypeName = AtlasGraphUtilsV1.getTypeName(end2Vertex); - - boolean validEndTypes = false; - - if (relationshipType.getEnd1Type().isTypeOrSuperTypeOf(end1TypeName)) { - validEndTypes = relationshipType.getEnd2Type().isTypeOrSuperTypeOf(end2TypeName); - } else if (relationshipType.getEnd2Type().isTypeOrSuperTypeOf(end1TypeName)) { - validEndTypes = relationshipType.getEnd1Type().isTypeOrSuperTypeOf(end2TypeName); - } - - if (!validEndTypes) { - throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_END_TYPE, relationshipName, relationshipType.getEnd2Type().getTypeName(), end1TypeName); - } - - List<String> messages = new ArrayList<>(); - AtlasRelationship relationship = new AtlasRelationship(relationshipName, attributes); - - relationshipType.validateValue(relationship, relationshipName, messages); - - if (!messages.isEmpty()) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_CRUD_INVALID_PARAMS, messages); - } - - relationshipType.getNormalizedValue(relationship); - } - - - /** - * Validate the ends of the passed relationship - * @param relationship - * @throws AtlasBaseException - */ - private void validateEnds(AtlasRelationship relationship) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("validateEnds entry relationship:" + relationship); - } - List<AtlasObjectId> ends = new ArrayList<>(); - List<AtlasRelationshipEndDef> endDefs = new ArrayList<>(); - String relationshipTypeName = relationship.getTypeName(); - AtlasRelationshipDef relationshipDef = typeRegistry.getRelationshipDefByName(relationshipTypeName); - - ends.add(relationship.getEnd1()); - ends.add(relationship.getEnd2()); - endDefs.add(relationshipDef.getEndDef1()); - endDefs.add(relationshipDef.getEndDef2()); - - for (int i = 0; i < ends.size(); i++) { - AtlasObjectId end = ends.get(i); - String guid = end.getGuid(); - String typeName = end.getTypeName(); - Map<String, Object> uniqueAttributes = end.getUniqueAttributes(); - AtlasVertex endVertex = AtlasGraphUtilsV1.findByGuid(guid); - - if (!AtlasTypeUtil.isValidGuid(guid) || endVertex == null) { - throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); - - } else if (MapUtils.isNotEmpty(uniqueAttributes)) { - AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); - - if (AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqueAttributes) == null) { - throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, typeName, uniqueAttributes.toString()); - } - } else { - // check whether the guid is the correct type - String vertexTypeName = endVertex.getProperty(Constants.TYPE_NAME_PROPERTY_KEY, String.class); - - if (!Objects.equals(vertexTypeName, typeName)) { - String attrName = endDefs.get(i).getName(); - - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_INVALID_ENDTYPE, attrName, guid, vertexTypeName, typeName); - } - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug("validateEnds exit successfully validated relationship:" + relationship); - } - } - - private void validateAndNormalize(AtlasRelationship relationship) throws AtlasBaseException { - List<String> messages = new ArrayList<>(); - - if (! AtlasTypeUtil.isValidGuid(relationship.getGuid())) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, relationship.getGuid()); - } - - AtlasRelationshipType type = typeRegistry.getRelationshipTypeByName(relationship.getTypeName()); - - if (type == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.RELATIONSHIP.name(), relationship.getTypeName()); - } - - type.validateValue(relationship, relationship.getTypeName(), messages); - - if (!messages.isEmpty()) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_CRUD_INVALID_PARAMS, messages); - } - - type.getNormalizedValue(relationship); - } - - public AtlasEdge getRelationshipEdge(AtlasVertex fromVertex, AtlasVertex toVertex, String relationshipType) { - String relationshipLabel = getRelationshipEdgeLabel(fromVertex, toVertex, relationshipType); - Iterator<AtlasEdge> edgesIterator = getOutGoingEdgesByLabel(fromVertex, relationshipLabel); - AtlasEdge ret = null; - - while (edgesIterator != null && edgesIterator.hasNext()) { - AtlasEdge edge = edgesIterator.next(); - - if (edge != null) { - Status status = graphHelper.getStatus(edge); - - if ((status == null || status == ACTIVE) && - StringUtils.equals(getIdFromVertex(edge.getInVertex()), getIdFromVertex(toVertex))) { - ret = edge; - break; - } - } - } - - return ret; - } - - private Long getRelationshipVersion(AtlasRelationship relationship) { - Long ret = relationship != null ? relationship.getVersion() : null; - - return (ret != null) ? ret : DEFAULT_RELATIONSHIP_VERSION; - } - - private AtlasVertex getVertexFromEndPoint(AtlasObjectId endPoint) { - AtlasVertex ret = null; - - if (StringUtils.isNotEmpty(endPoint.getGuid())) { - ret = AtlasGraphUtilsV1.findByGuid(endPoint.getGuid()); - } else if (StringUtils.isNotEmpty(endPoint.getTypeName()) && MapUtils.isNotEmpty(endPoint.getUniqueAttributes())) { - AtlasEntityType entityType = typeRegistry.getEntityTypeByName(endPoint.getTypeName()); - - ret = AtlasGraphUtilsV1.findByUniqueAttributes(entityType, endPoint.getUniqueAttributes()); - } - - return ret; - } - - private AtlasEdge createRelationshipEdge(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) throws RepositoryException, AtlasBaseException { - String relationshipLabel = getRelationshipEdgeLabel(fromVertex, toVertex, relationship.getTypeName()); - PropagateTags tagPropagation = getRelationshipTagPropagation(fromVertex, toVertex, relationship); - AtlasEdge ret = graphHelper.getOrCreateEdge(fromVertex, toVertex, relationshipLabel); - - if (LOG.isDebugEnabled()) { - LOG.debug("Created relationship edge from [{}] --> [{}] using edge label: [{}]", getTypeName(fromVertex), getTypeName(toVertex), relationshipLabel); - } - - // map additional properties to relationship edge - if (ret != null) { - final String guid = UUID.randomUUID().toString(); - - AtlasGraphUtilsV1.setProperty(ret, Constants.ENTITY_TYPE_PROPERTY_KEY, relationship.getTypeName()); - AtlasGraphUtilsV1.setProperty(ret, Constants.RELATIONSHIP_GUID_PROPERTY_KEY, guid); - AtlasGraphUtilsV1.setProperty(ret, Constants.VERSION_PROPERTY_KEY, getRelationshipVersion(relationship)); - AtlasGraphUtilsV1.setProperty(ret, Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, tagPropagation.name()); - - // blocked propagated classifications - handleBlockedClassifications(ret, relationship.getBlockedPropagatedClassifications()); - - // propagate tags - deleteHandler.addTagPropagation(ret, tagPropagation); - } - - return ret; - } - - private PropagateTags getRelationshipTagPropagation(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) { - AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName()); - AtlasRelationshipEndDef endDef1 = relationshipType.getRelationshipDef().getEndDef1(); - AtlasRelationshipEndDef endDef2 = relationshipType.getRelationshipDef().getEndDef2(); - Set<String> fromVertexTypes = getTypeAndAllSuperTypes(getTypeName(fromVertex)); - Set<String> toVertexTypes = getTypeAndAllSuperTypes(getTypeName(toVertex)); - PropagateTags ret = relationshipType.getRelationshipDef().getPropagateTags(); - - // relationshipDef is defined as end1 (hive_db) and end2 (hive_table) and tagPropagation = ONE_TO_TWO - // relationship edge exists from [hive_table --> hive_db] - // swap the tagPropagation property for such cases. - if (fromVertexTypes.contains(endDef2.getType()) && toVertexTypes.contains(endDef1.getType())) { - if (ret == ONE_TO_TWO) { - ret = TWO_TO_ONE; - } else if (ret == TWO_TO_ONE) { - ret = ONE_TO_TWO; - } - } - - return ret; - } - - private String getRelationshipEdgeLabel(AtlasVertex fromVertex, AtlasVertex toVertex, String relationshipTypeName) { - if (LOG.isDebugEnabled()) { - LOG.debug("getRelationshipEdgeLabel({})", relationshipTypeName); - } - - AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipTypeName); - String ret = relationshipType.getRelationshipDef().getRelationshipLabel(); - AtlasRelationshipEndDef endDef1 = relationshipType.getRelationshipDef().getEndDef1(); - AtlasRelationshipEndDef endDef2 = relationshipType.getRelationshipDef().getEndDef2(); - Set<String> fromVertexTypes = getTypeAndAllSuperTypes(AtlasGraphUtilsV1.getTypeName(fromVertex)); - Set<String> toVertexTypes = getTypeAndAllSuperTypes(AtlasGraphUtilsV1.getTypeName(toVertex)); - AtlasAttribute attribute = null; - - // validate entity type and all its supertypes contains relationshipDefs end type - // e.g. [hive_process -> hive_table] -> [Process -> DataSet] - if (fromVertexTypes.contains(endDef1.getType()) && toVertexTypes.contains(endDef2.getType())) { - String attributeName = endDef1.getName(); - - attribute = relationshipType.getEnd1Type().getRelationshipAttribute(attributeName); - - } else if (fromVertexTypes.contains(endDef2.getType()) && toVertexTypes.contains(endDef1.getType())) { - String attributeName = endDef2.getName(); - - attribute = relationshipType.getEnd2Type().getRelationshipAttribute(attributeName); - } - - if (attribute != null) { - ret = attribute.getRelationshipEdgeLabel(); - } - - return ret; - } - - public Set<String> getTypeAndAllSuperTypes(String entityTypeName) { - AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName); - - return (entityType != null) ? entityType.getTypeAndAllSuperTypes() : new HashSet<String>(); - } - - private String getTypeNameFromObjectId(AtlasObjectId objectId) { - String typeName = objectId.getTypeName(); - - if (StringUtils.isBlank(typeName)) { - typeName = AtlasGraphUtilsV1.getTypeNameFromGuid(objectId.getGuid()); - } - - return typeName; - } - - /** - * Check whether this vertex has a relationship associated with this relationship type. - * @param vertex - * @param relationshipTypeName - * @return true if found an edge with this relationship type in. - */ - private boolean vertexHasRelationshipWithType(AtlasVertex vertex, String relationshipTypeName) { - String relationshipEdgeLabel = getRelationshipEdgeLabel(getTypeName(vertex), relationshipTypeName); - Iterator<AtlasEdge> iter = graphHelper.getAdjacentEdgesByLabel(vertex, AtlasEdgeDirection.BOTH, relationshipEdgeLabel); - - return (iter != null) ? iter.hasNext() : false; - } - - private String getRelationshipEdgeLabel(String typeName, String relationshipTypeName) { - AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipTypeName); - AtlasRelationshipDef relationshipDef = relationshipType.getRelationshipDef(); - AtlasEntityType end1Type = relationshipType.getEnd1Type(); - AtlasEntityType end2Type = relationshipType.getEnd2Type(); - Set<String> vertexTypes = getTypeAndAllSuperTypes(typeName); - AtlasAttribute attribute = null; - - if (vertexTypes.contains(end1Type.getTypeName())) { - String attributeName = relationshipDef.getEndDef1().getName(); - - attribute = (attributeName != null) ? end1Type.getAttribute(attributeName) : null; - } else if (vertexTypes.contains(end2Type.getTypeName())) { - String attributeName = relationshipDef.getEndDef2().getName(); - - attribute = (attributeName != null) ? end2Type.getAttribute(attributeName) : null; - } - - return (attribute != null) ? attribute.getRelationshipEdgeLabel() : null; - } -} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/3d5b4880/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java deleted file mode 100644 index cf1d307..0000000 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java +++ /dev/null @@ -1,611 +0,0 @@ -/** - * 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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.store.graph.v1; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.atlas.AtlasErrorCode; -import org.apache.atlas.authorize.AtlasPrivilege; -import org.apache.atlas.authorize.AtlasTypeAccessRequest; -import org.apache.atlas.authorize.AtlasAuthorizationUtils; -import org.apache.atlas.exception.AtlasBaseException; -import org.apache.atlas.model.typedef.AtlasStructDef; -import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; -import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef; -import org.apache.atlas.v1.model.typedef.AttributeDefinition; -import org.apache.atlas.repository.Constants; -import org.apache.atlas.repository.graph.GraphHelper; -import org.apache.atlas.repository.graphdb.AtlasVertex; -import org.apache.atlas.type.AtlasStructType; -import org.apache.atlas.type.AtlasStructType.AtlasAttribute; -import org.apache.atlas.type.AtlasType; -import org.apache.atlas.type.AtlasTypeRegistry; -import org.apache.atlas.type.AtlasTypeUtil; -import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; -import org.apache.atlas.v1.model.typedef.Multiplicity; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * StructDef store in v1 format. - */ -public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDef> { - private static final Logger LOG = LoggerFactory.getLogger(AtlasStructDefStoreV1.class); - - public AtlasStructDefStoreV1(AtlasTypeDefGraphStoreV1 typeDefStore, AtlasTypeRegistry typeRegistry) { - super(typeDefStore, typeRegistry); - } - - @Override - public AtlasVertex preCreate(AtlasStructDef structDef) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.preCreate({})", structDef); - } - - validateType(structDef); - - AtlasType type = typeRegistry.getType(structDef.getName()); - - if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, structDef.getName(), TypeCategory.STRUCT.name()); - } - - AtlasVertex ret = typeDefStore.findTypeVertexByName(structDef.getName()); - - if (ret != null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, structDef.getName()); - } - - ret = typeDefStore.createTypeVertex(structDef); - - AtlasStructDefStoreV1.updateVertexPreCreate(structDef, (AtlasStructType)type, ret, typeDefStore); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.preCreate({}): {}", structDef, ret); - } - - return ret; - } - - @Override - public AtlasStructDef create(AtlasStructDef structDef, AtlasVertex preCreateResult) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.create({}, {})", structDef, preCreateResult); - } - - AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, structDef), "create struct-def ", structDef.getName()); - - if (CollectionUtils.isEmpty(structDef.getAttributeDefs())) { - throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Missing attributes for structdef"); - } - - AtlasVertex vertex = (preCreateResult == null) ? preCreate(structDef) : preCreateResult; - - AtlasStructDefStoreV1.updateVertexAddReferences(structDef, vertex, typeDefStore); - - AtlasStructDef ret = toStructDef(vertex); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.create({}, {}): {}", structDef, preCreateResult, ret); - } - - return ret; - } - - @Override - public List<AtlasStructDef> getAll() throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.getAll()"); - } - - List<AtlasStructDef> ret = new ArrayList<>(); - - Iterator<AtlasVertex> vertices = typeDefStore.findTypeVerticesByCategory(TypeCategory.STRUCT); - while (vertices.hasNext()) { - ret.add(toStructDef(vertices.next())); - } - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.getAll(): count={}", ret.size()); - } - return ret; - } - - @Override - public AtlasStructDef getByName(String name) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.getByName({})", name); - } - - AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.STRUCT); - - if (vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); - } - - vertex.getProperty(Constants.TYPE_CATEGORY_PROPERTY_KEY, String.class); - - AtlasStructDef ret = toStructDef(vertex); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.getByName({}): {}", name, ret); - } - - return ret; - } - - @Override - public AtlasStructDef getByGuid(String guid) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.getByGuid({})", guid); - } - - AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.STRUCT); - - if (vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid); - } - - AtlasStructDef ret = toStructDef(vertex); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.getByGuid({}): {}", guid, ret); - } - - return ret; - } - - @Override - public AtlasStructDef update(AtlasStructDef structDef) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.update({})", structDef); - } - - validateType(structDef); - - AtlasStructDef ret = StringUtils.isNotBlank(structDef.getGuid()) ? updateByGuid(structDef.getGuid(), structDef) - : updateByName(structDef.getName(), structDef); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.update({}): {}", structDef, ret); - } - - return ret; - } - - @Override - public AtlasStructDef updateByName(String name, AtlasStructDef structDef) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.updateByName({}, {})", name, structDef); - } - - AtlasStructDef existingDef = typeRegistry.getStructDefByName(name); - - AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update struct-def ", name); - - validateType(structDef); - - AtlasType type = typeRegistry.getType(structDef.getName()); - - if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, structDef.getName(), TypeCategory.STRUCT.name()); - } - - AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.STRUCT); - - if (vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); - } - - AtlasStructDefStoreV1.updateVertexPreUpdate(structDef, (AtlasStructType)type, vertex, typeDefStore); - AtlasStructDefStoreV1.updateVertexAddReferences(structDef, vertex, typeDefStore); - - AtlasStructDef ret = toStructDef(vertex); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.updateByName({}, {}): {}", name, structDef, ret); - } - - return ret; - } - - @Override - public AtlasStructDef updateByGuid(String guid, AtlasStructDef structDef) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.updateByGuid({})", guid); - } - - AtlasStructDef existingDef = typeRegistry.getStructDefByGuid(guid); - - AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update struct-def ", (existingDef != null ? existingDef.getName() : guid)); - - validateType(structDef); - - AtlasType type = typeRegistry.getTypeByGuid(guid); - - if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, structDef.getName(), TypeCategory.STRUCT.name()); - } - - AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.STRUCT); - - if (vertex == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid); - } - - AtlasStructDefStoreV1.updateVertexPreUpdate(structDef, (AtlasStructType)type, vertex, typeDefStore); - AtlasStructDefStoreV1.updateVertexAddReferences(structDef, vertex, typeDefStore); - - AtlasStructDef ret = toStructDef(vertex); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.updateByGuid({}): {}", guid, ret); - } - - return ret; - } - - @Override - public AtlasVertex preDeleteByName(String name) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.preDeleteByName({})", name); - } - - AtlasStructDef existingDef = typeRegistry.getStructDefByName(name); - - AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete struct-def ", name); - - AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.STRUCT); - - if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, name); - } - - if (ret == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name); - } - - typeDefStore.deleteTypeVertexOutEdges(ret); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.preDeleteByName({}): {}", name, ret); - } - - return ret; - } - - @Override - public AtlasVertex preDeleteByGuid(String guid) throws AtlasBaseException { - if (LOG.isDebugEnabled()) { - LOG.debug("==> AtlasStructDefStoreV1.preDeleteByGuid({})", guid); - } - - AtlasStructDef existingDef = typeRegistry.getStructDefByGuid(guid); - - AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete struct-def ", (existingDef != null ? existingDef.getName() : guid)); - - AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.STRUCT); - - String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class); - - if (AtlasGraphUtilsV1.typeHasInstanceVertex(typeName)) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, typeName); - } - - if (ret == null) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid); - } - - typeDefStore.deleteTypeVertexOutEdges(ret); - - if (LOG.isDebugEnabled()) { - LOG.debug("<== AtlasStructDefStoreV1.preDeleteByGuid({}): {}", guid, ret); - } - - return ret; - } - - private AtlasStructDef toStructDef(AtlasVertex vertex) throws AtlasBaseException { - AtlasStructDef ret = null; - - if (vertex != null && typeDefStore.isTypeVertex(vertex, TypeCategory.STRUCT)) { - ret = toStructDef(vertex, new AtlasStructDef(), typeDefStore); - } - - return ret; - } - - public static void updateVertexPreCreate(AtlasStructDef structDef, AtlasStructType structType, - AtlasVertex vertex, AtlasTypeDefGraphStoreV1 typeDefStore) throws AtlasBaseException { - List<String> attrNames = new ArrayList<>(structDef.getAttributeDefs().size()); - - for (AtlasAttributeDef attributeDef : structDef.getAttributeDefs()) { - // Validate the mandatory features of an attribute (compatibility with legacy type system) - if (StringUtils.isEmpty(attributeDef.getName())) { - throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, structDef.getName(), "name"); - } - if (StringUtils.isEmpty(attributeDef.getTypeName())) { - throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, structDef.getName(), "typeName"); - } - - String propertyKey = AtlasGraphUtilsV1.getTypeDefPropertyKey(structDef, attributeDef.getName()); - - AtlasGraphUtilsV1.setProperty(vertex, propertyKey, toJsonFromAttribute(structType.getAttribute(attributeDef.getName()))); - - attrNames.add(attributeDef.getName()); - } - AtlasGraphUtilsV1.setProperty(vertex, AtlasGraphUtilsV1.getTypeDefPropertyKey(structDef), attrNames); - } - - public static void updateVertexPreUpdate(AtlasStructDef structDef, AtlasStructType structType, - AtlasVertex vertex, AtlasTypeDefGraphStoreV1 typeDefStore) - throws AtlasBaseException { - - List<String> attrNames = new ArrayList<>(); - if (CollectionUtils.isNotEmpty(structDef.getAttributeDefs())) { - for (AtlasAttributeDef attributeDef : structDef.getAttributeDefs()) { - attrNames.add(attributeDef.getName()); - } - } - - List<String> currAttrNames = vertex.getProperty(AtlasGraphUtilsV1.getTypeDefPropertyKey(structDef), List.class); - - // delete attributes that are not present in updated structDef - if (CollectionUtils.isNotEmpty(currAttrNames)) { - for (String currAttrName : currAttrNames) { - if (!attrNames.contains(currAttrName)) { - throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_DELETION_NOT_SUPPORTED, - structDef.getName(), currAttrName); - } - } - } - - typeDefStore.updateTypeVertex(structDef, vertex); - - // Load up current struct definition for matching attributes - AtlasStructDef currentStructDef = toStructDef(vertex, new AtlasStructDef(), typeDefStore); - - // add/update attributes that are present in updated structDef - if (CollectionUtils.isNotEmpty(structDef.getAttributeDefs())) { - for (AtlasAttributeDef attributeDef : structDef.getAttributeDefs()) { - if (CollectionUtils.isEmpty(currAttrNames) || !currAttrNames.contains(attributeDef.getName())) { - // new attribute - only allow if optional - if (!attributeDef.getIsOptional()) { - throw new AtlasBaseException(AtlasErrorCode.CANNOT_ADD_MANDATORY_ATTRIBUTE, structDef.getName(), attributeDef.getName()); - } - } - - // Validate the mandatory features of an attribute (compatibility with legacy type system) - if (StringUtils.isEmpty(attributeDef.getName())) { - throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, structDef.getName(), "name"); - } - if (StringUtils.isEmpty(attributeDef.getTypeName())) { - throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, structDef.getName(), "typeName"); - } - - AtlasAttributeDef existingAttribute = currentStructDef.getAttribute(attributeDef.getName()); - if (null != existingAttribute && !attributeDef.getTypeName().equals(existingAttribute.getTypeName())) { - throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Data type update for attribute is not supported"); - } - - String propertyKey = AtlasGraphUtilsV1.getTypeDefPropertyKey(structDef, attributeDef.getName()); - - AtlasGraphUtilsV1.setProperty(vertex, propertyKey, toJsonFromAttribute(structType.getAttribute(attributeDef.getName()))); - } - } - - AtlasGraphUtilsV1.setProperty(vertex, AtlasGraphUtilsV1.getTypeDefPropertyKey(structDef), attrNames); - } - - public static void updateVertexAddReferences(AtlasStructDef structDef, AtlasVertex vertex, - AtlasTypeDefGraphStoreV1 typeDefStore) throws AtlasBaseException { - for (AtlasAttributeDef attributeDef : structDef.getAttributeDefs()) { - addReferencesForAttribute(vertex, attributeDef, typeDefStore); - } - } - - public static AtlasStructDef toStructDef(AtlasVertex vertex, AtlasStructDef structDef, - AtlasTypeDefGraphStoreV1 typeDefStore) throws AtlasBaseException { - AtlasStructDef ret = (structDef != null) ? structDef :new AtlasStructDef(); - - typeDefStore.vertexToTypeDef(vertex, ret); - - List<AtlasAttributeDef> attributeDefs = new ArrayList<>(); - List<String> attrNames = vertex.getProperty(AtlasGraphUtilsV1.getTypeDefPropertyKey(ret), List.class); - - if (CollectionUtils.isNotEmpty(attrNames)) { - for (String attrName : attrNames) { - String propertyKey = AtlasGraphUtilsV1.getTypeDefPropertyKey(ret, attrName); - String attribJson = vertex.getProperty(GraphHelper.encodePropertyKey(propertyKey), String.class); - - attributeDefs.add(toAttributeDefFromJson(structDef, AtlasType.fromJson(attribJson, Map.class), - typeDefStore)); - } - } - ret.setAttributeDefs(attributeDefs); - - return ret; - } - - private static void addReferencesForAttribute(AtlasVertex vertex, AtlasAttributeDef attributeDef, - AtlasTypeDefGraphStoreV1 typeDefStore) throws AtlasBaseException { - Set<String> referencedTypeNames = AtlasTypeUtil.getReferencedTypeNames(attributeDef.getTypeName()); - - String typeName = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY, String.class); - - for (String referencedTypeName : referencedTypeNames) { - if (!AtlasTypeUtil.isBuiltInType(referencedTypeName)) { - AtlasVertex referencedTypeVertex = typeDefStore.findTypeVertexByName(referencedTypeName); - - if (referencedTypeVertex == null) { - throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_TYPE, referencedTypeName, typeName, attributeDef.getName()); - } - - String label = AtlasGraphUtilsV1.getEdgeLabel(typeName, attributeDef.getName()); - - typeDefStore.getOrCreateEdge(vertex, referencedTypeVertex, label); - } - } - } - - @VisibleForTesting - public static String toJsonFromAttribute(AtlasAttribute attribute) { - AtlasAttributeDef attributeDef = attribute.getAttributeDef(); - Map<String, Object> attribInfo = new HashMap<>(); - - attribInfo.put("name", attributeDef.getName()); - attribInfo.put("dataType", attributeDef.getTypeName()); - attribInfo.put("isUnique", attributeDef.getIsUnique()); - attribInfo.put("isIndexable", attributeDef.getIsIndexable()); - attribInfo.put("includeInNotification", attributeDef.getIncludeInNotification()); - attribInfo.put("isComposite", attribute.isOwnedRef()); - attribInfo.put("reverseAttributeName", attribute.getInverseRefAttributeName()); - attribInfo.put("defaultValue", attributeDef.getDefaultValue()); - attribInfo.put("description", attributeDef.getDescription()); - - final int lower; - final int upper; - - if (attributeDef.getCardinality() == AtlasAttributeDef.Cardinality.SINGLE) { - lower = attributeDef.getIsOptional() ? 0 : 1; - upper = 1; - } else { - if(attributeDef.getIsOptional()) { - lower = 0; - } else { - lower = attributeDef.getValuesMinCount() < 1 ? 1 : attributeDef.getValuesMinCount(); - } - - upper = attributeDef.getValuesMaxCount() < 2 ? Integer.MAX_VALUE : attributeDef.getValuesMaxCount(); - } - - Map<String, Object> multiplicity = new HashMap<>(); - multiplicity.put("lower", lower); - multiplicity.put("upper", upper); - multiplicity.put("isUnique", AtlasAttributeDef.Cardinality.SET.equals(attributeDef.getCardinality())); - - attribInfo.put("multiplicity", AtlasType.toJson(multiplicity)); - - return AtlasType.toJson(attribInfo); - } - - @VisibleForTesting - public static AtlasAttributeDef toAttributeDefFromJson(AtlasStructDef structDef, - Map attribInfo, - AtlasTypeDefGraphStoreV1 typeDefStore) - throws AtlasBaseException { - AtlasAttributeDef ret = new AtlasAttributeDef(); - - ret.setName((String) attribInfo.get("name")); - ret.setTypeName((String) attribInfo.get("dataType")); - ret.setIsUnique((Boolean) attribInfo.get("isUnique")); - ret.setIsIndexable((Boolean) attribInfo.get("isIndexable")); - ret.setIncludeInNotification((Boolean) attribInfo.get("includeInNotification")); - ret.setDefaultValue((String) attribInfo.get("defaultValue")); - ret.setDescription((String) attribInfo.get("description")); - - if ((Boolean)attribInfo.get("isComposite")) { - ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF)); - } - - final String reverseAttributeName = (String) attribInfo.get("reverseAttributeName"); - if (StringUtils.isNotBlank(reverseAttributeName)) { - ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF, - new HashMap<String, Object>() {{ - put(AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE, reverseAttributeName); - }})); - } - - Map multiplicity = AtlasType.fromJson((String) attribInfo.get("multiplicity"), Map.class); - Number minCount = (Number) multiplicity.get("lower"); - Number maxCount = (Number) multiplicity.get("upper"); - Boolean isUnique = (Boolean) multiplicity.get("isUnique"); - - if (minCount == null || minCount.intValue() == 0) { - ret.setIsOptional(true); - ret.setValuesMinCount(0); - } else { - ret.setIsOptional(false); - ret.setValuesMinCount(minCount.intValue()); - } - - if (maxCount == null || maxCount.intValue() < 2) { - ret.setCardinality(AtlasAttributeDef.Cardinality.SINGLE); - ret.setValuesMaxCount(1); - } else { - if (isUnique == null || isUnique == Boolean.FALSE) { - ret.setCardinality(AtlasAttributeDef.Cardinality.LIST); - } else { - ret.setCardinality(AtlasAttributeDef.Cardinality.SET); - } - - ret.setValuesMaxCount(maxCount.intValue()); - } - - return ret; - } - - public static Multiplicity getMultiplicity(AtlasAttributeDef attributeDef) { - final int lower; - final int upper; - final boolean isUnique = AtlasAttributeDef.Cardinality.SET.equals(attributeDef.getCardinality()); - - if (attributeDef.getCardinality() == AtlasAttributeDef.Cardinality.SINGLE) { - lower = attributeDef.getIsOptional() ? 0 : 1; - upper = 1; - } else { - if(attributeDef.getIsOptional()) { - lower = 0; - } else { - lower = attributeDef.getValuesMinCount() < 1 ? 1 : attributeDef.getValuesMinCount(); - } - - upper = attributeDef.getValuesMaxCount() < 2 ? Integer.MAX_VALUE : attributeDef.getValuesMaxCount(); - } - - Multiplicity ret = new Multiplicity(lower, upper, isUnique); - - return ret; - } - - public static AttributeDefinition toAttributeDefinition(AtlasAttribute attribute) { - final AtlasAttributeDef attrDef = attribute.getAttributeDef(); - - AttributeDefinition ret = new AttributeDefinition(); - - ret.setName(attrDef.getName()); - ret.setDataTypeName(attrDef.getTypeName()); - ret.setMultiplicity(getMultiplicity(attrDef)); - ret.setIsComposite(attribute.isOwnedRef()); - ret.setIsUnique(attrDef.getIsUnique()); - ret.setIsIndexable(attrDef.getIsIndexable()); - ret.setReverseAttributeName(attribute.getInverseRefAttributeName()); - ret.setDescription(attrDef.getDescription()); - ret.setDefaultValue(attrDef.getDefaultValue()); - - return ret; - } -}