Реализация Java-секционированного графа Orientdb

У меня есть бэкэнд-приложение Spring и графическая база данных Orientdb. Я использую Tinkerpop Frames для сопоставления вершин orientdb с java-объектами и OPS4J для управления весенними транзакциями. Теперь я хочу реализовать мультитенантность, где несколько клиентов (арендаторов) используют этот экземпляр приложения. Это приложение полностью работает на принципах REST и открыто для нескольких приложений Angular - каждое для каждого клиента. Таким образом, существует столько же приложений Angular, сколько наших клиентов, и только одно приложение REST Spring. Серверная часть распознает клиента по HTTP-запросу.

Теперь я не уверен в лучшем решении...

Первое решение

Когда я прочитал документацию Orientdb, я нашел там способ реализации мультитенантности в orientdb - http://orientdb.com/docs/2.1/Partitioned-Graphs.html. Однако я не знаю, как использовать его через Java API, если я не хочу создавать новое соединение с базой данных для каждого запроса. Потому что прямо сейчас диспетчер транзакций Spring принимает соединения из пула соединений, который централизованно задан в конфигурации управления транзакциями Spring. Я не нашел никакого примера Java для этого.

Конфигурация управления транзакциями Spring:

@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());
    }

}

Получение соединения:

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

Второе решение

Другое решение состоит в том, чтобы использовать Tinkerpop

PartitionGraph

класс, который работает на Orientdb, но я не нашел ни одного предложения об этой возможности в документации Orientdb. Просто это в Tinkerpop - https://github.com/tinkerpop/blueprints/wiki/Partition-Implementation. Это работает, но, в конце концов, оно просто создает неиндексированное свойство в каждой вершине orientdb, так что я боюсь производительности запросов здесь.

У кого-нибудь есть опыт с этим? Любое предложение?

1 ответ

Использование Java API для создания многораздельной БД (если я понимаю, что вас интересует):

  • получить соединение (используя пул повторно используются значения db);
  • изменить класс V и E; создать нового пользователя, который позволит писать;
  • когда вы входите в базу данных, пользователь user1 может писать вершины, невидимые пользователю user2 и наоборот;

    // ЗАПИСАТЬ В ВАШЕМ КОНТРОЛЛЕРЕ: СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ, КОТОРОЕ МОЖНО ЗАПИСАТЬ В БД............. 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();
    
        }
    }
    

Для адаптации этих шагов и вставки их в Spring может быть полезна эта ссылка, которая является OrientDB - реализация Spring. это не так много, но я надеюсь, что поможет.

Другие вопросы по тегам