#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:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -13,37 +13,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.cassandra;
|
||||
package example.springdata.cassandra.basic;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cassandra.config.java.AbstractCqlTemplateConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.core.CassandraTemplate;
|
||||
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* Basic {@link Configuration} to create the necessary schema for the {@link User} table.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
class SimpleConfiguration {
|
||||
class BasicConfiguration {
|
||||
|
||||
@Configuration
|
||||
@EnableCassandraRepositories
|
||||
static class CassandraConfig extends AbstractCqlTemplateConfiguration {
|
||||
static class CassandraConfig extends AbstractCassandraConfiguration {
|
||||
|
||||
@Override
|
||||
public String getKeyspaceName() {
|
||||
return "example";
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public CassandraTemplate cassandraTemplate(Session session) {
|
||||
return new CassandraTemplate(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { User.class.getPackage().getName() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaAction getSchemaAction() {
|
||||
return SchemaAction.RECREATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013-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.basic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.cassandra.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Simple repository interface for {@link User} instances. The interface is used to declare so called query methods,
|
||||
* methods to retrieve single entities or collections of them.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface BasicUserRepository extends CrudRepository<User, Long> {
|
||||
|
||||
/**
|
||||
* Sample method annotated with {@link Query}. This method executes the CQL from the {@link Query} value.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Query("SELECT * from users where user_id in(?0)")
|
||||
User findUserByIdIn(long id);
|
||||
|
||||
/**
|
||||
* Derived query method. This query corresponds with {@code SELECT * FROM users WHERE uname = ?0}.
|
||||
* {@link User#username} is not part of the primary so it requires a secondary index.
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
User findUserByUsername(String username);
|
||||
|
||||
/**
|
||||
* Derived query method using SASI (SSTable Attached Secondary Index) features through the {@code LIKE} keyword. This
|
||||
* query corresponds with {@code SELECT * FROM users WHERE uname LIKE '?0%'}. {@link User#username} is not part of the
|
||||
* primary so it requires a secondary index.
|
||||
*
|
||||
* @param lastnamePrefix
|
||||
* @return
|
||||
*/
|
||||
List<User> findUsersByLastnameStartsWith(String lastnamePrefix);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.cassandra;
|
||||
package example.springdata.cassandra.basic;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Package showing a simple repository interface to use basic query method execution functionality.
|
||||
*/
|
||||
package example.springdata.cassandra;
|
||||
package example.springdata.cassandra.basic;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -13,14 +13,26 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.springdata.cassandra;
|
||||
package example.springdata.cassandra.convert;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple repository interface for {@link User} instances. The interface is used to declare so called query methods,
|
||||
* methods to retrieve single entities or collections of them.
|
||||
* Sample Addressbook class.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface SimpleUserRepository extends CrudRepository<User, Long> {}
|
||||
@Data
|
||||
@Table
|
||||
public class Addressbook {
|
||||
|
||||
@Id String id;
|
||||
|
||||
Contact me;
|
||||
List<Contact> friends;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.convert;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Sample Contact class.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Contact {
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.convert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
|
||||
import org.springframework.data.cassandra.convert.CustomConversions;
|
||||
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* {@link Configuration} class to register custom converters.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCassandraRepositories
|
||||
class ConverterConfiguration extends AbstractCassandraConfiguration {
|
||||
|
||||
@Override
|
||||
public String getKeyspaceName() {
|
||||
return "example";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { Addressbook.class.getPackage().getName() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaAction getSchemaAction() {
|
||||
return SchemaAction.RECREATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomConversions customConversions() {
|
||||
|
||||
List<Converter<?, ?>> converters = new ArrayList<>();
|
||||
converters.add(new PersonWriteConverter());
|
||||
converters.add(new PersonReadConverter());
|
||||
converters.add(new CustomAddressbookReadConverter());
|
||||
|
||||
return new CustomConversions(converters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a {@link Contact} into its {@link String} representation.
|
||||
*/
|
||||
static class PersonWriteConverter implements Converter<Contact, String> {
|
||||
|
||||
public String convert(Contact source) {
|
||||
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(source);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a {@link Contact} from its {@link String} representation.
|
||||
*/
|
||||
static class PersonReadConverter implements Converter<String, Contact> {
|
||||
|
||||
public Contact convert(String source) {
|
||||
|
||||
if (StringUtils.hasText(source)) {
|
||||
try {
|
||||
return new ObjectMapper().readValue(source, Contact.class);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform custom mapping by reading a {@link Row} into a custom class.
|
||||
*/
|
||||
static class CustomAddressbookReadConverter implements Converter<Row, CustomAddressbook> {
|
||||
|
||||
public CustomAddressbook convert(Row source) {
|
||||
|
||||
CustomAddressbook result = new CustomAddressbook();
|
||||
|
||||
result.setTheId(source.getString("id"));
|
||||
result.setMyDetailsAsJson(source.getString("me"));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.convert;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Data
|
||||
public class CustomAddressbook {
|
||||
|
||||
String theId;
|
||||
String myDetailsAsJson;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Package showing conversion features.
|
||||
*/
|
||||
package example.springdata.cassandra.convert;
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.projection;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Value
|
||||
@Table
|
||||
class Customer {
|
||||
|
||||
@Id String id;
|
||||
String firstname, lastname;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.projection;
|
||||
|
||||
/**
|
||||
* An example projection interface containing only the firstname.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
interface CustomerProjection {
|
||||
|
||||
String getFirstname();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.projection;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Sample repository managing customers to show projecting functionality of Spring Data Cassandra.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
interface CustomerRepository extends CrudRepository<Customer, String> {
|
||||
|
||||
/**
|
||||
* Uses a projection interface to indicate the fields to be returned. As the projection doesn't use any dynamic
|
||||
* fields, the query execution will be restricted to only the fields needed by the projection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Collection<CustomerProjection> findAllProjectedBy();
|
||||
|
||||
/**
|
||||
* When a projection is used that contains dynamic properties (i.e. SpEL expressions in an {@link Value} annotation),
|
||||
* the normal target entity will be loaded but dynamically projected so that the target can be referred to in the
|
||||
* expression.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Collection<CustomerSummary> findAllSummarizedBy();
|
||||
|
||||
/**
|
||||
* Passes in the projection type dynamically.
|
||||
*
|
||||
* @param id
|
||||
* @param projection
|
||||
* @return
|
||||
*/
|
||||
<T> Collection<T> findById(String id, Class<T> projection);
|
||||
|
||||
/**
|
||||
* Projection for a single entity.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
CustomerProjection findProjectedById(String id);
|
||||
|
||||
/**
|
||||
* Dynamic projection for a single entity.
|
||||
*
|
||||
* @param id
|
||||
* @param projection
|
||||
* @return
|
||||
*/
|
||||
<T> T findProjectedById(String id, Class<T> projection);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.projection;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
/**
|
||||
* An example of using SpEL with projections.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
interface CustomerSummary {
|
||||
|
||||
@Value("#{target.firstname + ' ' + target.lastname}")
|
||||
String getFullName();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.projection;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.core.CassandraTemplate;
|
||||
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
import example.springdata.cassandra.basic.User;
|
||||
|
||||
/**
|
||||
* Basic {@link Configuration} to create the necessary schema for the {@link Customer} table.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
class ProjectionConfiguration {
|
||||
|
||||
@Configuration
|
||||
@EnableCassandraRepositories
|
||||
static class CassandraConfig extends AbstractCassandraConfiguration {
|
||||
|
||||
@Override
|
||||
public String getKeyspaceName() {
|
||||
return "example";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEntityBasePackages() {
|
||||
return new String[] { Customer.class.getPackage().getName() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaAction getSchemaAction() {
|
||||
return SchemaAction.RECREATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Package showing projection features.
|
||||
*/
|
||||
package example.springdata.cassandra.projection;
|
||||
Reference in New Issue
Block a user