Skip to content

Commit 5c27cc6

Browse files
committed
Merge pull request eugenp#299 from sameira/master
Adding Cassandra Templates and CQL Queries tutorial code samples
2 parents bb61669 + d7d86a1 commit 5c27cc6

File tree

6 files changed

+285
-5
lines changed

6 files changed

+285
-5
lines changed

spring-data-cassandra/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Spring Data Cassandra
2+
3+
### Relevant Articles:
4+
- [Introduction to Spring Data Cassandra](http://www.baeldung.com/spring-data-cassandra-tutorial)
5+
6+
### Build the Project with Tests Running
7+
```
8+
mvn clean install
9+
```
10+
11+
### Run Tests Directly
12+
```
13+
mvn test
14+
```
15+

spring-data-cassandra/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<properties>
1313
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14-
<org.springframework.data.version>1.3.1.RELEASE</org.springframework.data.version>
14+
<org.springframework.data.version>1.3.2.RELEASE</org.springframework.data.version>
1515
<org.springframework.version>4.2.2.RELEASE</org.springframework.version>
1616
<junit.version>4.11</junit.version>
1717
<org.slf4j.version>1.7.12</org.slf4j.version>

spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212

1313
@Table
1414
public class Book {
15-
@PrimaryKeyColumn(name = "isbn", ordinal = 2, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING)
15+
@PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.CLUSTERED, ordering = Ordering.DESCENDING)
1616
private UUID id;
17-
@PrimaryKeyColumn(name = "title", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
17+
@PrimaryKeyColumn(name = "title", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
1818
private String title;
1919

20-
@PrimaryKeyColumn(name = "publisher", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
20+
@PrimaryKeyColumn(name = "publisher", ordinal = 2, type = PrimaryKeyType.PARTITIONED)
2121
private String publisher;
2222
@Column
2323
private Set<String> tags = new HashSet<>();

spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public static void startCassandraEmbedded() throws InterruptedException, TTransp
5252
Session session = cluster.connect();
5353
session.execute(KEYSPACE_CREATION_QUERY);
5454
session.execute(KEYSPACE_ACTIVATE_QUERY);
55-
Thread.sleep(5000);
5655
LOGGER.info("KeySpace created and activated.");
56+
Thread.sleep(5000);
5757
}
5858

5959
@Before
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package org.baeldung.spring.data.cassandra.repository;
2+
3+
import com.datastax.driver.core.Cluster;
4+
import com.datastax.driver.core.Session;
5+
import com.datastax.driver.core.querybuilder.Insert;
6+
import com.datastax.driver.core.querybuilder.QueryBuilder;
7+
import com.datastax.driver.core.querybuilder.Select;
8+
import com.datastax.driver.core.utils.UUIDs;
9+
import com.google.common.collect.ImmutableSet;
10+
import org.apache.cassandra.exceptions.ConfigurationException;
11+
import org.apache.commons.logging.Log;
12+
import org.apache.commons.logging.LogFactory;
13+
import org.apache.thrift.transport.TTransportException;
14+
import org.baeldung.spring.data.cassandra.config.CassandraConfig;
15+
import org.baeldung.spring.data.cassandra.model.Book;
16+
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
17+
import org.junit.*;
18+
import org.junit.runner.RunWith;
19+
import org.springframework.beans.factory.annotation.Autowired;
20+
import org.springframework.cassandra.core.cql.CqlIdentifier;
21+
import org.springframework.data.cassandra.core.CassandraAdminOperations;
22+
import org.springframework.data.cassandra.core.CassandraOperations;
23+
import org.springframework.test.context.ContextConfiguration;
24+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
25+
26+
import java.io.IOException;
27+
import java.util.ArrayList;
28+
import java.util.HashMap;
29+
import java.util.List;
30+
import java.util.UUID;
31+
32+
import static junit.framework.TestCase.assertEquals;
33+
34+
@RunWith(SpringJUnit4ClassRunner.class)
35+
@ContextConfiguration(classes = CassandraConfig.class)
36+
public class CQLQueriesIntegrationTest {
37+
38+
private static final Log LOGGER = LogFactory.getLog(CQLQueriesIntegrationTest.class);
39+
40+
public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace " + "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };";
41+
42+
public static final String KEYSPACE_ACTIVATE_QUERY = "USE testKeySpace;";
43+
44+
public static final String DATA_TABLE_NAME = "book";
45+
46+
@Autowired
47+
private CassandraAdminOperations adminTemplate;
48+
49+
@Autowired
50+
private CassandraOperations cassandraTemplate;
51+
52+
@BeforeClass
53+
public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException {
54+
EmbeddedCassandraServerHelper.startEmbeddedCassandra(25000);
55+
Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142).build();
56+
LOGGER.info("Server Started at 127.0.0.1:9142... ");
57+
Session session = cluster.connect();
58+
session.execute(KEYSPACE_CREATION_QUERY);
59+
session.execute(KEYSPACE_ACTIVATE_QUERY);
60+
LOGGER.info("KeySpace created and activated.");
61+
Thread.sleep(5000);
62+
}
63+
64+
@Before
65+
public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException {
66+
adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<String, Object>());
67+
}
68+
69+
@Test
70+
public void whenSavingBook_thenAvailableOnRetrieval_usingQueryBuilder() {
71+
UUID uuid = UUIDs.timeBased();
72+
Insert insert = QueryBuilder.insertInto(DATA_TABLE_NAME).value("id", uuid).value("title", "Head First Java").value("publisher", "OReilly Media").value("tags", ImmutableSet.of("Software"));
73+
cassandraTemplate.execute(insert);
74+
Select select = QueryBuilder.select().from("book").limit(10);
75+
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);
76+
assertEquals(uuid, retrievedBook.getId());
77+
}
78+
79+
@Test
80+
public void whenSavingBook_thenAvailableOnRetrieval_usingCQLStatements() {
81+
UUID uuid = UUIDs.timeBased();
82+
String insertCql = "insert into book (id, title, publisher, tags) values " + "(" + uuid + ", 'Head First Java', 'OReilly Media', {'Software'})";
83+
cassandraTemplate.execute(insertCql);
84+
Select select = QueryBuilder.select().from("book").limit(10);
85+
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);
86+
assertEquals(uuid, retrievedBook.getId());
87+
}
88+
89+
@Test
90+
public void whenSavingBook_thenAvailableOnRetrieval_usingPreparedStatements() throws InterruptedException {
91+
UUID uuid = UUIDs.timeBased();
92+
String insertPreparedCql = "insert into book (id, title, publisher, tags) values (?, ?, ?, ?)";
93+
List<Object> singleBookArgsList = new ArrayList<>();
94+
List<List<?>> bookList = new ArrayList<>();
95+
singleBookArgsList.add(uuid);
96+
singleBookArgsList.add("Head First Java");
97+
singleBookArgsList.add("OReilly Media");
98+
singleBookArgsList.add(ImmutableSet.of("Software"));
99+
bookList.add(singleBookArgsList);
100+
cassandraTemplate.ingest(insertPreparedCql, bookList);
101+
//This may not be required, just added to avoid any transient issues
102+
Thread.sleep(5000);
103+
Select select = QueryBuilder.select().from("book");
104+
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);
105+
assertEquals(uuid, retrievedBook.getId());
106+
}
107+
108+
@After
109+
public void dropTable() {
110+
adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME));
111+
}
112+
113+
@AfterClass
114+
public static void stopCassandraEmbedded() {
115+
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
116+
}
117+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package org.baeldung.spring.data.cassandra.repository;
2+
3+
import com.datastax.driver.core.Cluster;
4+
import com.datastax.driver.core.Session;
5+
import com.datastax.driver.core.querybuilder.QueryBuilder;
6+
import com.datastax.driver.core.querybuilder.Select;
7+
import com.datastax.driver.core.utils.UUIDs;
8+
import com.google.common.collect.ImmutableSet;
9+
import org.apache.cassandra.exceptions.ConfigurationException;
10+
import org.apache.commons.logging.Log;
11+
import org.apache.commons.logging.LogFactory;
12+
import org.apache.thrift.transport.TTransportException;
13+
import org.baeldung.spring.data.cassandra.config.CassandraConfig;
14+
import org.baeldung.spring.data.cassandra.model.Book;
15+
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
16+
import org.junit.*;
17+
import org.junit.runner.RunWith;
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.cassandra.core.cql.CqlIdentifier;
20+
import org.springframework.data.cassandra.core.CassandraAdminOperations;
21+
import org.springframework.data.cassandra.core.CassandraOperations;
22+
import org.springframework.test.context.ContextConfiguration;
23+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
24+
25+
import java.io.IOException;
26+
import java.util.ArrayList;
27+
import java.util.HashMap;
28+
import java.util.List;
29+
30+
import static junit.framework.TestCase.assertNull;
31+
import static org.hamcrest.CoreMatchers.is;
32+
import static org.junit.Assert.assertEquals;
33+
import static org.junit.Assert.assertThat;
34+
35+
@RunWith(SpringJUnit4ClassRunner.class)
36+
@ContextConfiguration(classes = CassandraConfig.class)
37+
public class CassandraTemplateIntegrationTest {
38+
39+
private static final Log LOGGER = LogFactory.getLog(CassandraTemplateIntegrationTest.class);
40+
41+
public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace " + "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };";
42+
43+
public static final String KEYSPACE_ACTIVATE_QUERY = "USE testKeySpace;";
44+
45+
public static final String DATA_TABLE_NAME = "book";
46+
47+
@Autowired
48+
private CassandraAdminOperations adminTemplate;
49+
50+
@Autowired
51+
private CassandraOperations cassandraTemplate;
52+
53+
@BeforeClass
54+
public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException {
55+
EmbeddedCassandraServerHelper.startEmbeddedCassandra();
56+
Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142).build();
57+
LOGGER.info("Server Started at 127.0.0.1:9142... ");
58+
Session session = cluster.connect();
59+
session.execute(KEYSPACE_CREATION_QUERY);
60+
session.execute(KEYSPACE_ACTIVATE_QUERY);
61+
LOGGER.info("KeySpace created and activated.");
62+
Thread.sleep(5000);
63+
}
64+
65+
@Before
66+
public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException {
67+
adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<String, Object>());
68+
}
69+
70+
@Test
71+
public void whenSavingBook_thenAvailableOnRetrieval() {
72+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
73+
cassandraTemplate.insert(javaBook);
74+
Select select = QueryBuilder.select().from("book").where(QueryBuilder.eq("title", "Head First Java")).and(QueryBuilder.eq("publisher", "O'Reilly Media")).limit(10);
75+
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);
76+
assertEquals(javaBook.getId(), retrievedBook.getId());
77+
}
78+
79+
@Test
80+
public void whenSavingBooks_thenAllAvailableOnRetrieval() {
81+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
82+
Book dPatternBook = new Book(UUIDs.timeBased(), "Head Design Patterns", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
83+
List<Book> bookList = new ArrayList<>();
84+
bookList.add(javaBook);
85+
bookList.add(dPatternBook);
86+
cassandraTemplate.insert(bookList);
87+
88+
Select select = QueryBuilder.select().from("book").limit(10);
89+
List<Book> retrievedBooks = cassandraTemplate.select(select, Book.class);
90+
assertThat(retrievedBooks.size(), is(2));
91+
assertEquals(javaBook.getId(), retrievedBooks.get(0).getId());
92+
assertEquals(dPatternBook.getId(), retrievedBooks.get(1).getId());
93+
}
94+
95+
@Test
96+
public void whenUpdatingBook_thenShouldUpdatedOnRetrieval() {
97+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
98+
cassandraTemplate.insert(javaBook);
99+
Select select = QueryBuilder.select().from("book").limit(10);
100+
Book retrievedBook = cassandraTemplate.selectOne(select, Book.class);
101+
retrievedBook.setTags(ImmutableSet.of("Java", "Programming"));
102+
cassandraTemplate.update(retrievedBook);
103+
Book retrievedUpdatedBook = cassandraTemplate.selectOne(select, Book.class);
104+
assertEquals(retrievedBook.getTags(), retrievedUpdatedBook.getTags());
105+
}
106+
107+
@Test
108+
public void whenDeletingASelectedBook_thenNotAvailableOnRetrieval() throws InterruptedException {
109+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "OReilly Media", ImmutableSet.of("Computer", "Software"));
110+
cassandraTemplate.insert(javaBook);
111+
cassandraTemplate.delete(javaBook);
112+
Select select = QueryBuilder.select().from("book").limit(10);
113+
Book retrievedUpdatedBook = cassandraTemplate.selectOne(select, Book.class);
114+
assertNull(retrievedUpdatedBook);
115+
}
116+
117+
@Test
118+
public void whenDeletingAllBooks_thenNotAvailableOnRetrieval() {
119+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
120+
Book dPatternBook = new Book(UUIDs.timeBased(), "Head Design Patterns", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
121+
cassandraTemplate.insert(javaBook);
122+
cassandraTemplate.insert(dPatternBook);
123+
cassandraTemplate.deleteAll(Book.class);
124+
Select select = QueryBuilder.select().from("book").limit(10);
125+
Book retrievedUpdatedBook = cassandraTemplate.selectOne(select, Book.class);
126+
assertNull(retrievedUpdatedBook);
127+
}
128+
129+
@Test
130+
public void whenAddingBooks_thenCountShouldBeCorrectOnRetrieval() {
131+
Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
132+
Book dPatternBook = new Book(UUIDs.timeBased(), "Head Design Patterns", "O'Reilly Media", ImmutableSet.of("Computer", "Software"));
133+
cassandraTemplate.insert(javaBook);
134+
cassandraTemplate.insert(dPatternBook);
135+
long bookCount = cassandraTemplate.count(Book.class);
136+
assertEquals(2, bookCount);
137+
}
138+
139+
@After
140+
public void dropTable() {
141+
adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME));
142+
}
143+
144+
@AfterClass
145+
public static void stopCassandraEmbedded() {
146+
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
147+
}
148+
}

0 commit comments

Comments
 (0)