sovanegger
sovanegger

Reputation: 121

Orientdb partitioned graph java implementation

I've got a backend Spring application and Orientdb graph database. I use Tinkerpop Frames to map orientdb vertices to java objects and OPS4J for spring transaction management. Now I want to implement there a multitenancy where several customers (tenants) uses this one application instance. This application completely works on REST principles and it is opened to several Angular applications - each per customer. So there's as many frontend Angular applications as our customers and only one backend REST Spring application. Backend recognize the tenant from a HTTP request.

Now I'm not sure about the best solution...

First solution

When I read the Orientdb documentation, I found there a way how to implement multitenancy in orientdb - http://orientdb.com/docs/2.1/Partitioned-Graphs.html. However I don't know how to use it through the Java API unless I don't want to create a new database connection for each request. Because right now the spring transaction manager takes connections from connection pool which is centrally set in Spring transaction management configuration. I didn't find any Java example to this.

Spring transaction management config:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean
    @Qualifier("graphDbTx")
    public OrientTransactionManager graphDbTransactionManager() {
        OrientTransactionManager bean = new OrientTransactionManager();
        bean.setDatabaseManager(graphDatabaseFactory());
        return bean;
    }

    @Bean
    public OrientBlueprintsGraphFactory graphDatabaseFactory() {
        OrientBlueprintsGraphFactory dbf = new OrientBlueprintsGraphFactory();
        dbf.setMaxPoolSize(6);
        dbf.setUrl(DbConfig.DATABASE_URL);
        dbf.setUsername("admin");
        dbf.setPassword("admin");
        return dbf;
    }

    @Bean
    public FramedGraphFactory framedGraphFactory() {
        return new FramedGraphFactory(new JavaHandlerModule());
    }

}

Getting connection:

protected FramedGraph<OrientGraph> framedGraph() {
    return framedGraphFactory.create(gdbf.graph());
}

Second solution

Another solution is to use the Tinkerpop

PartitionGraph

class which works on Orientdb but I didn't find any sentence about this possibility in Orientdb documentation. Just this in Tinkerpop - https://github.com/tinkerpop/blueprints/wiki/Partition-Implementation. It works but in the end it just creates a not indexed property in every orientdb vertex so I'm afraid about performance of querying here.

Does anyone have any experiences with this? Any suggestion?

Upvotes: 3

Views: 462

Answers (1)

lsavio
lsavio

Reputation: 850

Using the Java API to create a partitioned DB (if I understand what you're interested in) macro steps are:

  • get connection (using the pool the istance of db are reused);
  • modify class V and E; create new user enable to write;
  • when you log in the db, user1 can write Vertices, invisible to the user2 and contrary;

    //WRITE IN YOUR CONTROLLER: CREATE USER ENABLE TO WRITE ON DB .............. Connection con = new Connection(); OrientGraph noTx = con.getConnection();

    //create partition
        noTx.begin();
        noTx.command(new OCommandSQL("ALTER CLASS V superclass orestricted")).execute();
        noTx.command(new OCommandSQL("ALTER CLASS E superclass orestricted")).execute();
        noTx.commit();
    
        //create different users
        noTx.begin();
        String ridRule = "";
        Iterable<Vertex> rule = noTx.command(new OCommandSQL("select from ORole where name = 'writer'")).execute();
        ridRule = rule.iterator().next().getId().toString();
        noTx.command(new OCommandSQL("INSERT INTO ouser SET name = 'user1', status = 'ACTIVE', password = 'user1', roles = ["+ridRule+"]")).execute();
        noTx.command(new OCommandSQL("INSERT INTO ouser SET name = 'user2', status = 'ACTIVE', password = 'user2', roles = ["+ridRule+"]")).execute();
        noTx.commit();
    
        //will not close the graph instance, but will keep open and available for the next requester
        noTx.shutdown();
    
        //finally To release all the instances and free all the resources
        con.clodeAllConnect();
    
    
        //WRITE IN YOUR CONTROLLER: LOGIN WITH USER APPROPRIATE .....................
        //CODE to login with user1 or user2,  CREATE VERTEX SET label = 'food', name = 'Pizza' etc....
    }
    
    
    //beans 
    public static class Connection {
    
        private OrientGraphFactory factory = null;
    
        public Connection() {
            //recyclable pool of instances 
            factory = new OrientGraphFactory("remote:localhost/blog").setupPool(1, 10);
        }
    
        //return the connection 
        public OrientGraph getConnection() {
            OrientGraph txGraph = factory.getTx();
            return txGraph;
        }
    
        public void clodeAllConnect(){
            factory.close();
    
        }
    }
    

To adapt these steps and insert them in Spring might be useful this link that is OrientDB - spring implementation. it isn't much but I hope will be of help.

Upvotes: 1

Related Questions