Merge branch 'eugenp:master' into master

This commit is contained in:
Mladen Savic 2021-08-02 10:34:38 +02:00 committed by GitHub
commit fbe9fbf752
42 changed files with 1249 additions and 9 deletions

View File

@ -43,6 +43,12 @@
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Webclient -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>${spring-boot.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -0,0 +1,17 @@
package com.baeldung.httpclient.readresponsebodystring;
import org.junit.Test;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class SpringWebClientUnitTest {
public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test
public void whenUseWebClientRetrieve_thenCorrect() {
WebClient webClient = WebClient.create(DUMMY_URL);
Mono<String> body = webClient.get().retrieve().bodyToMono(String.class);
String s = body.block();
System.out.println(s);
}
}

View File

@ -123,9 +123,9 @@
<repositories> <repositories>
<!-- Needed for Renjin --> <!-- Needed for Renjin -->
<repository> <repository>
<id>bedatadriven</id> <id>mulesoft</id>
<name>bedatadriven public repo</name> <name>Mulesoft Repository</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url> <url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
</repository> </repository>
</repositories> </repositories>

View File

@ -29,6 +29,11 @@
<artifactId>commons-vfs2</artifactId> <artifactId>commons-vfs2</artifactId>
<version>${vfs.version}</version> <version>${vfs.version}</version>
</dependency> </dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>

View File

@ -0,0 +1,22 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
import java.util.Arrays;
public class CreateSplitZipFile {
public static void main(String[] args) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
int splitLength = 1024 * 1024 * 10; //10MB
zipFile.createSplitZipFile(Arrays.asList(new File("aFile.txt")), zipParameters, true, splitLength);
zipFile.createSplitZipFileFromFolder(new File("/users/folder_to_add"), zipParameters, true, splitLength);
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
public class ExtractAllFile {
public static void main(String[] args) throws ZipException {
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.extractAll("/destination_directory");
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
public class ExtractSingleFile {
public static void main(String[] args) throws ZipException {
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.extractFile("aFile.txt", "/destination_directory");
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
public class ZipFolder {
public static void main(String[] args) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.addFolder(new File("/users/folder_to_add"), zipParameters);
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class ZipMultiFile {
public static void main(String[] args) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
List<File> filesToAdd = Arrays.asList(
new File("aFile.txt"),
new File("bFile.txt")
);
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.java.io.zip4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import java.io.File;
public class ZipSingleFile {
public static void main(String[] args) throws ZipException {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setCompressionLevel(CompressionLevel.HIGHER);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.addFile(new File("aFile.txt"));
}
}

View File

@ -0,0 +1,108 @@
<?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>
<groupId>com.baeldung.maven.plugin</groupId>
<artifactId>host-maven-repo-example</artifactId>
<version>1.0-SNAPSHOT</version>
<url>https://github.com/sgrverma23/host-maven-repo-example.git</url>
<properties>
<github.global.server>github</github.global.server>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<scm>
<url>https://github.com/sgrverma23/host-maven-repo-example.git</url>
<connection>scm:git:git@github.com:sgrverma23/host-maven-repo-example.git</connection>
<developerConnection>scm:git:git@github.com:sgrverma23/host-maven-repo-example.git</developerConnection>
</scm>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/mvn-artifact</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.github</groupId>
<artifactId>site-maven-plugin</artifactId>
<version>0.12</version>
<configuration>
<message>Maven artifacts for ${project.version}</message>
<noJekyll>true</noJekyll>
<outputDirectory>${project.build.directory}</outputDirectory>
<branch>refs/heads/main</branch>
<includes>
<include>**/*</include>
</includes>
<merge>true</merge>
<repositoryName>host-maven-repo-example</repositoryName>
<repositoryOwner>sgrverma23</repositoryOwner>
<server>github</server>
</configuration>
<executions>
<execution>
<goals>
<goal>site</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<altDeploymentRepository>
internal.repo::default::file://${project.build.directory}/mvn-artifact
</altDeploymentRepository>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>PROJECT-REPO-URL</id>
<url>https://github.com/sgrverma23/host-maven-repo-example/main</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</project>

View File

@ -0,0 +1,7 @@
package com.baeldung.maven.plugin;
public class MainApp {
public static void main(String[] args){
System.out.println("Maven Repo Add");
}
}

View File

@ -33,6 +33,7 @@
<module>versions-maven-plugin</module> <module>versions-maven-plugin</module>
<module>maven-printing-plugins</module> <module>maven-printing-plugins</module>
<module>maven-builder-plugin</module> <module>maven-builder-plugin</module>
<module>host-maven-repo-example</module>
<module>plugin-management</module> <module>plugin-management</module>
</modules> </modules>

View File

@ -0,0 +1,24 @@
package com.baeldung.mvc_mvp.mvc;
public class MvcMainClass {
public static void main(String[] args) {
Product model = retrieveProductFromDatabase();
ProductView view = new ProductView();
model.setView(view);
model.showProduct();
ProductController controller = new ProductController(model);
controller.setName("SmartPhone");
model.showProduct();
}
private static Product retrieveProductFromDatabase() {
Product product = new Product();
product.setName("Mobile");
product.setDescription("New Brand");
product.setPrice(1000.0);
return product;
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.mvc_mvp.mvc;
public class Product {
private String name;
private String description;
private Double price;
private ProductView view;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public ProductView getView() {
return view;
}
public void setView(ProductView view) {
this.view = view;
}
public void showProduct() {
view.printProductDetails(name, description, price);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.mvc_mvp.mvc;
public class ProductController {
private final Product product;
public ProductController(Product product) {
this.product = product;
}
public String getName() {
return product.getName();
}
public void setName(String name) {
product.setName(name);
}
public String getDescription() {
return product.getDescription();
}
public void setDescription(String description) {
product.setDescription(description);
}
public Double getPrice() {
return product.getPrice();
}
public void setPrice(Double price) {
product.setPrice(price);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.mvc_mvp.mvc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ProductView {
private static Logger log = LoggerFactory.getLogger(ProductView.class);
public void printProductDetails(String name, String description, Double price) {
log.info("Product details:");
log.info("product Name: " + name);
log.info("product Description: " + description);
log.info("product price: " + price);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.mvc_mvp.mvp;
public class MvpMainClass {
public static void main(String[] args) {
Product model = retrieveProductFromDatabase();
ProductView view = new ProductView();
ProductPresenter presenter = new ProductPresenter(model, view);
presenter.showProduct();
presenter.setName("SmartPhone");
presenter.showProduct();
}
private static Product retrieveProductFromDatabase() {
Product product = new Product();
product.setName("Mobile");
product.setDescription("New Brand");
product.setPrice(1000.0);
return product;
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.mvc_mvp.mvp;
public class Product {
private String name;
private String description;
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.mvc_mvp.mvp;
public class ProductPresenter {
private final Product product;
private final ProductView view;
public ProductPresenter(Product product, ProductView view) {
this.product = product;
this.view = view;
}
public String getName() {
return product.getName();
}
public void setName(String name) {
product.setName(name);
}
public String getDescription() {
return product.getDescription();
}
public void setDescription(String description) {
product.setDescription(description);
}
public Double getProductPrice() {
return product.getPrice();
}
public void setPrice(Double price) {
product.setPrice(price);
}
public void showProduct() {
view.printProductDetails(product.getName(), product.getDescription(), product.getPrice());
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.mvc_mvp.mvp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ProductView {
private static Logger log = LoggerFactory.getLogger(ProductView.class);
public void printProductDetails(String name, String description, Double price) {
log.info("Product details:");
log.info("product Name: " + name);
log.info("product Description: " + description);
log.info("product price: " + price);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.jdbcautocommit;
public class Person {
private Integer id;
private String name;
private String lastName;
private Integer age;
public Person() {
}
public Person(Integer id, String name, String lastName, Integer age) {
this.id = id;
this.name = name;
this.lastName = lastName;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

View File

@ -0,0 +1,259 @@
package com.baeldung.jdbcautocommit;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class AutoCommitUnitTest {
private static final String INSERT_PERSON_SQL = "INSERT INTO Person VALUES (?,?,?,?)";
private static final String SELECT_ALL_PEOPLE_SQL = "SELECT * FROM Person";
private static final String UPDATE_PERSON_AGE_BY_ID_SQL = "UPDATE Person SET age = ? WHERE id = ?";
private static final String DELETE_ALL_PEOPLE_SQL = "DELETE FROM Person";
private static final String UPDATE_PERSON_AGE_BY_NAME_SQL
= "UPDATE Person SET age = ? WHERE id = (SELECT id FROM Person WHERE name = ?)";
private static final String CREATE_PERSON_TABLE_SQL
= "CREATE TABLE Person (id INTEGER not null, name VARCHAR(50), lastName VARCHAR(50), age INTEGER, PRIMARY KEY (id))";
private static Connection connection1;
private static Connection connection2;
@BeforeAll
static void setup() throws SQLException {
connection1 = DriverManager.getConnection("jdbc:h2:mem:autocommit", "sa", "");
createPersonTable(connection1);
connection2 = DriverManager.getConnection("jdbc:h2:mem:autocommit", "sa", "");
}
@Test
void givenAutoCommitTrue_whenInsertAndUpdateRecord_thenDataPersistedAfterEachWithoutCommit() throws SQLException {
connection1.setAutoCommit(true);
Person person = new Person(1, "John", "Doe", 45);
insertPerson(connection1, person);
// no explicit commit needed here when auto-commit true
// viewed from different connection, connection2 : assert person has been persisted into
// the database
List<Person> people = selectAllPeople(connection2);
assertThat("person record inserted OK into empty table", people.size(), is(equalTo(1)));
Person personInserted = people.iterator().next();
assertThat("id correct", personInserted.getId(), is(equalTo(1)));
// update age for person in database
updatePersonAgeById(connection1, 1, 65);
// no explicit commit needed here
// viewed from connection2 : assert person's age has been updated to database
people = selectAllPeople(connection2);
Person personUpdated = people.iterator().next();
assertThat("updated age correct", personUpdated.getAge(), is(equalTo(65)));
}
@Test
void givenAutoCommitFalse_whenInsertCommitAndUpdateCommit_thenDataViewableAfterEachCommit() throws SQLException {
connection1.setAutoCommit(false);
Person person = new Person(1, "John", "Doe", 45);
insertPerson(connection1, person);
// viewed from different connection, connection2 : assert that person has not yet been
// persisted to database before issuing commit
List<Person> people = selectAllPeople(connection2);
assertThat("No people have been inserted into database yet", people.size(), is(equalTo(0)));
connection1.commit();
// viewed from connection2 : assert that person has been persisted to database after
// issuing commit
people = selectAllPeople(connection2);
assertThat("Person has been inserted into empty table after commit", people.size(), is(equalTo(1)));
Person personInserted = people.iterator().next();
assertThat("id correct", personInserted.getId(), is(equalTo(1)));
updatePersonAgeById(connection1, 1, 65);
// assert that person's age has not been updated before issuing commit
people = selectAllPeople(connection2);
Person personUpdated = people.iterator().next();
assertThat("person's age still 45, not updated", personUpdated.getAge(), is(equalTo(45)));
connection1.commit();
// viewed from connection2 : assert that person's age has been updated after issuing commit
people = selectAllPeople(connection2);
personUpdated = people.iterator().next();
assertThat("person's age updated to 65", personUpdated.getAge(), is(equalTo(65)));
}
@Test
void givenAutoCommitFalse_whenInsertAndUpdateWithCommitOnlyAtEnd_thenDataOnlyViewableAfterCommit() throws SQLException {
connection1.setAutoCommit(false);
Person person = new Person(1, "John", "Doe", 45);
insertPerson(connection1, person);
// viewed from different connection, connection2 : assert that person has not yet been
// persisted to database before issuing commit
List<Person> people = selectAllPeople(connection2);
assertThat("No people have been inserted into database yet", people.size(), is(equalTo(0)));
updatePersonAgeById(connection1, 1, 65);
// viewed from connection2 : assert that person has still not yet been
// persisted to database before issuing commit
people = selectAllPeople(connection2);
assertThat("No people have been inserted into database yet", people.size(), is(equalTo(0)));
connection1.commit();
// viewed from connection2 : assert that person record has been persisted to
// database and person's age has been updated after issuing commit
people = selectAllPeople(connection2);
Person personUpdated = people.iterator().next();
assertThat("person's age updated to 65", personUpdated.getAge(), is(equalTo(65)));
}
@Test
void givenAutoCommitTrue_whenUpdateWithNestedSelect_thenUpdatePersistedWithoutCommit() throws SQLException {
connection1.setAutoCommit(true);
Person person = new Person(1, "John", "Doe", 45);
insertPerson(connection1, person);
updatePersonAgeByName(connection1, "John", 77);
// viewed from connection2 : assert person's age has been updated correctly to database
// without issuing commit
List<Person> people = selectAllPeople(connection2);
Person personUpdated = people.iterator().next();
assertThat("updated age correct", personUpdated.getAge(), is(equalTo(77)));
}
@Test
void givenAutoCommitFalse_whenModeChangedToTrueAfterSQLUpdate_thenUpdatePersistedWithoutCommit() throws SQLException {
connection1.setAutoCommit(false);
Person person = new Person(1, "John", "Doe", 45);
insertPerson(connection1, person);
updatePersonAgeByName(connection1, "John", 77);
connection1.setAutoCommit(true);
// viewed from connection2 : assert record inserted and person's age has been updated
// correctly to database after auto-commit changed false -> true ... without explicit commit needed
List<Person> people = selectAllPeople(connection2);
Person personUpdated = people.iterator().next();
assertThat("updated age correct", personUpdated.getAge(), is(equalTo(77)));
}
@AfterEach
void deleteAllRecords() throws SQLException {
if (connection1.getAutoCommit() == false) {
connection1.setAutoCommit(true);
}
deleteAllPeople(connection1);
}
@AfterAll
static void closeConnections() throws SQLException {
connection1.close();
connection2.close();
}
private static void createPersonTable(Connection connection) throws SQLException {
try(Statement statement = connection.createStatement()) {
statement.executeUpdate(CREATE_PERSON_TABLE_SQL);
}
}
private static int insertPerson(Connection connection, Person person) throws SQLException {
try (PreparedStatement preparedStatement = connection.prepareStatement(INSERT_PERSON_SQL)) {
preparedStatement.setInt(1, person.getId());
preparedStatement.setString(2, person.getName());
preparedStatement.setString(3, person.getLastName());
preparedStatement.setInt(4, person.getAge());
// execute statement and return the number of rows inserted
return preparedStatement.executeUpdate();
}
}
private static void deleteAllPeople(Connection connection) throws SQLException {
try (Statement statement = connection.createStatement()) {
statement.execute(DELETE_ALL_PEOPLE_SQL);
}
}
private static List<Person> selectAllPeople(Connection connection) throws SQLException {
List<Person> people = null;
try (Statement statement = connection.createStatement()) {
people = new ArrayList<>();
ResultSet resultSet = statement.executeQuery(SELECT_ALL_PEOPLE_SQL);
while (resultSet.next()) {
Person person = new Person();
person.setId(resultSet.getInt("id"));
person.setName(resultSet.getString("name"));
person.setLastName(resultSet.getString("lastName"));
person.setAge(resultSet.getInt("age"));
people.add(person);
}
}
return people;
}
private static void updatePersonAgeById(Connection connection, int id, int newAge) throws SQLException {
try (PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_PERSON_AGE_BY_ID_SQL)) {
preparedStatement.setInt(1, newAge);
preparedStatement.setInt(2, id);
preparedStatement.executeUpdate();
}
}
private static void updatePersonAgeByName(Connection connection, String name, int newAge) throws SQLException {
try (PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_PERSON_AGE_BY_NAME_SQL)) {
preparedStatement.setInt(1, newAge);
preparedStatement.setString(2, name);
preparedStatement.executeUpdate();
}
}
}

View File

@ -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>
@ -87,7 +88,7 @@
<module>spring-jpa-2</module> <module>spring-jpa-2</module>
<module>spring-jdbc</module> <module>spring-jdbc</module>
<module>spring-jooq</module> <module>spring-jooq</module>
<!-- <module>spring-mybatis</module> --> <!-- needs fixing in BAEL-9021 --> <module>spring-mybatis</module>
<module>spring-persistence-simple</module> <module>spring-persistence-simple</module>
</modules> </modules>

View 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
```

View 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>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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";
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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');

View File

@ -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:

View File

@ -84,7 +84,7 @@
<properties> <properties>
<!-- Spring --> <!-- Spring -->
<org.springframework.version>5.1.8.RELEASE</org.springframework.version> <org.springframework.version>5.3.8</org.springframework.version>
<!-- persistence --> <!-- persistence -->
<spring-mybatis.version>2.0.2</spring-mybatis.version> <spring-mybatis.version>2.0.2</spring-mybatis.version>
<mybatis.version>3.5.2</mybatis.version> <mybatis.version>3.5.2</mybatis.version>

View File

@ -8,6 +8,6 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest
@ContextConfiguration(classes = PersistenceAutoConfig.class) @ContextConfiguration(classes = PersistenceAutoConfig.class)
public class ArticleMapperBootIntegrationTest extends ArticleMapperCommonTest { public class ArticleMapperBootUnitTest extends ArticleMapperCommonUnitTest {
} }

View File

@ -5,7 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class ArticleMapperCommonTest { class ArticleMapperCommonUnitTest {
@Autowired @Autowired
ArticleMapper articleMapper; ArticleMapper articleMapper;

View File

@ -6,6 +6,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = PersistenceConfig.class) @ContextConfiguration(classes = PersistenceConfig.class)
public class ArticleMapperIntegrationTest extends ArticleMapperCommonTest { public class ArticleMapperUnitTest extends ArticleMapperCommonUnitTest {
} }

View File

@ -6,6 +6,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/beans.xml") @ContextConfiguration(locations = "classpath:/beans.xml")
public class ArticleMapperXMLIntegrationTest extends ArticleMapperCommonTest { public class ArticleMapperXMLUnitTest extends ArticleMapperCommonUnitTest {
} }