2016-05-20 14 views
6

Utilizzando Cassandra, voglio creare lo spazio delle chiavi e le tabelle in modo dinamico utilizzando l'applicazione Spring Boot. Sto usando la configurazione basata su Java.Crea spazio chiavi, tabella e genera tabelle dinamicamente utilizzando Spring Data Cassandra

Ho un'entità annotata con @Table di cui voglio creare lo schema prima che l'applicazione si avvii poiché ha risolto i campi che sono noti in anticipo.

Tuttavia, a seconda dell'utente connesso, desidero anche creare tabelle aggiuntive per tali utenti dinamicamente e poter inserire voci in queste tabelle.

Può qualcuno guidarmi ad alcune risorse che posso utilizzare o indirizzarmi nella giusta direzione su come risolvere questi problemi. Grazie mille per l'aiuto!

risposta

9

La cosa più semplice da fare sarebbe quella di aggiungere il Spring Boot Starter Data Cassandra dipendenza alla vostra primavera Boot applicazione, in questo modo ...

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

Inoltre, questo aggiungerà la Cassandra primavera datidependency a la tua applicazione.

Con primavera dati Cassandra, è possibile configurare spazio delle chiavi della vostra applicazione (s) utilizzando il CassandraClusterFactoryBean (o, più precisamente, la sottoclasse ... CassandraCqlClusterFactoryBean) chiamando il metodo setKeyspaceCreations(:Set).

La classe KeyspaceActionSpecification è abbastanza auto-esplicativa. Puoi persino crearne uno con lo KeyspaceActionSpecificationFactoryBean, aggiungerlo a un Set e quindi passarlo al metodo setKeyspaceCreations(..) su CassandraClusterFactoryBean.

Per generare tabelle dell'applicazione, è essenzialmente solo bisogno di annotare l'oggetto dominio di applicazione (s) (entità) utilizzando la SD Cassandra @Table annotazioni, e assicurarsi che gli oggetti del dominio/entità possono essere trovati sul CLASSPATH dell'applicazione.

In particolare, è possibile avere la classe di applicazione @Configuration estendere la classe SD Cassandra AbstractClusterConfiguration. Qui troverai il metodo getEntityBasePackages():String[] che puoi sovrascrivere per fornire le posizioni dei pacchetti contenenti le classi oggetto/entità dominio del dominio dell'applicazione, che SD Cassandra utilizzerà quindi su scan per oggetto/entità di dominio @Table.

con l'applicazione @Table oggetto di dominio/entità correttamente identificati, è possibile impostare la SD Cassandra SchemaAction-CREATE utilizzando il metodo CassandraSessionFactoryBean, setSchemaAction(:SchemaAction). Questo creerà Tabelle nel tuo Keyspace per tutti gli oggetti/entità di dominio trovati durante la scansione, fornendo identified l'appropriato spazio Keys sul tuo CassandraSessionFactoryBean in modo appropriato.

Ovviamente, se l'applicazione crea/utilizza più Keyspaces, sarà necessario creare un separato CassandraSessionFactoryBean per ogni spazio delle chiavi, con la proprietà di configurazione entityBasePackages impostare in modo appropriato per le entità che appartengono a un particolare spazio delle chiavi, in modo che le tabelle associate sono creato in quel Keyspace.

Ora ...

per i tavoli "aggiuntivi" per utente, che è un po 'più complicato e difficile.

Qui potrebbe essere possibile utilizzare i profili Spring, tuttavia i profili vengono generalmente applicati solo all'avvio. Se un utente diverso accede a un'applicazione già in esecuzione, è necessario un modo per fornire classi @Configuration aggiuntive a Spring ApplicationContext in fase di esecuzione.

tuo Primavera Boot applicazione potrebbe iniettare un riferimento a un AnnotationConfigApplicationContext, e poi usarlo su un evento di accesso a livello di programmazione register ulteriori @Configuration classi in base all'utente che ha effettuato l'accesso all'applicazione. Devi seguire le tue chiamate register(Class...) con uno ApplicationContext.refresh().

È inoltre necessario gestire in modo appropriato la situazione in cui le tabelle esistono già.

Questo non è attualmente supportato in SD Cassandra, ma vedere DATACASS-219 per ulteriori dettagli.

Tecnicamente, sarebbe molto più semplice creare tutte le possibili tabelle richieste dall'applicazione per tutti gli utenti in fase di esecuzione e utilizzare le impostazioni di sicurezza di Cassandra per limitare l'accesso dei singoli utenti in base al ruolo e alle autorizzazioni assegnate.

Un'altra opzione potrebbe essere solo quella di creare spazi temporanei e/o tabelle temporanei quando necessario quando un utente accede all'applicazione, rilasciarli quando l'utente si disconnette.

Chiaramente, ci sono molte scelte diverse qui, e si riduce più alle decisioni architettoniche, ai compromessi e alle considerazioni, quindi alla fattibilità tecnica, quindi state attenti.

Spero che questo aiuti.

Cheers!

10

La seguente classe di configurazione di primavera crea lo spazio delle chiavi e le tabelle se non esistono.

@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

Ho seguito questo codice, ma ancora non riesco a creare Keyspace e tabelle all'avvio dell'applicazione. C'è qualcos'altro che mi manca? Per favore guidami. – Milesh

0

Il seguente configurazione cassandra creerà uno spazio delle chiavi quando non esiste e anche eseguire lo script di avvio specificato

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

} 
Problemi correlati