Cassandraを使用して、Spring Bootアプリケーションを使用して動的にキースペースとテーブルを作成します。 Javaベースの構成を使用しています。
@Tableアノテーションが付けられたエンティティがあり、そのスキーマは、事前にわかっている固定フィールドがあるため、アプリケーションの起動前に作成する必要があります。
ただし、ログインしているユーザーに応じて、それらのユーザー用に追加のテーブルを動的に作成し、それらのテーブルにエントリを挿入できるようにしたいと考えています。
誰かが私が利用できるいくつかのリソースに私を案内したり、これらの問題を解決する方法に私を正しい方向に向けることができますか?助けてくれてありがとう!
最も簡単なことは、 Spring Boot Starter Data Cassandra 依存関係をSpring Bootアプリケーションに追加することです。 ..
_<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
_
さらに、これによりSpring Data Cassandradependency がアプリケーションに追加されます。
Spring Data Cassandraでは、CassandraClusterFactoryBean
(より正確には、サブクラス... CassandraCqlClusterFactoryBean
)を使用してアプリケーションのキースペースを構成できます。 setKeyspaceCreations(:Set) メソッド。
KeyspaceActionSpecification クラスは一目瞭然です。 KeyspaceActionSpecificationFactoryBean を使用して作成し、それをSet
に追加して、CassandraClusterFactoryBean
のsetKeyspaceCreations(..)
メソッドに渡すこともできます。
アプリケーションのテーブルを生成するには、基本的に、SD Cassandra @ Table アノテーションを使用して、アプリケーションドメインオブジェクト(エンティティ)に注釈を付ける必要があります。ドメインオブジェクト/エンティティは、アプリケーションのCLASSPATHにあります。
具体的には、アプリケーションに_@Configuration
_クラスを拡張して、SD Cassandra AbstractClusterConfiguration クラスを拡張できます。そこに、 getEntityBasePackages())があります。 String [] アプリケーションドメインオブジェクト/エンティティクラスを含むパッケージの場所を提供するためにオーバーライドできるメソッド。これは、SD Cassandraが scan for _@Table
_ドメインオブジェクト/エンティティ。
アプリケーション_@Table
_ドメインオブジェクト/エンティティが適切に識別されたら、CREATE
メソッドを使用してSD Cassandra SchemaAction をCassandraSessionFactoryBean
に設定します setSchemaAction( :SchemaAction) 。これにより、スキャン中に見つかったすべてのドメインオブジェクト/エンティティのキースペースにテーブルが作成され、 identifiedCassandraSessionFactoryBean
に適切なキースペースが適切に提供されます。
明らかに、アプリケーションが複数のキースペースを作成/使用する場合は、特定のキースペースに属するエンティティに適切に設定されたCassandraSessionFactoryBean
構成プロパティを使用して、キースペースごとに個別のentityBasePackages
を作成し、関連するテーブルがそのキースペースに作成されるようにする必要があります。 。
さて...
ユーザーごとの「追加の」テーブルの場合、これはかなり複雑でトリッキーです。
ここでSpringプロファイルを活用できる場合がありますが、プロファイルは通常、起動時にのみ適用されます。別のユーザーが既に実行中のアプリケーションにログインする場合、実行時にSpring ApplicationContext
に追加の_@Configuration
_クラスを提供する方法が必要です。
Spring BootアプリケーションがAnnotationConfigApplicationContext
への参照を挿入し、それをログインイベントで使用してプログラムで register 追加_@Configuration
_アプリケーションにログインしたユーザーに基づくクラス。 register(Class...)
呼び出しの後にApplicationContext.refresh()
を付ける必要があります。
また、テーブルがすでに存在する状況にも適切に対処する必要があります。
これは現在SD Cassandraではサポートされていませんが、詳細については DATACASS-219 を参照してください。
技術的には、実行時にアプリケーションがすべてのユーザーに対して必要とする可能性のあるすべてのテーブルを作成し、Cassandraのセキュリティ設定を使用して、役割と割り当てられた権限によって個々のユーザーアクセスを制限する方がはるかに簡単です。
別のオプションは、ユーザーがアプリケーションにログインするときに必要に応じて一時的なキースペースやテーブルを作成し、ユーザーがログアウトするときにそれらを削除することです。
明らかに、ここには多くの異なる選択肢があり、それはアーキテクチャの決定、トレードオフ、および考慮事項に要約され、技術的な実現可能性を実現するため、注意が必要です。
お役に立てれば。
乾杯!
以下のSpring構成クラスは、存在しない場合にキースペースとテーブルを作成します。
@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;
}
}
@EnesAltınkayaの回答を使用する:
@Value("${cassandra.keyspace}")
private String keySpace;
@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
return Arrays.asList(
CreateKeyspaceSpecification.createKeyspace()
.name(keySpace)
.ifNotExists()
.withNetworkReplication(new DataCenterReplication("dc1", 3L)));
}
変数を定義するには、application.properties
またはapplication.yml
ファイルを使用します。
cassandra:
keyspace: yout_keyspace_name
ハードコードされた文字列の代わりに構成ファイルを使用すると、パスワードやエントリポイント(.gitignore
ファイル)を公開せずに、コードをGitHubなどに公開できます。
次のcassandra configurationは、キースペースが存在しない場合に作成し、指定された起動スクリプトも実行します
@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;");
}
}
テーブルの作成には、application.propertiesファイルでこれを使用できます
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS
この答えは、Viswanathの答えに触発されています。
私の_cassandra.yml
_は次のようになります:
_
spring:
data:
cassandra:
cluster-name: Test Cluster
keyspace-name: keyspace
port: 9042
contact-points:
- 127.0.0.1
_
_
@Configuration
@PropertySource(value = { "classpath:cassandra.yml" })
@ConfigurationProperties("spring.data.cassandra")
@EnableCassandraRepositories(basePackages = "info.vishrantgupta.repository")
public class CassandraConfig extends AbstractCassandraConfiguration {
@Value("${keyspacename}")
protected String keyspaceName;
@Override
protected String getKeyspaceName() {
return this.keyspaceName;
}
@Override
protected List getKeyspaceCreations() {
return Collections.singletonList(CreateKeyspaceSpecification
.createKeyspace(keyspaceName).ifNotExists()
.with(KeyspaceOption.DURABLE_WRITES, true)
.withSimpleReplication());
}
@Override
protected List getStartupScripts() {
return Collections.singletonList("CREATE KEYSPACE IF NOT EXISTS "
+ keyspaceName + " WITH replication = {"
+ " 'class': 'SimpleStrategy', "
+ " 'replication_factor': '3' " + "};");
}
}
_
@ConfigurationProperties("spring.data.cassandra")
をカスタマイズする必要がある場合があります。設定が_cassandra.yml
_ファイルのcassandra
で始まる場合は、@ConfigurationProperties("cassandra")
を使用します