2016-05-20 10 views
6

Korzystając z Cassandry, chcę dynamicznie tworzyć przestrzeń kluczy i tabele przy użyciu aplikacji Spring Boot. Używam konfiguracji opartej na języku Java.Twórz przestrzeń kluczy, tabelę i generuj tabele dynamicznie za pomocą Spring Data Cassandra

Mam obiekt oznaczony przy pomocy @Table, którego schemat chcę utworzyć przed uruchomieniem aplikacji, ponieważ ma on ustalone wcześniej pola, które są znane.

Jednak w zależności od zalogowanego użytkownika chcę również dynamicznie tworzyć dodatkowe tabele dla tych użytkowników i móc wstawiać wpisy do tych tabel.

Czy ktoś może mnie poprowadzić do pewnych zasobów, z których mogę skorzystać lub wskazać mi właściwy kierunek, w jaki sposób rozwiązać te problemy. Wielkie dzięki za pomoc!

Odpowiedz

9

Najprostszym rozwiązaniem byłoby dodać zależność Spring Boot Starter Data Cassandra do Wiosna Boot aplikacji, tak jak ...

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-data-cassandra</artifactId> 
    <version>1.3.5.RELEASE</version> 
</dependency> 

Oprócz tego doda Cassandrę Wiosna danychdependency do Twoje zgłoszenie.

Z wiosennym danych Cassandra można skonfigurować KEYSPACE (a) aplikacji używając CassandraClusterFactoryBean (lub bardziej precyzyjnie, podklasa ... CassandraCqlClusterFactoryBean) przez wywołanie metody setKeyspaceCreations(:Set).

Klasa KeyspaceActionSpecification jest dość zrozumiała. Można nawet utworzyć go przy pomocy KeyspaceActionSpecificationFactoryBean, dodać go do Set, a następnie przekazać do metody setKeyspaceCreations(..) na urządzeniu CassandraClusterFactoryBean.

Aby wygenerować tabele aplikacji, wystarczy po prostu zanotować obiekt (y) domeny aplikacji (encje) za pomocą adnotacji SD Cassandra @Table i upewnić się, że obiekty/obiekty domeny można znaleźć na ścieżce CLASSPATH aplikacji.

W szczególności, można rozszerzyć klasę Cassandra o @Configuration klasy SD Cassandra AbstractClusterConfiguration. Znajdziesz tam metodę getEntityBasePackages():String[], którą możesz przesłonić, aby udostępnić lokalizacje pakietów zawierające klasy obiektu/podmiotu domeny aplikacji, które SD Cassandra będzie następnie używać do scan dla obiektu/podmiotów domeny domeny @Table.

z aplikacją @Table obiektu domeny/podmioty prawidłowo zidentyfikowane, można ustawić SD Cassandra SchemaAction do CREATE stosując metodę CassandraSessionFactoryBean, setSchemaAction(:SchemaAction). Spowoduje to utworzenie tabel w obszarze Keyspace dla wszystkich obiektów/obiektów domeny znalezionych podczas skanowania, pod warunkiem, że odpowiednio ustawisz odpowiednią przestrzeń kluczy na swoim komputerze .

Oczywiście, jeśli twoja aplikacja tworzy/używa wielu Obszarów Kluczowych, będziesz musiał utworzyć oddzielną CassandraSessionFactoryBean dla każdego Pola, z właściwością konfiguracyjną entityBasePackages ustawioną odpowiednio dla encji należących do określonego Obszaru Klucza, tak, aby powiązane Tabele były utworzone w tym Keyspace.

teraz ...

Przez „dodatkowe” Stoły na użytkownika, który jest trochę bardziej skomplikowane i trudne.

Możesz być w stanie wykorzystać profile wiosny tutaj, jednak profile są zazwyczaj stosowane tylko podczas uruchamiania. Jeśli inny użytkownik loguje się do już działającej aplikacji, potrzebny jest sposób dostarczenia dodatkowych klas @Configuration do wersji Spring ApplicationContext w środowisku wykonawczym.

Twój Wiosna Boot aplikacja mogła wprowadzić odniesienie do AnnotationConfigApplicationContext, a następnie użyć go w przypadku logowania programowo register dodatkowych @Configuration zajęcia oparte na użytkownika, który zalogował się do aplikacji. Musisz wykonać połączenie register(Class...) z ApplicationContext.refresh().

Musisz również odpowiednio zająć się sytuacją, w której tabele już istnieją.

