io.flowly.engine.data.manager.FlowlyGraph.java Source code

Java tutorial

Introduction

Here is the source code for io.flowly.engine.data.manager.FlowlyGraph.java

Source

/*
 * Copyright (c) 2015 The original author or authors.
 *
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Apache License v2.0
 *  which accompanies this distribution.
 *
 *  The Apache License v2.0 is available at
 *  http://opensource.org/licenses/Apache-2.0
 *
 *  You may elect to redistribute this code under this license.
 */

package io.flowly.engine.data.manager;

import com.thinkaurelius.titan.core.EdgeLabel;
import com.thinkaurelius.titan.core.Multiplicity;
import com.thinkaurelius.titan.core.PropertyKey;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.schema.TitanManagement;
import io.flowly.engine.JsonKeys;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;

import java.util.Date;

/**
 * Create a Titan graph by configuring the storage and indexing options.
 * Prepares the graph schema when the graph is created for the first time.
 *
 * @author <a>Uday Tatiraju</a>
 */
public class FlowlyGraph {
    private static final Logger logger = LoggerFactory.getLogger(FlowlyGraph.class);

    private TitanGraph graph;

    // TODO: Use Cassandra.
    public FlowlyGraph(JsonObject config) {
        TitanFactory.Builder titanConfig = TitanFactory.build();
        titanConfig.set(JsonKeys.DB_STORAGE_BACKEND, "berkeleyje");
        titanConfig.set(JsonKeys.DB_STORAGE_DIRECTORY, config.getString(JsonKeys.DB_STORAGE_DIRECTORY));

        graph = titanConfig.open();
        configureSchema(graph);
    }

    public Graph getInstance() {
        return graph;
    }

    // TODO: Create an upgradable schema by defining onCreate and onUpdate methods.
    // TODO: Read JSON files to create schema.
    private void configureSchema(TitanGraph graph) {
        TitanManagement management = graph.openManagement();
        boolean schemaCreated = false;

        if (management.containsVertexLabel(Schema.V_PROCESS_INSTANCE)) {
            logger.info("Flowly graph schema created in a previous run.");
        } else {
            logger.info("Creating flowly graph schema...");

            // Subject (user, group, team) vertex.
            management.makeVertexLabel(Schema.V_SUBJECT).make();
            PropertyKey subjectId = management.makePropertyKey(Schema.V_P_SUBJECT_ID).dataType(String.class).make();
            // Graph-level composite index (only supports equality operator).
            management.buildIndex("subjectIdx", Vertex.class).addKey(subjectId).unique().buildCompositeIndex();

            // IsAssigned edge.
            EdgeLabel isAssigned = management.makeEdgeLabel(Schema.E_IS_ASSIGNED)
                    .multiplicity(Multiplicity.ONE2MANY).make();
            PropertyKey receivedStatus = management.makePropertyKey(Schema.E_P_RECEIVED_STATUS)
                    .dataType(String.class).make();
            PropertyKey assignedOn = management.makePropertyKey(Schema.E_P_ASSIGNED_ON).dataType(Date.class).make();
            management.makePropertyKey(Schema.E_P_DUE_DATE).dataType(Date.class).make();
            management.makePropertyKey(Schema.E_P_AT_RISK_DATE).dataType(Date.class).make();
            // Build vertex-centric index on the edge.
            management.buildEdgeIndex(isAssigned, "isAssignedIdx", Direction.OUT, Order.decr, assignedOn,
                    receivedStatus);

            // Process instance vertex.
            management.makeVertexLabel(Schema.V_PROCESS_INSTANCE).make();
            management.makePropertyKey(Schema.V_P_PROCESS_FLOW_ID).dataType(String.class).make();

            // Flow object instance vertex.
            management.makeVertexLabel(Schema.V_FLOW_OBJECT_INSTANCE).make();
            management.makePropertyKey(Schema.V_P_INSTANCE_ID).dataType(Long.class).make();
            management.makePropertyKey(Schema.V_P_FLOW_OBJECT_ID).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_META_DATA).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_DATA).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_INPUT_DATA).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_OUTPUT_DATA).dataType(String.class).make();

            // Flow object instance edges.
            management.makeEdgeLabel(Schema.E_FLOW_TO).multiplicity(Multiplicity.ONE2MANY).make();
            management.makeEdgeLabel(Schema.E_FLOW_INTO).multiplicity(Multiplicity.ONE2ONE).make();
            management.makeEdgeLabel(Schema.E_FLOW_OUT).multiplicity(Multiplicity.ONE2ONE).make();

            // Flow vertex
            management.makeVertexLabel(Schema.V_FLOW_METADATA).make();
            management.makePropertyKey(Schema.V_P_FLOW_TYPE).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_APP_ID).dataType(String.class).make();
            // Build graph-level composite index.
            PropertyKey flowId = management.makePropertyKey(Schema.V_P_FLOW_ID).dataType(String.class).make();
            management.buildIndex("flowIdx", Vertex.class).addKey(flowId).unique().buildCompositeIndex();

            // Flow route vertex.
            management.makeVertexLabel(Schema.V_FLOW_ROUTE).make();
            // TODO: Add index on current flow object id?
            management.makePropertyKey(Schema.V_P_CURRENT_FLOW_OBJECT_ID).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_CONNECTING_OBJECT_ID).dataType(String.class).make();
            management.makePropertyKey(Schema.V_P_NEXT_FLOW_OBJECT_ID).dataType(String.class).make();
            // Build graph-level composite index.
            PropertyKey routeFlowId = management.makePropertyKey(Schema.V_P_ROUTE_FLOW_ID).dataType(String.class)
                    .make();
            management.buildIndex("routeFlowIdx", Vertex.class).addKey(routeFlowId).buildCompositeIndex();

            // General vertex properties.
            management.makePropertyKey(Schema.P_STATUS).dataType(String.class).make();
            management.makePropertyKey(Schema.P_SUBJECT).dataType(String.class).make();
            management.makePropertyKey(Schema.P_SUB_FLOW_ID).dataType(String.class).make();

            schemaCreated = true;
            logger.info("Flowly graph schema created.");
        }

        management.commit();

        // Create admin user vertex.
        if (schemaCreated) {
            Vertex adminVertex = graph.addVertex(Schema.V_SUBJECT);
            adminVertex.property(Schema.V_P_SUBJECT_ID, JsonKeys.ADMIN_USER_ID);
            graph.tx().commit();

            logger.info("Admin vertex created.");
        }
    }
}