2016-05-20 23 views
6

Mit Cassandra, ich möchte Schlüsselbereich und Tabellen dynamisch mit Spring Boot-Anwendung erstellen. Ich verwende Java-basierte Konfiguration.Erstellen Sie Schlüsselbereich, Tabelle und Tabellen dynamisch generieren mit Spring Data Cassandra

Ich habe eine mit @Table annotierte Entität, deren Schema ich erstellt werden soll, bevor die Anwendung gestartet wird, da es feste Felder hat, die vorher bekannt sind.

Allerdings möchte ich, abhängig vom angemeldeten Benutzer, auch zusätzliche Tabellen für diese Benutzer dynamisch erstellen und in der Lage sein, Einträge in diese Tabellen einzufügen.

Kann jemand mich zu einigen Ressourcen führen, die ich nutzen kann, oder mir in die richtige Richtung zeigen, wie ich diese Probleme lösen kann? Vielen Dank für Ihre Hilfe!

Antwort

9

Die einfachste Sache der Spring Boot Starter Data Cassandra Abhängigkeit zu Ihrer Frühlings-Boot Anwendung, wie so hinzuzufügen, zu tun wäre ...

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

Darüber hinaus wird diese fügen Sie die Spring Data Cassandradependency zu Ihre Bewerbung.

Mit Spring Data Cassandra, können Sie Ihre Anwendung Schlüsselraum (n) unter Verwendung der CassandraClusterFactoryBean (oder genauer gesagt, die Unterklasse ... CassandraCqlClusterFactoryBean) konfigurieren, indem Sie die setKeyspaceCreations(:Set) Methode aufrufen.

Die KeyspaceActionSpecification Klasse ist ziemlich selbsterklärend. Sie können sogar eine mit der KeyspaceActionSpecificationFactoryBean erstellen, diese zu einer Set hinzufügen und diese dann an die setKeyspaceCreations(..) Methode über die CassandraClusterFactoryBean übergeben.

Zum Generieren der Tabellen der Anwendung müssen Sie im Wesentlichen nur Ihre Anwendungsdomänenobjekte (Entitäten) mit der SD Cassandra @Table Annotation annotieren und sicherstellen, dass Ihre Domänenobjekte/Entitäten im CLASSPATH der Anwendung gefunden werden.

Insbesondere können Sie Ihre Anwendung Klasse erweitern die SD Cassandra AbstractClusterConfiguration Klasse. Dort finden Sie die getEntityBasePackages():String[]-Methode, die Sie überschreiben können, um die Paketspeicherorte anzugeben, die Ihre Anwendungsdomänenobjekt-/Entitätsklassen enthalten, die SD Cassandra dann für scan für @Table Domain-Objekt/Entitäten verwendet.

Mit Ihrer Anwendung @Table Domain-Objekt/Entitäten ordnungsgemäß identifiziert, stellen Sie die SD Cassandra SchemaAction-CREATE mit der CassandraSessionFactoryBean Methode, setSchemaAction(:SchemaAction). Dadurch werden Tabellen in Ihrem Schlüsselbereich für alle Domänenobjekte/Entitäten erstellt, die während des Scans gefunden wurden, und Sie erhalten identified den entsprechenden Schlüsselbereich auf Ihrem CassandraSessionFactoryBean entsprechend.

Offensichtlich müssen Sie, wenn Ihre Anwendung mehrere Schlüsselbereiche erstellt/verwendet, für jeden Schlüsselbereich eine separate CassandraSessionFactoryBean erstellen, wobei die entityBasePackages Konfigurationseigenschaft für die Entitäten, die zu einem bestimmten Schlüsselbereich gehören, entsprechend für die zugehörigen Tabellen festgelegt wird erstellt in diesem Schlüsselbereich. Jetzt

...

Für die „zusätzlichen“ Tables pro Benutzer, das ist ein bisschen komplizierter und schwierig.

Möglicherweise können Sie Federprofile hier verwenden, Profile werden jedoch in der Regel nur beim Start angewendet. Wenn sich ein anderer Benutzer bei einer bereits laufenden Anwendung anmeldet, müssen Sie zur Laufzeit zusätzliche @Configuration-Klassen zur Verfügung stellen. ApplicationContext

Ihre Frühlings-Boot Anwendung könnte einen Verweis auf eine AnnotationConfigApplicationContext, injizieren und dann auf einem Anmeldeereignis verwenden, um programm register zusätzliche @Configuration Klassen basierend auf den Benutzer, der in der Anwendung protokolliert. Sie müssen Ihre register(Class...) Anrufe mit einer ApplicationContext.refresh() folgen.

Sie müssen auch die Situation, in der die Tabellen bereits existieren, entsprechend behandeln.

Dies wird derzeit nicht in SD Cassandra unterstützt, aber siehe DATACASS-219 für weitere Details.

Technisch gesehen wäre es viel einfacher, alle möglichen Tabellen zu erstellen, die die Anwendung für alle Benutzer zur Laufzeit benötigt, und die Sicherheitseinstellungen von Cassandra zu verwenden, um den Zugriff einzelner Benutzer nach Rolle und zugewiesenen Berechtigungen einzuschränken.

Eine andere Option besteht möglicherweise darin, temporäre Keepspaces und/oder Tabellen nach Bedarf zu erstellen, wenn sich ein Benutzer bei der Anwendung anmeldet und sie beim Abmelden des Benutzers ablegt.

Offensichtlich gibt es hier eine Menge verschiedener Möglichkeiten, und es läuft mehr auf architektonische Entscheidungen, Kompromisse und Überlegungen hinaus, dann macht es technische Machbarkeit, also sei vorsichtig.

Hoffe, das hilft.

Prost!

10

Die folgende Spring-Konfigurationsklasse erstellt Schlüsselraum und Tabellen, wenn sie nicht existieren.

@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

Ich habe gefolgt, aber ich bin noch nicht Erstellen Sie Keyspace und Tabellen beim Start der Anwendung. Gibt es noch etwas, das ich vermisse? Bitte führen Sie mich. – Milesh

0

Die folgenden cassandra Konfiguration einen Schlüsselraum erstellen, wenn es nicht und auch der Start-up-Skript

läuft existiert angegeben diesen Code
@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;"); 
    } 

}