Реализация 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. это не так много, но я надеюсь, что поможет.