diff --git a/spring-data-cassandra/pom.xml b/spring-data-cassandra/pom.xml
new file mode 100644
index 0000000000..13c5c18529
--- /dev/null
+++ b/spring-data-cassandra/pom.xml
@@ -0,0 +1,110 @@
+
+ 4.0.0
+
+ org.baeldung
+ spring-data-cassandra
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-data-cassandra
+
+
+ UTF-8
+ 1.3.1.RELEASE
+ 4.2.2.RELEASE
+ 4.11
+ 1.7.12
+ 1.1.3
+ 2.1.5
+ 2.1.9.2
+ 2.1.9.2
+ 2.0-0
+
+
+
+
+ org.springframework.data
+ spring-data-cassandra
+ ${org.springframework.data.version}
+
+
+ org.springframework
+ spring-core
+ ${org.springframework.version}
+
+
+ junit
+ junit-dep
+ ${junit.version}
+ test
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+ org.cassandraunit
+ cassandra-unit-spring
+ ${cassandra-unit-spring.version}
+ test
+
+
+ org.cassandraunit
+ cassandra-unit
+
+
+
+
+ org.cassandraunit
+ cassandra-unit-shaded
+ ${cassandra-unit-shaded}
+ test
+
+
+ org.hectorclient
+ hector-core
+ ${hector-core.version}
+
+
+ com.datastax.cassandra
+ cassandra-driver-core
+ ${cassandra-driver-core.version}
+ true
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java
new file mode 100644
index 0000000000..5f2c4c6d47
--- /dev/null
+++ b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java
@@ -0,0 +1,43 @@
+package org.baeldung.spring.data.cassandra.config;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.data.cassandra.config.CassandraClusterFactoryBean;
+import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
+import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext;
+import org.springframework.data.cassandra.mapping.CassandraMappingContext;
+import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
+
+@Configuration
+@PropertySource(value = { "classpath:cassandra.properties" })
+@EnableCassandraRepositories(basePackages = "org.baeldung.spring.data.cassandra.repository")
+public class CassandraConfig extends AbstractCassandraConfiguration {
+
+ private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class);
+ @Autowired
+ private Environment environment;
+
+ @Override
+ protected String getKeyspaceName() {
+ return environment.getProperty("cassandra.keyspace");
+ }
+
+ @Bean
+ public CassandraClusterFactoryBean cluster() {
+ CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
+ cluster.setContactPoints(environment.getProperty("cassandra.contactpoints"));
+ cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port")));
+ LOGGER.info("Cluster created with contact points [" + environment.getProperty("cassandra.contactpoints") + "] " + "& port [" + Integer.parseInt(environment.getProperty("cassandra.port")) + "].");
+ return cluster;
+ }
+
+ @Bean
+ public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
+ return new BasicCassandraMappingContext();
+ }
+}
\ No newline at end of file
diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java
new file mode 100644
index 0000000000..ebb619c456
--- /dev/null
+++ b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java
@@ -0,0 +1,63 @@
+package org.baeldung.spring.data.cassandra.model;
+
+import org.springframework.cassandra.core.Ordering;
+import org.springframework.cassandra.core.PrimaryKeyType;
+import org.springframework.data.cassandra.mapping.Column;
+import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
+import org.springframework.data.cassandra.mapping.Table;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+@Table
+public class Book {
+ @PrimaryKeyColumn(name = "isbn", ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING)
+ private UUID id;
+ @PrimaryKeyColumn(name = "title", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
+ private String title;
+
+ @PrimaryKeyColumn(name = "publisher", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
+ private String publisher;
+ @Column
+ private Set tags = new HashSet<>();
+
+ public Book(UUID id, String title, String publisher, Set tags) {
+ this.id = id;
+ this.title = title;
+ this.publisher = publisher;
+ this.tags.addAll(tags);
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getPublisher() {
+ return publisher;
+ }
+
+ public Set getTags() {
+ return tags;
+ }
+
+ public void setId(UUID id) {
+ this.id = id;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setPublisher(String publisher) {
+ this.publisher = publisher;
+ }
+
+ public void setTags(Set tags) {
+ this.tags = tags;
+ }
+}
diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java
new file mode 100644
index 0000000000..e37ae78b59
--- /dev/null
+++ b/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java
@@ -0,0 +1,12 @@
+package org.baeldung.spring.data.cassandra.repository;
+
+import org.baeldung.spring.data.cassandra.model.Book;
+import org.springframework.data.cassandra.repository.CassandraRepository;
+import org.springframework.data.cassandra.repository.Query;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface BookRepository extends CassandraRepository {
+ @Query("select * from book where title = ?0 and publisher=?1")
+ Iterable findByTitleAndPublisher(String title, String publisher);
+}
diff --git a/spring-data-cassandra/src/main/resources/cassandra.properties b/spring-data-cassandra/src/main/resources/cassandra.properties
new file mode 100644
index 0000000000..1550cdea4e
--- /dev/null
+++ b/spring-data-cassandra/src/main/resources/cassandra.properties
@@ -0,0 +1,3 @@
+cassandra.contactpoints=127.0.0.1
+cassandra.port=9142
+cassandra.keyspace=testKeySpace
\ No newline at end of file
diff --git a/spring-data-cassandra/src/main/resources/logback.xml b/spring-data-cassandra/src/main/resources/logback.xml
new file mode 100644
index 0000000000..215eeede64
--- /dev/null
+++ b/spring-data-cassandra/src/main/resources/logback.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-data-cassandra/src/main/resources/test.png b/spring-data-cassandra/src/main/resources/test.png
new file mode 100644
index 0000000000..c3b5e80276
Binary files /dev/null and b/spring-data-cassandra/src/main/resources/test.png differ
diff --git a/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java b/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..2451f14f4a
--- /dev/null
+++ b/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java
@@ -0,0 +1,117 @@
+package org.baeldung.spring.data.cassandra.repository;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.utils.UUIDs;
+import com.google.common.collect.ImmutableSet;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.thrift.transport.TTransportException;
+import org.baeldung.spring.data.cassandra.config.CassandraConfig;
+import org.baeldung.spring.data.cassandra.model.Book;
+import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
+import org.junit.*;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.data.cassandra.core.CassandraAdminOperations;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = CassandraConfig.class)
+public class BookRepositoryIntegrationTest {
+
+ private static final Log LOGGER = LogFactory.getLog(BookRepositoryIntegrationTest.class);
+
+ public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };";
+
+ public static final String KEYSPACE_ACTIVATE_QUERY = "USE testKeySpace;";
+
+ public static final String DATA_TABLE_NAME = "book";
+
+ @Autowired
+ private BookRepository bookRepository;
+
+ @Autowired
+ private CassandraAdminOperations adminTemplate;
+
+ @BeforeClass
+ public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException {
+ EmbeddedCassandraServerHelper.startEmbeddedCassandra();
+ Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1")
+ .withPort(9142).build();
+ LOGGER.info("Server Started at 127.0.0.1:9142... ");
+ Session session = cluster.connect();
+ session.execute(KEYSPACE_CREATION_QUERY);
+ session.execute(KEYSPACE_ACTIVATE_QUERY);
+ LOGGER.info(session.execute("Select * from Book").all().toArray());
+ Thread.sleep(5000);
+ LOGGER.info("KeySpace created and activated.");
+ }
+
+ @Before
+ public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException {
+ adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap());
+ }
+
+ @Test
+ public void whenSavingBook_thenAvailableOnRetrieval() {
+ Book javaBook = new Book(UUIDs.timeBased(), "Head First Java",
+ "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
+ bookRepository.save(ImmutableSet.of(javaBook));
+ Iterable books = bookRepository.findByTitleAndPublisher("Head First Java", "O'Reilly Media");
+ assertEquals(javaBook.getId(), books.iterator().next().getId());
+ }
+
+ @Test
+ public void whenUpdatingBooks_thenAvailableOnRetrieval() {
+ Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
+ bookRepository.save(ImmutableSet.of(javaBook));
+ Iterable books = bookRepository.findByTitleAndPublisher("Head First Java", "O'Reilly Media");
+ javaBook.setTitle("Head First Java Second Edition");
+ bookRepository.save(ImmutableSet.of(javaBook));
+ Iterable updateBooks = bookRepository.findByTitleAndPublisher("Head First Java Second Edition", "O'Reilly Media");
+ assertEquals(javaBook.getTitle(), updateBooks.iterator().next().getTitle());
+ }
+
+ @Test(expected = java.util.NoSuchElementException.class)
+ public void whenDeletingExistingBooks_thenNotAvailableOnRetrieval() {
+ Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
+ bookRepository.save(ImmutableSet.of(javaBook));
+ bookRepository.delete(javaBook);
+ Iterable books = bookRepository.findByTitleAndPublisher("Head First Java", "O'Reilly Media");
+ assertNotEquals(javaBook.getId(), books.iterator().next().getId());
+ }
+
+ @Test
+ public void whenSavingBooks_thenAllShouldAvailableOnRetrieval() {
+ Book javaBook = new Book(UUIDs.timeBased(), "Head First Java",
+ "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
+ Book dPatternBook = new Book(UUIDs.timeBased(), "Head Design Patterns",
+ "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
+ bookRepository.save(ImmutableSet.of(javaBook));
+ bookRepository.save(ImmutableSet.of(dPatternBook));
+ Iterable books = bookRepository.findAll();
+ int bookCount = 0;
+ for (Book book : books) bookCount++;
+ assertEquals(bookCount, 2);
+ }
+
+ @After
+ public void dropTable() {
+ adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME));
+ }
+
+ @AfterClass
+ public static void stopCassandraEmbedded() {
+ EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
+ }
+}
diff --git a/spring-security-oauth/spring-security-oauth-server/src/main/java/org/baeldung/config/ServerSecurityConfig.java b/spring-security-oauth/spring-security-oauth-server/src/main/java/org/baeldung/config/ServerSecurityConfig.java
index 5a09bb7e03..3e1a8a8ccb 100644
--- a/spring-security-oauth/spring-security-oauth-server/src/main/java/org/baeldung/config/ServerSecurityConfig.java
+++ b/spring-security-oauth/spring-security-oauth-server/src/main/java/org/baeldung/config/ServerSecurityConfig.java
@@ -28,7 +28,7 @@ public class ServerSecurityConfig extends WebSecurityConfigurerAdapter {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
- // .and().formLogin().permitAll()
+ .and().formLogin().permitAll()
;
// @formatter:on
}
diff --git a/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/java/org/baeldung/config/UiWebConfig.java b/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/java/org/baeldung/config/UiWebConfig.java
index 2ee0585615..71197ce5d2 100644
--- a/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/java/org/baeldung/config/UiWebConfig.java
+++ b/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/java/org/baeldung/config/UiWebConfig.java
@@ -26,8 +26,9 @@ public class UiWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
- registry.addViewController("/index");
+ registry.addViewController("/").setViewName("forward:/index");
registry.addViewController("/oauthTemp");
+ registry.addViewController("/index");
}
@Override
diff --git a/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/resources/templates/header.html b/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/resources/templates/header.html
index f56ff0ce99..a62bce9747 100644
--- a/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/resources/templates/header.html
+++ b/spring-security-oauth/spring-security-oauth-ui-implicit/src/main/resources/templates/header.html
@@ -12,7 +12,7 @@
diff --git a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiWebConfig.java b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiWebConfig.java
index 46e7f6db42..0732182354 100644
--- a/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiWebConfig.java
+++ b/spring-security-oauth/spring-security-oauth-ui-password/src/main/java/org/baeldung/config/UiWebConfig.java
@@ -26,6 +26,7 @@ public class UiWebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
+ registry.addViewController("/").setViewName("forward:/index");
registry.addViewController("/index");
registry.addViewController("/login");
}