#203 - Revise Cassandra Examples.

Simplify examples by adopting Spring Boot 1.4 improvements. Upgrade Cassandra Java driver to 3.0.3. Add examples for Ingalls (Query derivation, projection, Java 8 feature support).

Cassandra example setup is now self-contained by requiring just a running Cassandra instance.
Keyspace and tables are created during the tests. Examples also check if Cassandra is running and some examples additionally check the required version. Test execution is skipped if conditions are not met.

Cassandra (2.x) is started with TravisCI.
This commit is contained in:
Mark Paluch
2016-07-25 16:40:41 +02:00
parent d2e5c4b28f
commit 95978416d1
38 changed files with 1708 additions and 112 deletions

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.SchemaAction;
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
/**
* @author Mark Paluch
*/
@Configuration
@EnableAutoConfiguration
class CassandraConfiguration {
@Configuration
@EnableCassandraRepositories
static class CassandraConfig extends AbstractCassandraConfiguration {
@Override
public String getKeyspaceName() {
return "example";
}
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.RECREATE;
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.ZoneId;
import org.springframework.data.annotation.Id;
import org.springframework.data.cassandra.mapping.Table;
/**
* @author Mark Paluch
*/
@Table("pizza_orders")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
@Id String id;
LocalDate orderDate;
ZoneId zoneId;
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import java.time.LocalDate;
import java.time.ZoneId;
import org.springframework.data.cassandra.mapping.CassandraType;
import org.springframework.data.cassandra.repository.Query;
import org.springframework.data.repository.Repository;
/**
* Repository to manage {@link Order} instances.
*
* @author Mark Paluch
*/
public interface OrderRepository extends Repository<Order, String> {
/**
* Method parameters are converted according the registered Converters into Cassandra types.
*/
@Query("SELECT * from pizza_orders WHERE orderdate = ?0 and zoneid = ?1 ALLOW FILTERING")
Order findOrderByOrderDateAndZoneId(LocalDate orderDate, ZoneId zoneId);
/**
* Parameter conversion can be overridden by using the {@link CassandraType} annotation.
*/
@Query("SELECT * from pizza_orders WHERE orderdate = ?0 and zoneid = ?1 ALLOW FILTERING")
Order findOrderByDate(com.datastax.driver.core.LocalDate orderDate, String zoneId);
void deleteAll();
Order save(Order order);
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import org.springframework.data.annotation.Id;
import org.springframework.data.cassandra.mapping.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Mark Paluch
*/
@Table
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id String id;
String firstname, lastname;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import java.util.Optional;
import java.util.stream.Stream;
import org.springframework.data.cassandra.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.Repository;
/**
* Repository to manage {@link Person} instances.
*
* @author Mark Paluch
*/
public interface PersonRepository extends Repository<Person, String> {
/**
* Special customization of {@link CrudRepository#findOne(java.io.Serializable)} to return a JDK 8 {@link Optional}.
*
* @param id
* @return
*/
Optional<Person> findOne(String id);
@Query("select * from person")
Stream<Person> streamAllPeople();
/**
* Sample method to derive a query from using JDK 8's {@link Optional} as return type.
*
* @param id
* @return
*/
@Query("select * from person where id = ?0")
Optional<Person> findById(String id);
/**
* Sample default method to show JDK 8 feature support.
*
* @param person
* @return
*/
default Optional<Person> findByPerson(Person person) {
return findById(person == null ? null : person.id);
}
void deleteAll();
Person save(Person person);
}

View File

@@ -0,0 +1,4 @@
/**
* Package showing Java 8 features.
*/
package example.springdata.cassandra.java8;

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import example.springdata.cassandra.util.RequiresCassandraKeyspace;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.util.Version;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Integration test to show the usage of Java 8 features with Spring Data Cassandra.
*
* @author Mark Paluch
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CassandraConfiguration.class)
public class Java8IntegrationTests {
@ClassRule
public final static RequiresCassandraKeyspace CASSANDRA_KEYSPACE = RequiresCassandraKeyspace.onLocalhost().atLeast(Version.parse("3.0"));
@Autowired PersonRepository repository;
@Before
public void setUp() throws Exception {
repository.deleteAll();
}
@Test
public void providesFindOneWithOptional() {
Person homer = repository.save(new Person("1", "Homer", "Simpson"));
assertThat(repository.findOne(homer.id).isPresent(), is(true));
assertThat(repository.findOne(homer.id + 1), is(Optional.<Person> empty()));
}
@Test
public void invokesDefaultMethod() {
Person homer = repository.save(new Person("1", "Homer", "Simpson"));
Optional<Person> result = repository.findByPerson(homer);
assertThat(result.isPresent(), is(true));
assertThat(result.get(), is(homer));
}
/**
* Streaming data from the store by using a repository method that returns a {@link Stream}. Note, that since the
* resulting {@link Stream} contains state it needs to be closed explicitly after use!
*/
@Test
public void useJava8StreamsWithCustomQuery() {
Person homer = repository.save(new Person("1", "Homer", "Simpson"));
Person bart = repository.save(new Person("2", "Bart", "Simpson"));
try (Stream<Person> stream = repository.streamAllPeople()) {
assertThat(stream.collect(Collectors.toList()), hasItems(homer, bart));
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.cassandra.java8;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.time.LocalDate;
import java.time.ZoneId;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.util.Version;
import org.springframework.test.context.junit4.SpringRunner;
import example.springdata.cassandra.util.RequiresCassandraKeyspace;
/**
* Integration test to show the usage of JSR-310 date/time types with Spring Data Cassandra.
*
* @author Mark Paluch
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CassandraConfiguration.class)
public class Jsr310IntegrationTests {
@ClassRule public final static RequiresCassandraKeyspace CASSANDRA_KEYSPACE = RequiresCassandraKeyspace.onLocalhost()
.atLeast(Version.parse("3.0"));
@Autowired OrderRepository repository;
@Before
public void setUp() throws Exception {
repository.deleteAll();
}
@Test
public void findOneByJsr310Types() {
Order order = new Order("42", LocalDate.now(), ZoneId.systemDefault());
repository.save(order);
assertThat(repository.findOrderByOrderDateAndZoneId(order.getOrderDate(), order.getZoneId()), is(equalTo(order)));
}
@Test
public void findOneByConvertedTypes() {
Order order = new Order("42", LocalDate.of(2010, 1, 2), ZoneId.systemDefault());
repository.save(order);
com.datastax.driver.core.LocalDate date = com.datastax.driver.core.LocalDate.fromYearMonthDay(2010, 1, 2);
String zoneId = order.getZoneId().getId();
assertThat(repository.findOrderByDate(date, zoneId), is(equalTo(order)));
}
}