To nie jest obecnie obsługiwane w SD Cassandra, ale dalsze szczegóły można znaleźć pod numerem DATACASS-219.

Z technicznego punktu widzenia znacznie prostsze byłoby stworzenie wszystkich możliwych tabel wymaganych przez aplikację dla wszystkich użytkowników w czasie wykonywania i stosowanie ustawień zabezpieczeń Cassandra w celu ograniczenia dostępu do poszczególnych użytkowników według roli i przypisanych uprawnień.

Inną opcją może być po prostu utworzenie tymczasowych Obszarów kluczowych i/lub tabel w razie potrzeby, gdy użytkownik zaloguje się do aplikacji, upuść je, gdy użytkownik się wyloguje.

Oczywiście, istnieje wiele różnych opcji, a to sprowadza się bardziej do decyzji architektonicznych, kompromisów i względów, to robi techniczną wykonalność, więc należy zachować ostrożność.

Mam nadzieję, że to pomoże.

Pozdrawiam!

10

Następująca klasa konfiguracji wiosennej tworzy przestrzeń kluczy i tabele, jeśli nie istnieją.

@Configuration 
public class CassandraConfig extends AbstractCassandraConfiguration { 
    private static final String KEYSPACE = "my_keyspace"; 
    private static final String USERNAME = "cassandra"; 
    private static final String PASSWORD = "cassandra"; 
    private static final String NODES = "127.0.0.1"; // comma seperated nodes 


    @Bean 
    @Override 
    public CassandraCqlClusterFactoryBean cluster() { 
     CassandraCqlClusterFactoryBean bean = new CassandraCqlClusterFactoryBean(); 
     bean.setKeyspaceCreations(getKeyspaceCreations()); 
     bean.setContactPoints(NODES); 
     bean.setUsername(USERNAME); 
     bean.setPassword(PASSWORD); 
     return bean; 
    } 

    @Override 
    public SchemaAction getSchemaAction() { 
     return SchemaAction.CREATE_IF_NOT_EXISTS; 
    } 

    @Override 
    protected String getKeyspaceName() { 
     return KEYSPACE; 
    } 

    @Override 
    public String[] getEntityBasePackages() { 
     return new String[]{"com.panda"}; 
    } 


    protected List<CreateKeyspaceSpecification> getKeyspaceCreations() { 
     List<CreateKeyspaceSpecification> createKeyspaceSpecifications = new ArrayList<>(); 
     createKeyspaceSpecifications.add(getKeySpaceSpecification()); 
     return createKeyspaceSpecifications; 
    } 

    // Below method creates "my_keyspace" if it doesnt exist. 
    private CreateKeyspaceSpecification getKeySpaceSpecification() { 
     CreateKeyspaceSpecification pandaCoopKeyspace = new CreateKeyspaceSpecification(); 
     DataCenterReplication dcr = new DataCenterReplication("dc1", 3L); 
     pandaCoopKeyspace.name(KEYSPACE); 
     pandaCoopKeyspace.ifNotExists(true).createKeyspace().withNetworkReplication(dcr); 
     return pandaCoopKeyspace; 
    } 

} 
+0

Śledzę ten kod, ale nadal nie jestem w stanie utwórz Keyspace i tabele w bootowaniu aplikacji. Czy jest jeszcze coś, czego mi brakuje? Proszę, prowadź mnie. – Milesh

0

Poniższy konfiguracja Cassandra stworzy KEYSPACE gdy nie istnieje, a także uruchomić skrypt startowy określony

@Configuration 
@PropertySource(value = {"classpath:cassandra.properties"}) 
@EnableCassandraRepositories 
public class CassandraConfig extends AbstractCassandraConfiguration { 

    @Value("${cassandra.keyspace}") 
    private String cassandraKeyspace; 

    @Override 
    protected List<CreateKeyspaceSpecification> getKeyspaceCreations() { 
    return Collections.singletonList(CreateKeyspaceSpecification.createKeyspace(cassandraKeyspace) 
       .ifNotExists() 
       .with(KeyspaceOption.DURABLE_WRITES, true) 
       .withSimpleReplication()); 
    } 

    @Override 
    protected List<String> getStartupScripts() { 
    return Collections.singletonList("CREATE TABLE IF NOT EXISTS "+cassandraKeyspace+".test(id UUID PRIMARY KEY, greeting text, occurrence timestamp) WITH default_time_to_live = 600;"); 
    } 

} 
Powiązane problemy