diff --git a/spring-geode/spring-geode.gradle b/spring-geode/spring-geode.gradle index af84692e..d7087074 100644 --- a/spring-geode/spring-geode.gradle +++ b/spring-geode/spring-geode.gradle @@ -27,6 +27,7 @@ dependencies { testCompile "org.mockito:mockito-core" testCompile "org.projectlombok:lombok" testCompile "org.testcontainers:testcontainers" + testCompile "org.testcontainers:cassandra" testCompile "edu.umd.cs.mtc:multithreadedtc" testCompile("org.springframework.boot:spring-boot-starter-test") { diff --git a/spring-geode/src/test/java/example/app/crm/config/TestCassandraConfiguration.java b/spring-geode/src/test/java/example/app/crm/config/TestCassandraConfiguration.java index 66dd6073..cede16f0 100644 --- a/spring-geode/src/test/java/example/app/crm/config/TestCassandraConfiguration.java +++ b/spring-geode/src/test/java/example/app/crm/config/TestCassandraConfiguration.java @@ -15,96 +15,198 @@ */ package example.app.crm.config; -import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException; +import static org.assertj.core.api.Assertions.assertThat; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; +import java.util.Optional; +import java.util.function.Consumer; +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.session.Session; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; +import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; -import org.springframework.data.cassandra.config.AbstractCassandraConfiguration; +import org.springframework.data.cassandra.SessionFactory; import org.springframework.data.cassandra.config.CqlSessionFactoryBean; -import org.springframework.data.gemfire.tests.util.IOUtils; +import org.springframework.data.cassandra.core.CassandraTemplate; +import org.springframework.data.cassandra.core.cql.CqlTemplate; +import org.springframework.data.cassandra.core.cql.RowMapper; +import org.springframework.data.cassandra.core.cql.session.init.KeyspacePopulator; +import org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator; +import org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer; import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; + +import example.app.crm.model.Customer; +import example.app.crm.repo.CustomerRepository; /** * Base test configuration used to configure and bootstrap an Apache Cassandra database with a schema and data. * * @author John Blum + * @see com.datastax.oss.driver.api.core.session.Session + * @see org.springframework.beans.factory.config.BeanPostProcessor + * @see org.springframework.context.annotation.Bean * @see org.springframework.core.io.Resource - * @see org.springframework.data.cassandra.config.AbstractCassandraConfiguration + * @see org.springframework.data.cassandra.SessionFactory * @see org.springframework.data.cassandra.config.CqlSessionFactoryBean + * @see org.springframework.data.cassandra.core.CassandraTemplate + * @see org.springframework.data.cassandra.core.cql.CqlTemplate + * @see org.springframework.data.cassandra.core.cql.session.init.KeyspacePopulator + * @see org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer * @since 1.1.0 */ -public abstract class TestCassandraConfiguration extends AbstractCassandraConfiguration { +@SuppressWarnings("unused") +public abstract class TestCassandraConfiguration { + + private static final boolean CONTINUE_ON_ERROR = false; + private static final boolean IGNORE_FAILED_DROPS = true; + + private static final Customer pieDoe = Customer.newCustomer(16L, "Pie Doe"); + + private static final String CQL_SCRIPT_ENCODING = null; protected static final int CASSANDRA_DEFAULT_PORT = CqlSessionFactoryBean.DEFAULT_PORT; - private static final String CASSANDRA_DATA_CQL = "cassandra-data.cql"; - private static final String CASSANDRA_SCHEMA_CQL = "cassandra-schema.cql"; - private static final String LOCAL_DATA_CENTER = "datacenter1"; - private static final String KEYSPACE_NAME = "CustomerService"; - private static final String SESSION_NAME = "CustomerServiceCluster"; + protected static final String CASSANDRA_DATA_CQL = "cassandra-data.cql"; + protected static final String CASSANDRA_INIT_CQL = "cassandra-init.cql"; + protected static final String CASSANDRA_SCHEMA_CQL = "cassandra-schema.cql"; + protected static final String DEBUGGING_PROFILE = "debugging"; + protected static final String KEYSPACE_NAME = "CustomerService"; + protected static final String TABLE_NAME = "Customers"; - @NonNull - @Override - protected String getKeyspaceName() { - return KEYSPACE_NAME; + protected @NonNull Resource newCassandraDataCqlScriptResource() { + return new ClassPathResource(CASSANDRA_DATA_CQL); } - @Override - protected String getLocalDataCenter() { - return LOCAL_DATA_CENTER; + protected @NonNull Resource newCassandraInitCqlScriptResource() { + return new ClassPathResource(CASSANDRA_INIT_CQL); } - @Nullable - @Override - protected String getSessionName() { - return SESSION_NAME; + protected @NonNull Resource newCassandraSchemaCqlScriptResource() { + return new ClassPathResource(CASSANDRA_SCHEMA_CQL); } - /* - @Nullable @Override - protected KeyspacePopulator keyspacePopulator() { - return cqlSession -> loadCassandraCqlScripts().forEach(cqlSession::execute); - } - */ + @Bean + SessionFactoryInitializer sessionFactoryInitializer(SessionFactory sessionFactory) { - // TODO: Remove use of deprecation after Spring Data for Apache Cassandra issues are resolved! - @Override - protected List getStartupScripts() { + SessionFactoryInitializer sessionFactoryInitializer = new SessionFactoryInitializer(); - List startupScripts = new ArrayList<>(super.getStartupScripts()); + KeyspacePopulator keyspacePopulator = newKeyspacePopulator(newCassandraDataCqlScriptResource()); - startupScripts.addAll(readLines(new ClassPathResource(CASSANDRA_SCHEMA_CQL))); - startupScripts.addAll(readLines(new ClassPathResource(CASSANDRA_DATA_CQL))); + sessionFactoryInitializer.setKeyspacePopulator(keyspacePopulator); + sessionFactoryInitializer.setSessionFactory(sessionFactory); - return startupScripts; + return sessionFactoryInitializer; } - private @NonNull List readLines(@NonNull Resource resource) { + protected @NonNull KeyspacePopulator newKeyspacePopulator(Resource... cqlScripts) { + return new ResourceKeyspacePopulator(CONTINUE_ON_ERROR, IGNORE_FAILED_DROPS, CQL_SCRIPT_ENCODING, cqlScripts); + } - BufferedReader resourceReader = null; + @Bean + @Profile(DEBUGGING_PROFILE) + BeanPostProcessor cassandraTemplatePostProcessor() { - try { + return new BeanPostProcessor() { - resourceReader = new BufferedReader(new InputStreamReader(resource.getInputStream())); + @Override + public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException { - return resourceReader.lines() - .filter(StringUtils::hasText) - .collect(Collectors.toList()); - } - catch (IOException cause) { - throw newRuntimeException(cause, "Failed to read from Resource [%s]", resource); - } - finally { - IOUtils.close(resourceReader); - } + if (bean instanceof CassandraTemplate) { + + CassandraTemplate cassandraTemplate = (CassandraTemplate) bean; + + Consumer cassandraTemplateConsumer = noopCassandraTemplateConsumer() + .andThen(insertEntityObjectCassandraTemplateConsumer()) + .andThen(assertEntityCountCassandraTemplateConsumer()) + .andThen(assertEntityObjectCassandraTemplateConsumer()) + .andThen(assertKeyspaceNameCassandraTemplateConsumer()) + .andThen(assertTableNameCassandraTemplateConsumer()); + + cassandraTemplateConsumer.accept(cassandraTemplate); + } + + return bean; + } + }; + } + + private Consumer noopCassandraTemplateConsumer() { + return cassandraTemplate -> {}; + } + + private Consumer assertEntityCountCassandraTemplateConsumer() { + return cassandraTemplate -> assertThat(cassandraTemplate.count(Customer.class)).isOne(); + } + + private Consumer assertEntityObjectCassandraTemplateConsumer() { + + return cassandraTemplate -> { + + String cql = "SELECT id, name FROM \"Customers\""; + + RowMapper customerRowMapper = (row, rowNumber) -> + Customer.newCustomer(row.getLong("id"), row.getString("name")); + + Customer actualCustomer = cassandraTemplate.getCqlOperations().queryForObject(cql, customerRowMapper); + + assertThat(actualCustomer).isEqualTo(pieDoe); + assertThat(cassandraTemplate.selectOneById(16L, Customer.class)).isEqualTo(pieDoe); + assertThat(cassandraTemplate.query(Customer.class).stream().findFirst().orElse(null)).isEqualTo(pieDoe); + }; + } + + private Consumer insertEntityObjectCassandraTemplateConsumer() { + return cassandraTemplate -> cassandraTemplate.insert(pieDoe); + } + + private Consumer assertKeyspaceNameCassandraTemplateConsumer() { + + return cassandraTemplate -> { + + String resolvedKeyspaceName = Optional.of(cassandraTemplate.getCqlOperations()) + .filter(CqlTemplate.class::isInstance) + .map(CqlTemplate.class::cast) + .map(CqlTemplate::getSessionFactory) + .map(SessionFactory::getSession) + .flatMap(Session::getKeyspace) + .map(CqlIdentifier::toString) + .orElse(null); + + assertThat(resolvedKeyspaceName).isEqualToIgnoringCase(KEYSPACE_NAME); + }; + } + + private Consumer assertTableNameCassandraTemplateConsumer() { + + return cassandraTemplate -> { + + String entityTableName = cassandraTemplate.getTableName(Customer.class).toString(); + + assertThat(entityTableName).endsWith(TABLE_NAME); + + Optional.of(cassandraTemplate.getCqlOperations()) + .filter(CqlTemplate.class::isInstance) + .map(CqlTemplate.class::cast) + .map(CqlTemplate::getSessionFactory) + .map(SessionFactory::getSession) + .map(Session::getMetadata) + .flatMap(metadata -> metadata.getKeyspace(KEYSPACE_NAME)) + .map(keyspaceMetadata -> keyspaceMetadata.getTable(entityTableName)) + .orElseThrow(() -> new IllegalStateException(String.format("Table [%s] not found", entityTableName))); + }; + } + + @Bean + @Profile(DEBUGGING_PROFILE) + ApplicationListener populateCassandraDatabaseUsingRepository( + CustomerRepository customerRepository) { + + return event -> customerRepository.save(pieDoe); } } diff --git a/spring-geode/src/test/java/example/app/crm/config/TestcontainersCassandraConfiguration.java b/spring-geode/src/test/java/example/app/crm/config/TestcontainersCassandraConfiguration.java index 1a928981..336acc75 100644 --- a/spring-geode/src/test/java/example/app/crm/config/TestcontainersCassandraConfiguration.java +++ b/spring-geode/src/test/java/example/app/crm/config/TestcontainersCassandraConfiguration.java @@ -15,63 +15,163 @@ */ package example.app.crm.config; +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.InetSocketAddress; +import java.util.Arrays; + +import com.datastax.oss.driver.api.core.CqlSession; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.cassandra.CassandraProperties; +import org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.data.cassandra.core.CassandraTemplate; +import org.springframework.lang.NonNull; +import org.testcontainers.containers.CassandraContainer; import org.testcontainers.containers.GenericContainer; +import example.app.crm.model.Customer; + /** * Spring {@link @Configuration} for Apache Cassandra using Testcontainers. * * @author John Blum + * @see java.net.InetSocketAddress + * @see com.datastax.oss.driver.api.core.CqlSession + * @see org.springframework.boot.autoconfigure.cassandra.CqlSessionBuilderCustomizer + * @see org.springframework.boot.autoconfigure.domain.EntityScan * @see org.springframework.context.annotation.Bean * @see org.springframework.context.annotation.Configuration * @see org.springframework.context.annotation.Profile + * @see org.testcontainers.containers.CassandraContainer * @see org.testcontainers.containers.GenericContainer * @since 1.1.0 */ @Configuration @Profile("inline-caching-cassandra") +@EntityScan(basePackageClasses = Customer.class) @SuppressWarnings("unused") public class TestcontainersCassandraConfiguration extends TestCassandraConfiguration { private static final String CASSANDRA_DOCKER_IMAGE_NAME = "cassandra:latest"; + private static final String LOCAL_DATACENTER_NAME = "datacenter1"; - @Bean - @SuppressWarnings("rawtypes") - GenericContainer cassandraContainer() { + @Bean("CassandraContainer") + GenericContainer cassandraContainer(Environment environment) { - GenericContainer cassandraContainer = newCustomCassandraContainer(); + GenericContainer cassandraContainer = newEnvironmentOptimizedCassandraContainer(); cassandraContainer.start(); + return withCassandraServer(cassandraContainer, environment); + } + + private @NonNull GenericContainer newCassandraContainer() { + + return new CassandraContainer<>(CASSANDRA_DOCKER_IMAGE_NAME) + .withInitScript(CASSANDRA_SCHEMA_CQL) + //.withInitScript(CASSANDRA_INIT_CQL) + .withExposedPorts(CASSANDRA_DEFAULT_PORT) + .withReuse(true); + } + + // Information (feedback) received from Sergei Egorov. + private @NonNull GenericContainer newEnvironmentOptimizedCassandraContainer() { + + return newCassandraContainer() + .withEnv("CASSANDRA_SNITCH", "GossipingPropertyFileSnitch") + .withEnv("HEAP_NEWSIZE", "128M") + .withEnv("MAX_HEAP_SIZE", "1024M") + .withEnv("JVM_OPTS", "-Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.initial_token=0"); + } + + private @NonNull CassandraTemplate newCassandraTemplate(@NonNull CqlSession session) { + return new CassandraTemplate(session); + } + + private @NonNull CqlSession newCqlSession(@NonNull GenericContainer cassandraContainer) { + + return CqlSession.builder() + .addContactPoint(resolveContactPoint(cassandraContainer)) + .withLocalDatacenter(LOCAL_DATACENTER_NAME) + .build(); + } + + private @NonNull GenericContainer withCassandraServer(@NonNull GenericContainer cassandraContainer, + @NonNull Environment environment) { + + if (Arrays.asList(environment.getActiveProfiles()).contains(DEBUGGING_PROFILE)) { + cassandraContainer = initializeCassandraServer(cassandraContainer); + cassandraContainer = assertCassandraServerSetup(cassandraContainer); + } + return cassandraContainer; } - @SuppressWarnings("rawtypes") - private GenericContainer newCassandraContainer() { - return new GenericContainer(CASSANDRA_DOCKER_IMAGE_NAME) - .withExposedPorts(CASSANDRA_DEFAULT_PORT); + private @NonNull GenericContainer initializeCassandraServer(@NonNull GenericContainer cassandraContainer) { + + try (CqlSession session = newCqlSession(cassandraContainer)) { + newKeyspacePopulator(newCassandraSchemaCqlScriptResource()).populate(session); + } + + return cassandraContainer; } - @SuppressWarnings("rawtypes") - private GenericContainer newCustomCassandraContainer() { + private @NonNull GenericContainer assertCassandraServerSetup(@NonNull GenericContainer cassandraContainer) { - return newCassandraContainer() - .withEnv("HEAP_NEWSIZE", "128M") - .withEnv("MAX_HEAP_SIZE", "1024M") - .withEnv("JVM_OPTS", "-Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.initial_token=0") - .withEnv("CASSANDRA_SNITCH", "GossipingPropertyFileSnitch"); + try (CqlSession session = newCqlSession(cassandraContainer)) { + + session.getMetadata().getKeyspace(KEYSPACE_NAME) + .map(keyspaceMetadata -> { + + assertThat(keyspaceMetadata.getName().toString()).isEqualToIgnoringCase(KEYSPACE_NAME); + + keyspaceMetadata.getTable(TABLE_NAME) + .map(tableMetadata -> { + + assertThat(tableMetadata.getName().toString()).isEqualTo(TABLE_NAME); + assertThat(tableMetadata.getKeyspace().toString()).isEqualToIgnoringCase(KEYSPACE_NAME); + //assertCustomersTableHasSizeOne(session); + + return tableMetadata; + }) + .orElseThrow(() -> new IllegalStateException(String.format("Table [%s] not found", TABLE_NAME))); + + return keyspaceMetadata; + }) + .orElseThrow(() -> new IllegalStateException(String.format("Keyspace [%s] not found", KEYSPACE_NAME))); + } + + return cassandraContainer; } - @Override - protected String getContactPoints() { - return cassandraContainer().getContainerIpAddress(); + private void assertCustomersTableHasSizeOne(@NonNull CqlSession session) { + + CassandraTemplate template = newCassandraTemplate(session); + + assertThat(template.getCqlOperations().execute(String.format("USE %s;", KEYSPACE_NAME))).isTrue(); + assertThat(template.getCqlOperations().queryForObject("SELECT count(*) FROM \"Customers\"", Long.class)).isOne(); + //assertThat(template.count(Customer.class)).isOne(); // Table Customers not found; needs to use the Keyspace } - @Override - protected int getPort() { - return cassandraContainer().getFirstMappedPort(); + @Bean + CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer(CassandraProperties properties, + @Qualifier("CassandraContainer") GenericContainer cassandraContainer) { + + return cqlSessionBuilder -> cqlSessionBuilder + .addContactPoint(resolveContactPoint(cassandraContainer)) + .withLocalDatacenter(properties.getLocalDatacenter()) + .withKeyspace(properties.getKeyspaceName()); + } + + private @NonNull InetSocketAddress resolveContactPoint(@NonNull GenericContainer cassandraContainer) { + return new InetSocketAddress(cassandraContainer.getHost(), + cassandraContainer.getMappedPort(CASSANDRA_DEFAULT_PORT)); } } diff --git a/spring-geode/src/test/java/example/app/crm/model/Customer.java b/spring-geode/src/test/java/example/app/crm/model/Customer.java index a0188c24..f8c20183 100644 --- a/spring-geode/src/test/java/example/app/crm/model/Customer.java +++ b/spring-geode/src/test/java/example/app/crm/model/Customer.java @@ -18,7 +18,6 @@ package example.app.crm.model; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.core.mapping.Indexed; import org.springframework.data.cassandra.core.mapping.PrimaryKey; import org.springframework.data.gemfire.mapping.annotation.Region; @@ -32,8 +31,11 @@ import lombok.NoArgsConstructor; * The {@link Customer} class is an Abstract Data Type (ADT) modeling a customer. * * @author John Blum - * @see lombok - * @see org.springframework.data.annotation.Id + * @see javax.persistence.Entity + * @see javax.persistence.Table + * @see org.springframework.data.cassandra.core.mapping.Indexed + * @see org.springframework.data.cassandra.core.mapping.PrimaryKey + * @see org.springframework.data.cassandra.core.mapping.Table * @see org.springframework.data.gemfire.mapping.annotation.Region * @since 1.1.0 */ @@ -46,9 +48,8 @@ import lombok.NoArgsConstructor; @AllArgsConstructor(staticName = "newCustomer") public class Customer { - @Id - @javax.persistence.Id @PrimaryKey + @javax.persistence.Id private Long id; @Indexed diff --git a/spring-geode/src/test/java/org/springframework/geode/cache/inline/AbstractInlineCachingWithExternalDataSourceIntegrationTests.java b/spring-geode/src/test/java/org/springframework/geode/cache/inline/AbstractInlineCachingWithExternalDataSourceIntegrationTests.java index 4a6daddc..6e9ab8f5 100644 --- a/spring-geode/src/test/java/org/springframework/geode/cache/inline/AbstractInlineCachingWithExternalDataSourceIntegrationTests.java +++ b/spring-geode/src/test/java/org/springframework/geode/cache/inline/AbstractInlineCachingWithExternalDataSourceIntegrationTests.java @@ -41,8 +41,6 @@ import example.app.crm.repo.CustomerRepository; @SuppressWarnings("unused") public abstract class AbstractInlineCachingWithExternalDataSourceIntegrationTests extends IntegrationTestsSupport { - public static final String GEMFIRE_LOG_LEVEL = "off"; - @Autowired private CustomerRepository customerRepository; diff --git a/spring-geode/src/test/java/org/springframework/geode/cache/inline/cassandra/InlineCachingWithCassandraIntegrationTests.java b/spring-geode/src/test/java/org/springframework/geode/cache/inline/cassandra/InlineCachingWithCassandraIntegrationTests.java index 3e34a0a3..071b47e2 100644 --- a/spring-geode/src/test/java/org/springframework/geode/cache/inline/cassandra/InlineCachingWithCassandraIntegrationTests.java +++ b/spring-geode/src/test/java/org/springframework/geode/cache/inline/cassandra/InlineCachingWithCassandraIntegrationTests.java @@ -23,7 +23,6 @@ import org.apache.geode.cache.GemFireCache; import org.apache.geode.cache.client.ClientRegionShortcut; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; @@ -60,6 +59,7 @@ import example.app.crm.repo.CustomerRepository; * @see org.springframework.geode.cache.inline.AbstractInlineCachingWithExternalDataSourceIntegrationTests * @see org.springframework.test.context.ActiveProfiles * @see org.springframework.test.context.junit4.SpringRunner + * @see example.app.crm.config.TestcontainersCassandraConfiguration * @since 1.1.0 */ @SpringBootTest @@ -69,8 +69,8 @@ import example.app.crm.repo.CustomerRepository; public class InlineCachingWithCassandraIntegrationTests extends AbstractInlineCachingWithExternalDataSourceIntegrationTests { - @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, CassandraDataAutoConfiguration.class }) - @ClientCacheApplication(logLevel = GEMFIRE_LOG_LEVEL) + @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) + @ClientCacheApplication @EnableCassandraRepositories(basePackageClasses = CustomerRepository.class) @EnableEntityDefinedRegions(basePackageClasses = Customer.class, clientRegionShortcut = ClientRegionShortcut.LOCAL) @Import(TestcontainersCassandraConfiguration.class) diff --git a/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java b/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java index b250d049..d821f879 100644 --- a/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java +++ b/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java @@ -68,7 +68,7 @@ public class InlineCachingWithDatabaseIntegrationTests extends AbstractInlineCachingWithExternalDataSourceIntegrationTests { @SpringBootApplication(exclude = { CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class }) - @ClientCacheApplication(logLevel = GEMFIRE_LOG_LEVEL) + @ClientCacheApplication @EntityScan(basePackageClasses = Customer.class) @EnableEntityDefinedRegions(basePackageClasses = Customer.class, clientRegionShortcut = ClientRegionShortcut.LOCAL) @EnableJpaRepositories(basePackageClasses = CustomerRepository.class) diff --git a/spring-geode/src/test/resources/application-inline-caching-cassandra.properties b/spring-geode/src/test/resources/application-inline-caching-cassandra.properties new file mode 100644 index 00000000..6f7ca387 --- /dev/null +++ b/spring-geode/src/test/resources/application-inline-caching-cassandra.properties @@ -0,0 +1,5 @@ +# Spring Boot application.properties for Apache Cassandra configuration of Inline Caching + +spring.data.cassandra.keyspace-name=CustomerService +spring.data.cassandra.schema-action=recreate +spring.data.cassandra.local-datacenter=datacenter1 diff --git a/spring-geode/src/test/resources/application-inline-caching-database.properties b/spring-geode/src/test/resources/application-inline-caching-database.properties index 3516ffb2..06254c81 100644 --- a/spring-geode/src/test/resources/application-inline-caching-database.properties +++ b/spring-geode/src/test/resources/application-inline-caching-database.properties @@ -1,4 +1,4 @@ -# RBMS (Database) configuration properties +# Spring Boot application.properties for RDBMS (Database) configuration of Inline Caching spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=none diff --git a/spring-geode/src/test/resources/cassandra-data.cql b/spring-geode/src/test/resources/cassandra-data.cql index 9c64b2f2..2b682ebb 100644 --- a/spring-geode/src/test/resources/cassandra-data.cql +++ b/spring-geode/src/test/resources/cassandra-data.cql @@ -1 +1 @@ -INSERT INTO customers (id, name) VALUES (16, 'Pie Doe'); +INSERT INTO "Customers" (id, name) VALUES (16, 'Pie Doe'); diff --git a/spring-geode/src/test/resources/cassandra-init.cql b/spring-geode/src/test/resources/cassandra-init.cql new file mode 100644 index 00000000..c0f63a65 --- /dev/null +++ b/spring-geode/src/test/resources/cassandra-init.cql @@ -0,0 +1,5 @@ +CREATE KEYSPACE IF NOT EXISTS CustomerService WITH replication = { 'class':'SimpleStrategy', 'replication_factor':1 }; +USE CustomerService; +CREATE TABLE IF NOT EXISTS "Customers" (id BIGINT PRIMARY KEY, name TEXT); +CREATE INDEX IF NOT EXISTS CustomerNameIdx ON "Customers"(name); +INSERT INTO "Customers" (id, name) VALUES (16, 'Pie Doe'); diff --git a/spring-geode/src/test/resources/cassandra-schema.cql b/spring-geode/src/test/resources/cassandra-schema.cql index 89ddcf17..80d7a04e 100644 --- a/spring-geode/src/test/resources/cassandra-schema.cql +++ b/spring-geode/src/test/resources/cassandra-schema.cql @@ -1,4 +1,4 @@ CREATE KEYSPACE IF NOT EXISTS CustomerService WITH replication = { 'class':'SimpleStrategy', 'replication_factor':1 }; USE CustomerService; -CREATE TABLE IF NOT EXISTS customers (id BIGINT PRIMARY KEY, name TEXT); -CREATE INDEX IF NOT EXISTS CustomerNameIdx ON customers(name); +CREATE TABLE IF NOT EXISTS "Customers" (id BIGINT PRIMARY KEY, name TEXT); +CREATE INDEX IF NOT EXISTS CustomerNameIdx ON "Customers"(name);