Bael-5023 data cassandra test (#11082)
* Example implementation of Hexagonal Architecture pattern * Example Cassandra Springboot application demonstrating the usage of @DataCassandraTest annotation * Example Cassandra Springboot application demonstrating the usage of @DataCassandraTest annotation * temporarily ignoring the unit test * removed ddd-hexagonal-arch module * changed the test to LiveTest added readme * refactored test names * changes per review comments * upgraded Cassandra java core driver versino Co-authored-by: Suresh Raghavan <contactnrsuresh@gmail.com>
This commit is contained in:
parent
4f7a1b58d7
commit
d36b90a1d0
@ -58,6 +58,7 @@
|
|||||||
<module>spring-boot-persistence-h2</module>
|
<module>spring-boot-persistence-h2</module>
|
||||||
<module>spring-boot-persistence-mongodb</module>
|
<module>spring-boot-persistence-mongodb</module>
|
||||||
<module>spring-data-cassandra</module>
|
<module>spring-data-cassandra</module>
|
||||||
|
<module>spring-data-cassandra-test</module>
|
||||||
<module>spring-data-cassandra-reactive</module>
|
<module>spring-data-cassandra-reactive</module>
|
||||||
<module>spring-data-cosmosdb</module>
|
<module>spring-data-cosmosdb</module>
|
||||||
<module>spring-data-couchbase-2</module>
|
<module>spring-data-couchbase-2</module>
|
||||||
|
16
persistence-modules/spring-data-cassandra-test/README.md
Normal file
16
persistence-modules/spring-data-cassandra-test/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
## Spring @DataCassandraTest
|
||||||
|
|
||||||
|
### Build the Project
|
||||||
|
```
|
||||||
|
mvn clean install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prerequisite To Run Test
|
||||||
|
- Docker Engine must be running on the system
|
||||||
|
- Docker Compose must be installed
|
||||||
|
|
||||||
|
### Run Tests Directly
|
||||||
|
```
|
||||||
|
mvn test
|
||||||
|
```
|
||||||
|
|
77
persistence-modules/spring-data-cassandra-test/pom.xml
Normal file
77
persistence-modules/spring-data-cassandra-test/pom.xml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>spring-data-cassandra-test</artifactId>
|
||||||
|
<name>spring-data-cassandra-test</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-boot-starter-data-cassandra.version>2.5.3</spring-boot-starter-data-cassandra.version>
|
||||||
|
<lombok.version>1.18.18</lombok.version>
|
||||||
|
<java-driver-core.version>4.13.0</java-driver-core.version>
|
||||||
|
<cassandra-unit-spring.version>4.3.1.0</cassandra-unit-spring.version>
|
||||||
|
<testcontainers.version>1.15.3</testcontainers.version>
|
||||||
|
<native-protocol.version>1.5.0</native-protocol.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-cassandra</artifactId>
|
||||||
|
<version>${spring-boot-starter-data-cassandra.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.oss</groupId>
|
||||||
|
<artifactId>java-driver-core</artifactId>
|
||||||
|
<version>${java-driver-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.oss</groupId>
|
||||||
|
<artifactId>native-protocol</artifactId>
|
||||||
|
<version>${native-protocol.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>testcontainers</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>cassandra</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CassandraDataTestApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CassandraDataTestApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.api;
|
||||||
|
|
||||||
|
import com.baeldung.spring.data.cassandra.test.domain.Vehicle;
|
||||||
|
import com.baeldung.spring.data.cassandra.test.service.InventoryService;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/v1/api/inventory")
|
||||||
|
public class InventoryController {
|
||||||
|
private InventoryService inventoryService;
|
||||||
|
|
||||||
|
public InventoryController(InventoryService inventoryService) {
|
||||||
|
this.inventoryService = inventoryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/vehicles")
|
||||||
|
public List<Vehicle> getVehicles() {
|
||||||
|
return this.inventoryService.getVehicles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/vehicles")
|
||||||
|
public void addVehicles(@RequestBody List<Vehicle> vehicles) {
|
||||||
|
this.inventoryService.addVehicles(vehicles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/vehicles")
|
||||||
|
public void updateVehicles(@RequestBody List<Vehicle> vehicles) {
|
||||||
|
this.inventoryService.updateVehicles(vehicles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/vehicles/{vin}")
|
||||||
|
public void updateVehicles(@PathVariable(name = "vin") String vin,
|
||||||
|
@RequestBody Vehicle vehicles) {
|
||||||
|
this.inventoryService.updateVehicle(vin, vehicles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/vehicles/{vin}")
|
||||||
|
public void removeVehicle(@PathVariable(name = "vin") String vin) {
|
||||||
|
this.inventoryService.deleteVehicle(vin);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CassandraConfig extends AbstractCassandraConfiguration {
|
||||||
|
@Override
|
||||||
|
protected String getKeyspaceName() {
|
||||||
|
return "inventory";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContactPoints() {
|
||||||
|
return "localhost";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getLocalDataCenter() {
|
||||||
|
return "datacenter1";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.cassandra.core.mapping.Table;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Table("vehicles")
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Vehicle {
|
||||||
|
@Id
|
||||||
|
private String vin;
|
||||||
|
private Integer year;
|
||||||
|
private String make;
|
||||||
|
private String model;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.repository;
|
||||||
|
|
||||||
|
import com.baeldung.spring.data.cassandra.test.domain.Vehicle;
|
||||||
|
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||||
|
import org.springframework.data.cassandra.repository.Consistency;
|
||||||
|
import org.springframework.data.cassandra.repository.Query;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface InventoryRepository extends CrudRepository<Vehicle, String> {
|
||||||
|
|
||||||
|
@Query("select * from vehicles")
|
||||||
|
@Consistency(DefaultConsistencyLevel.LOCAL_QUORUM)
|
||||||
|
List<Vehicle> findAllVehicles();
|
||||||
|
|
||||||
|
@Consistency(DefaultConsistencyLevel.LOCAL_QUORUM)
|
||||||
|
Optional<Vehicle> findByVin(@Param("vin") String vin);
|
||||||
|
|
||||||
|
@Consistency(DefaultConsistencyLevel.LOCAL_QUORUM)
|
||||||
|
void deleteByVin(String vin);
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.service;
|
||||||
|
|
||||||
|
import com.baeldung.spring.data.cassandra.test.domain.Vehicle;
|
||||||
|
import com.baeldung.spring.data.cassandra.test.repository.InventoryRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class InventoryService {
|
||||||
|
private final InventoryRepository inventoryRepository;
|
||||||
|
|
||||||
|
public InventoryService(InventoryRepository inventoryRepository) {
|
||||||
|
this.inventoryRepository = inventoryRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Vehicle> getVehicles() {
|
||||||
|
return this.inventoryRepository.findAllVehicles();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vehicle getVehicle(String vin) {
|
||||||
|
return this.inventoryRepository.findByVin(vin).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addVehicles(List<Vehicle> vehicles) {
|
||||||
|
this.inventoryRepository.saveAll(vehicles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateVehicles(List<Vehicle> vehicles) {
|
||||||
|
this.inventoryRepository.saveAll(vehicles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateVehicle(String vin, Vehicle vehicle) {
|
||||||
|
Vehicle existingVehicle = this.inventoryRepository.findByVin(vin)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Vehicle not found"));
|
||||||
|
|
||||||
|
existingVehicle.setMake(vehicle.getMake());
|
||||||
|
existingVehicle.setYear(vehicle.getYear());
|
||||||
|
existingVehicle.setModel(vehicle.getModel());
|
||||||
|
|
||||||
|
this.inventoryRepository.save(existingVehicle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteVehicle(String vin) {
|
||||||
|
this.inventoryRepository.deleteByVin(vin);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
<logger name="org.testcontainers" level="INFO" additivity="false">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
</logger>
|
||||||
|
</configuration>
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.baeldung.spring.data.cassandra.test.service;
|
||||||
|
|
||||||
|
import com.baeldung.spring.data.cassandra.test.config.CassandraConfig;
|
||||||
|
import com.baeldung.spring.data.cassandra.test.domain.Vehicle;
|
||||||
|
import com.baeldung.spring.data.cassandra.test.repository.InventoryRepository;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.testcontainers.containers.DockerComposeContainer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@DataCassandraTest
|
||||||
|
@Import(CassandraConfig.class)
|
||||||
|
public class InventoryServiceLiveTest {
|
||||||
|
@Autowired
|
||||||
|
private InventoryRepository repository;
|
||||||
|
|
||||||
|
private InventoryService inventoryService;
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static DockerComposeContainer environment =
|
||||||
|
new DockerComposeContainer(new File("src/test/resources/compose-test.yml"));
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
inventoryService = new InventoryService(this.repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenVehiclesInDBInitially_whenRetrieved_thenReturnAllVehiclesFromDB() {
|
||||||
|
List<Vehicle> vehicles = inventoryService.getVehicles();
|
||||||
|
assertThat(vehicles).isNotNull();
|
||||||
|
assertThat(vehicles).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddMoreVehiclesToDB_thenRetrievalReturnsAllVehicles() {
|
||||||
|
String vin1 = "ABC123";
|
||||||
|
String vin2 = "XYZ123";
|
||||||
|
List<Vehicle> vehicles = Arrays.asList(
|
||||||
|
new Vehicle(vin1, 2020, "Toyota", "Camry"),
|
||||||
|
new Vehicle(vin2, 2019, "Honda", "Prius")
|
||||||
|
);
|
||||||
|
inventoryService.addVehicles(vehicles);
|
||||||
|
|
||||||
|
vehicles = inventoryService.getVehicles();
|
||||||
|
assertThat(vehicles).isNotNull();
|
||||||
|
assertThat(vehicles).isNotEmpty();
|
||||||
|
assertThat(vehicles.size()).isEqualTo(5);
|
||||||
|
|
||||||
|
Vehicle vehicle = inventoryService.getVehicle(vin1);
|
||||||
|
assertThat(vehicle).isNotNull();
|
||||||
|
assertThat(vehicle.getVin()).isEqualTo(vin1);
|
||||||
|
|
||||||
|
vehicle = inventoryService.getVehicle(vin2);
|
||||||
|
assertThat(vehicle).isNotNull();
|
||||||
|
assertThat(vehicle.getVin()).isEqualTo(vin2);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
CREATE KEYSPACE inventory
|
||||||
|
WITH replication = {
|
||||||
|
'class' : 'NetworkTopologyStrategy',
|
||||||
|
'datacenter1' : 3
|
||||||
|
};
|
||||||
|
|
||||||
|
use inventory;
|
||||||
|
|
||||||
|
CREATE TABLE vehicles (
|
||||||
|
vin text PRIMARY KEY,
|
||||||
|
year int,
|
||||||
|
make varchar,
|
||||||
|
model varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
consistency LOCAL_QUORUM;
|
||||||
|
|
||||||
|
insert into vehicles (vin, year, make, model) values ('387KSJHFK23874GH', 2020, 'Ford', 'F-150');
|
||||||
|
insert into vehicles (vin, year, make, model) values ('534HNDHFK23873EF', 2020, 'Honda', 'Accord');
|
||||||
|
insert into vehicles (vin, year, make, model) values ('953TOYJEK23853DB', 2020, 'Toyota', 'Camry');
|
@ -0,0 +1,79 @@
|
|||||||
|
version: '2.1'
|
||||||
|
services:
|
||||||
|
cassandra1:
|
||||||
|
image: cassandra:3.11.10
|
||||||
|
hostname: cassandra1
|
||||||
|
networks:
|
||||||
|
- cassandranet
|
||||||
|
ports:
|
||||||
|
- "9042:9042"
|
||||||
|
environment:
|
||||||
|
CASSANDRA_SEEDS: "cassandra1"
|
||||||
|
CASSANDRA_DC: datacenter1
|
||||||
|
CASSANDRA_RACK: rack1
|
||||||
|
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces" ]
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
cassandra2:
|
||||||
|
image: cassandra:3.11.10
|
||||||
|
hostname: cassandra2
|
||||||
|
networks:
|
||||||
|
- cassandranet
|
||||||
|
depends_on:
|
||||||
|
cassandra1:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "9043:9042"
|
||||||
|
environment:
|
||||||
|
CASSANDRA_SEEDS: "cassandra1"
|
||||||
|
CASSANDRA_DC: datacenter1
|
||||||
|
CASSANDRA_RACK: rack1
|
||||||
|
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces" ]
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
cassandra3:
|
||||||
|
image: cassandra:3.11.10
|
||||||
|
hostname: cassandra3
|
||||||
|
networks:
|
||||||
|
- cassandranet
|
||||||
|
depends_on:
|
||||||
|
cassandra2:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "9044:9042"
|
||||||
|
environment:
|
||||||
|
CASSANDRA_SEEDS: "cassandra1"
|
||||||
|
CASSANDRA_DC: datacenter1
|
||||||
|
CASSANDRA_RACK: rack1
|
||||||
|
CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces" ]
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
cassandra-load-keyspace:
|
||||||
|
image: cassandra:3.11.10
|
||||||
|
networks:
|
||||||
|
- cassandranet
|
||||||
|
depends_on:
|
||||||
|
cassandra1:
|
||||||
|
condition: service_healthy
|
||||||
|
cassandra2:
|
||||||
|
condition: service_healthy
|
||||||
|
cassandra3:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ./bootstrap-test.cql:/schema.cql
|
||||||
|
command: /bin/bash -c "echo loading cassandra keyspace && cqlsh cassandra1 -f /schema.cql"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
cassandranet:
|
Loading…
x
Reference in New Issue
Block a user