Esempio n. 1
0
  public Vertex createVertexWithIdentity(
      ITypedReferenceableInstance typedInstance, Set<String> superTypeNames) {
    final Vertex vertexWithIdentity =
        createVertexWithoutIdentity(
            typedInstance.getTypeName(), typedInstance.getId(), superTypeNames);

    // add identity
    final String guid = UUID.randomUUID().toString();
    setProperty(vertexWithIdentity, Constants.GUID_PROPERTY_KEY, guid);

    // add version information
    setProperty(vertexWithIdentity, Constants.VERSION_PROPERTY_KEY, typedInstance.getId().version);

    return vertexWithIdentity;
  }
  /**
   * Adds a new trait to an existing entity represented by a guid.
   *
   * @param guid globally unique identifier for the entity
   * @param traitInstance trait instance that needs to be added to entity
   * @throws RepositoryException
   */
  @Override
  @GraphTransaction
  public void addTrait(String guid, ITypedStruct traitInstance) throws RepositoryException {
    Preconditions.checkNotNull(traitInstance, "Trait instance cannot be null");
    final String traitName = traitInstance.getTypeName();
    LOG.debug("Adding a new trait={} for entity={}", traitName, guid);

    try {
      Vertex instanceVertex = graphHelper.getVertexForGUID(guid);

      // add the trait instance as a new vertex
      final String typeName = GraphHelper.getTypeName(instanceVertex);

      TypedInstanceToGraphMapper instanceToGraphMapper =
          new TypedInstanceToGraphMapper(graphToInstanceMapper, deleteHandler);
      instanceToGraphMapper.mapTraitInstanceToVertex(
          traitInstance, typeSystem.getDataType(ClassType.class, typeName), instanceVertex);

      // update the traits in entity once adding trait instance is successful
      GraphHelper.addProperty(instanceVertex, Constants.TRAIT_NAMES_PROPERTY_KEY, traitName);
      GraphHelper.setProperty(
          instanceVertex,
          Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
          RequestContext.get().getRequestTime());

    } catch (RepositoryException e) {
      throw e;
    } catch (Exception e) {
      throw new RepositoryException(e);
    }
  }
Esempio n. 3
0
  public Vertex createVertexWithoutIdentity(
      String typeName, Id typedInstanceId, Set<String> superTypeNames) {
    LOG.debug(
        "Creating vertex for type {} id {}",
        typeName,
        typedInstanceId != null ? typedInstanceId._getId() : null);
    final Vertex vertexWithoutIdentity = titanGraph.addVertex(null);

    // add type information
    setProperty(vertexWithoutIdentity, Constants.ENTITY_TYPE_PROPERTY_KEY, typeName);

    // add super types
    for (String superTypeName : superTypeNames) {
      addProperty(vertexWithoutIdentity, Constants.SUPER_TYPES_PROPERTY_KEY, superTypeName);
    }

    // add timestamp information
    setProperty(
        vertexWithoutIdentity, Constants.TIMESTAMP_PROPERTY_KEY, System.currentTimeMillis());

    return vertexWithoutIdentity;
  }
  private void updateTraits(Vertex instanceVertex, List<String> traitNames) {
    // remove the key
    instanceVertex.removeProperty(Constants.TRAIT_NAMES_PROPERTY_KEY);

    // add it back again
    for (String traitName : traitNames) {
      GraphHelper.addProperty(instanceVertex, Constants.TRAIT_NAMES_PROPERTY_KEY, traitName);
    }
    GraphHelper.setProperty(
        instanceVertex,
        Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
        RequestContext.get().getRequestTime());
  }
  /**
   * 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(Vertex outVertex, Vertex inVertex, String attributeName)
      throws AtlasException {
    LOG.debug(
        "Removing edge from {} to {} with attribute name {}",
        string(outVertex),
        string(inVertex),
        attributeName);
    String typeName = GraphHelper.getTypeName(outVertex);
    String outId = GraphHelper.getIdFromVertex(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;
    Edge 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 "
                  + string(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 = outVertex.getProperty(propertyName);
        if (elements != null) {
          elements =
              new ArrayList<>(
                  elements); // Make a copy, else list.remove reflects on titan.getProperty()
          for (String elementEdgeId : elements) {
            Edge elementEdge = graphHelper.getEdgeByEdgeId(outVertex, edgeLabel, elementEdgeId);
            if (elementEdge == null) {
              continue;
            }

            Vertex elementVertex = elementEdge.getVertex(Direction.IN);
            if (elementVertex.getId().toString().equals(inVertex.getId().toString())) {
              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 "
                        + string(outVertex)
                        + " "
                        + string(elementEdge));
              }

              if (shouldUpdateReverseAttribute) {
                // if composite attribute, remove the reference as well. else, just remove the edge
                // for example, when table is deleted, process still references the table
                // but when column is deleted, table will not reference the deleted column
                LOG.debug(
                    "Removing edge {} from the array attribute {}",
                    string(elementEdge),
                    attributeName);
                elements.remove(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 = outVertex.getProperty(propertyName);
        if (keys != null) {
          keys =
              new ArrayList<>(
                  keys); // Make a copy, else list.remove reflects on titan.getProperty()
          for (String key : keys) {
            String keyPropertyName = GraphHelper.getQualifiedNameForMapKey(propertyName, key);
            String mapEdgeId = outVertex.getProperty(keyPropertyName);
            Edge mapEdge = graphHelper.getEdgeByEdgeId(outVertex, keyPropertyName, mapEdgeId);
            Vertex mapVertex = mapEdge.getVertex(Direction.IN);
            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 "
                        + string(outVertex)
                        + " "
                        + string(mapEdge));
              }

              if (shouldUpdateReverseAttribute) {
                // remove this key
                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 "
                + string(outVertex)
                + " to "
                + string(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());
      requestContext.recordEntityUpdate(outId);
    }
  }