Merge remote-tracking branch 'baeldung/master' into BAEL-4288#flyway-repair

This commit is contained in:
Adrian Maghear 2020-07-17 15:28:06 +02:00
commit dcd3e80ac5
62 changed files with 1229 additions and 86 deletions

View File

@ -13,4 +13,4 @@ This module contains articles about core Java input and output (IO)
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
- [Java IO vs NIO](https://www.baeldung.com/java-io-vs-nio)
- [[<-- Prev]](/core-java-modules/core-java-io)
- [[<-- Prev]](/core-java-modules/core-java-io)[[More -->]](/core-java-modules/core-java-io-3)

View File

@ -0,0 +1,7 @@
## Core Java IO
This module contains articles about core Java input and output (IO)
### Relevant Articles:
- [Java Create a File](https://www.baeldung.com/java-how-to-create-a-file)
- [[<-- Prev]](/core-java-modules/core-java-io-2)

View File

@ -0,0 +1,86 @@
<?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>core-java-io-3</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-io-3</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<!-- utils -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- utils -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.tomakehurst/wiremock -->
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>${wiremock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-io-3</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<assertj.version>3.6.1</assertj.version>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<wiremock.version>2.26.3</wiremock.version>
</properties>
</project>

View File

@ -0,0 +1,50 @@
package com.baeldung.createfile;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class CreateFileUnitTest {
private final String FILE_NAME = "src/test/resources/fileToCreate.txt";
@AfterEach
@BeforeEach
public void cleanUpFiles() {
File targetFile = new File(FILE_NAME);
targetFile.delete();
}
@Test
public void givenUsingNio_whenCreatingFile_thenCorrect() throws IOException {
Path newFilePath = Paths.get(FILE_NAME);
Files.createFile(newFilePath);
}
@Test
public void givenUsingFile_whenCreatingFile_thenCorrect() throws IOException {
File newFile = new File(FILE_NAME);
boolean success = newFile.createNewFile();
assertTrue(success);
}
@Test
public void givenUsingGuava_whenCreatingFile_thenCorrect() throws IOException {
com.google.common.io.Files.touch(new File(FILE_NAME));
}
@Test
public void givenUsingCommonsIo_whenCreatingFile_thenCorrect() throws IOException {
FileUtils.touch(new File(FILE_NAME));
}
}

View File

@ -39,4 +39,4 @@
<assertj.version>3.12.2</assertj.version>
</properties>
</project>
</project>

View File

@ -0,0 +1,23 @@
package com.baeldung.staticvariables;
public class StaticVariableDemo {
public static int i;
public static int j = 20;
public static int z;
static {
z = 30;
a = 40;
}
public static int a = 50;
public static final int b = 100;
public StaticVariableDemo() {
}
static class Nested {
public static String nestedClassStaticVariable = "test";
}
}

View File

@ -0,0 +1,113 @@
package com.baeldung.staticvariables;
import static org.assertj.core.api.Assertions.assertThat;
import java.lang.reflect.Field;
import org.junit.jupiter.api.Test;
public class StaticVariableUnitTest {
@Test
public void initializeStaticVariable_checkAssignedValues() {
try {
Class<?> staticVariableDemo = this.getClass()
.getClassLoader()
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
Field field1 = staticVariableDemo.getField("i");
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(0);
Field field2 = staticVariableDemo.getField("j");
assertThat(field2.getInt(staticVariableDemo)).isEqualTo(20);
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Test
public void initializeStaticVariable_checkStaticBlock() {
try {
Class<?> staticVariableDemo = this.getClass()
.getClassLoader()
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
Field field1 = staticVariableDemo.getField("z");
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(30);
Field field2 = staticVariableDemo.getField("a");
assertThat(field2.getInt(staticVariableDemo)).isEqualTo(50);
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Test
public void initializeStaticVariable_checkFinalValues() {
try {
Class<?> staticVariableDemo = this.getClass()
.getClassLoader()
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
Field field1 = staticVariableDemo.getField("b");
assertThat(field1.getInt(staticVariableDemo)).isEqualTo(100);
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Test
public void initializeStaticVariable_checkInnerClassValues() {
try {
Class<?> staticVariableDemo = this.getClass()
.getClassLoader()
.loadClass("com.baeldung.staticvariables.StaticVariableDemo");
Class<?>[] nestedClasses = staticVariableDemo.getClasses();
for (Class<?> nestedClass : nestedClasses) {
if (nestedClass.getName()
.equals("Nested")) {
Field field1 = nestedClass.getField("nestedClassStaticVariable");
assertThat(field1.get(nestedClass)).isEqualTo("test");
}
}
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

View File

@ -72,6 +72,7 @@
<module>core-java-io</module>
<module>core-java-io-2</module>
<module>core-java-io-3</module>
<module>core-java-io-apis</module>
<module>core-java-io-conversions</module>
<module>core-java-io-conversions-2</module>

View File

@ -0,0 +1,46 @@
package com.baeldung.ddd.order.config;
import org.bson.Document;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import java.math.BigDecimal;
import java.util.Collections;
@Configuration
public class CustomMongoConfiguration {
@Bean
public MongoCustomConversions customConversions() {
return new MongoCustomConversions(Collections.singletonList(DocumentToMoneyConverter.INSTANCE));
}
@ReadingConverter
enum DocumentToMoneyConverter implements Converter<Document, Money> {
INSTANCE;
@Override
public Money convert(Document source) {
Document money = source.get("money", Document.class);
return Money.of(getCurrency(money), getAmount(money));
}
private CurrencyUnit getCurrency(Document money) {
Document currency = money.get("currency", Document.class);
String currencyCode = currency.getString("code");
return CurrencyUnit.of(currencyCode);
}
private BigDecimal getAmount(Document money) {
String amount = money.getString("amount");
return BigDecimal.valueOf(Double.parseDouble(amount));
}
}
}

View File

@ -1,19 +1,24 @@
package com.baeldung.ddd.order.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import java.math.BigDecimal;
import java.util.Arrays;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.math.BigDecimal;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
/*
To run this test we need to run the databases first.
A dedicated docker-compose.yml file is located under the resources directory.
We can run it by simple executing `docker-compose up`.
*/
@SpringJUnitConfig
@SpringBootTest
public class PersistOrderIntegrationTest {
public class PersistOrderLiveTest {
@Autowired
private JpaOrderRepository repository;

View File

@ -17,9 +17,14 @@ import com.baeldung.ddd.order.Order;
import com.baeldung.ddd.order.OrderLine;
import com.baeldung.ddd.order.Product;
/*
To run this test we need to run the databases first.
A dedicated docker-compose.yml file is located under the resources directory.
We can run it by simple executing `docker-compose up`.
*/
@SpringJUnitConfig
@SpringBootTest
public class OrderMongoIntegrationTest {
public class OrderMongoLiveTest {
@Autowired
private OrderMongoRepository repo;

View File

@ -18,10 +18,15 @@ import com.baeldung.dddhexagonalspring.domain.Product;
import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository;
import com.baeldung.dddhexagonalspring.infrastracture.repository.cassandra.SpringDataCassandraOrderRepository;
/*
To run this test we need to run the databases first.
A dedicated docker-compose.yml file is located under the resources directory.
We can run it by simple executing `docker-compose up`.
*/
@SpringJUnitConfig
@SpringBootTest
@TestPropertySource("classpath:ddd-layers-test.properties")
class CassandraDbOrderRepositoryIntegrationTest {
class CassandraDbOrderRepositoryLiveTest {
@Autowired
private SpringDataCassandraOrderRepository cassandraOrderRepository;

View File

@ -18,10 +18,15 @@ import com.baeldung.dddhexagonalspring.domain.Product;
import com.baeldung.dddhexagonalspring.domain.repository.OrderRepository;
import com.baeldung.dddhexagonalspring.infrastracture.repository.mongo.SpringDataMongoOrderRepository;
/*
To run this test we need to run the databases first.
A dedicated docker-compose.yml file is located under the resources directory.
We can run it by simple executing `docker-compose up`.
*/
@SpringJUnitConfig
@SpringBootTest
@TestPropertySource("classpath:ddd-layers-test.properties")
class MongoDbOrderRepositoryIntegrationTest {
class MongoDbOrderRepositoryLiveTest {
@Autowired
private SpringDataMongoOrderRepository mongoOrderRepository;

View File

@ -15,4 +15,5 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
- [A Guide to the Reflections Library](https://www.baeldung.com/reflections-library)
- [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once)
- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack)
- [Java-R Integration](https://www.baeldung.com/java-r-integration)
- More articles [[<-- prev]](/libraries-5)

View File

@ -92,8 +92,50 @@
<version>${commonsio.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>Rserve</artifactId>
<version>${rserve.version}</version>
</dependency>
<dependency>
<groupId>com.github.jbytecode</groupId>
<artifactId>RCaller</artifactId>
<version>${rcaller.version}</version>
</dependency>
<dependency>
<groupId>org.renjin</groupId>
<artifactId>renjin-script-engine</artifactId>
<version>${renjin.version}</version>
</dependency>
</dependencies>
<repositories>
<!-- Needed for Renjin -->
<repository>
<id>bedatadriven</id>
<name>bedatadriven public repo</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- Excludes FastR classes from compilations since they require GraalVM -->
<excludes>
<exclude>com/baeldung/r/FastRMean.java</exclude>
</excludes>
<testExcludes>
<exclude>com/baeldung/r/FastRMeanUnitTest.java</exclude>
</testExcludes>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<kafka.version>2.0.0</kafka.version>
<javapoet.version>1.10.0</javapoet.version>
@ -105,6 +147,9 @@
<commons-net.version>3.6</commons-net.version>
<assertj.version>3.6.2</assertj.version>
<commonsio.version>2.6</commonsio.version>
<renjin.version>RELEASE</renjin.version>
<rcaller.version>3.0</rcaller.version>
<rserve.version>1.8.1</rserve.version>
</properties>

View File

@ -1,8 +1,5 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* FastR showcase.
*

View File

@ -1,12 +1,12 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import com.github.rcaller.rstuff.RCaller;
import com.github.rcaller.rstuff.RCallerOptions;
import com.github.rcaller.rstuff.RCode;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* RCaller showcase.
*

View File

@ -1,13 +1,12 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.script.ScriptException;
import org.renjin.script.RenjinScriptEngine;
import org.renjin.sexp.DoubleArrayVector;
import javax.script.ScriptException;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* Renjin showcase.
*

View File

@ -1,14 +1,13 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.script.ScriptException;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import javax.script.ScriptException;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* Test for {@link RCallerMean}.
*

View File

@ -1,13 +1,11 @@
package com.baeldung.r;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.script.ScriptException;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Assert;
import javax.script.ScriptException;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* Test for {@link RenjinMean}.

View File

@ -8,10 +8,8 @@ This module contains articles about libraries for data processing in Java.
- [Introduction to Conflict-Free Replicated Data Types](https://www.baeldung.com/java-conflict-free-replicated-data-types)
- [Introduction to javax.measure](https://www.baeldung.com/javax-measure)
- [A Guide to Infinispan in Java](https://www.baeldung.com/infinispan)
- [Guide to JMapper](https://www.baeldung.com/jmapper)
- [An Introduction to SuanShu](https://www.baeldung.com/suanshu)
- [Intro to Derive4J](https://www.baeldung.com/derive4j)
- [Java-R Integration](https://www.baeldung.com/java-r-integration)
- [Univocity Parsers](https://www.baeldung.com/java-univocity-parsers)
- [Using Kafka MockConsumer](https://www.baeldung.com/kafka-mockconsumer)
- [Using Kafka MockProducer](https://www.baeldung.com/kafka-mockproducer)

View File

@ -86,11 +86,6 @@
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.jmapper-framework</groupId>
<artifactId>jmapper-core</artifactId>
<version>${jmapper.version}</version>
</dependency>
<dependency>
<groupId>com.numericalmethod</groupId>
<artifactId>suanshu</artifactId>
@ -126,6 +121,11 @@
<artifactId>kafka-clients</artifactId>
<version>${kafka.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
@ -138,21 +138,6 @@
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.rosuda.REngine</groupId>
<artifactId>Rserve</artifactId>
<version>${rserve.version}</version>
</dependency>
<dependency>
<groupId>com.github.jbytecode</groupId>
<artifactId>RCaller</artifactId>
<version>${rcaller.version}</version>
</dependency>
<dependency>
<groupId>org.renjin</groupId>
<artifactId>renjin-script-engine</artifactId>
<version>${renjin.version}</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
@ -175,33 +160,8 @@
<url>http://repo.numericalmethod.com/maven/</url>
<layout>default</layout>
</repository>
<!-- Needed for Renjin -->
<repository>
<id>bedatadriven</id>
<name>bedatadriven public repo</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- Excludes FastR classes from compilations since they require GraalVM -->
<excludes>
<exclude>com/baeldung/r/FastRMean.java</exclude>
</excludes>
<testExcludes>
<exclude>com/baeldung/r/FastRMeanUnitTest.java</exclude>
</testExcludes>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<flink.version>1.5.0</flink.version>
<hll.version>1.6.0</hll.version>
@ -210,17 +170,14 @@
<infinispan.version>9.1.5.Final</infinispan.version>
<jackson.version>2.9.8</jackson.version>
<spring.version>4.3.8.RELEASE</spring.version>
<jmapper.version>1.6.0.1</jmapper.version>
<suanshu.version>4.0.0</suanshu.version>
<derive4j.version>1.1.0</derive4j.version>
<assertj.version>3.6.2</assertj.version>
<slf4j.version>1.7.25</slf4j.version>
<awaitility.version>3.0.0</awaitility.version>
<univocity.version>2.8.4</univocity.version>
<renjin.version>RELEASE</renjin.version>
<rcaller.version>3.0</rcaller.version>
<rserve.version>1.8.1</rserve.version>
<kafka.version>2.5.0</kafka.version>
<guava.version>29.0-jre</guava.version>
</properties>
</project>

View File

@ -12,4 +12,5 @@ This module contains articles about libraries for data processing in Java.
- [Introduction to Kafka Connectors](https://www.baeldung.com/kafka-connectors-guide)
- [Kafka Connect Example with MQTT and MongoDB](https://www.baeldung.com/kafka-connect-mqtt-mongodb)
- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline)
- [Guide to JMapper](https://www.baeldung.com/jmapper)
More articles: [[next -->]](/../libraries-data-2)

View File

@ -126,6 +126,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.jmapper-framework</groupId>
<artifactId>jmapper-core</artifactId>
<version>${jmapper.version}</version>
</dependency>
</dependencies>
<build>
@ -172,6 +177,7 @@
<org.apache.crunch.crunch-core.version>0.15.0</org.apache.crunch.crunch-core.version>
<org.apache.hadoop.hadoop-client>2.2.0</org.apache.hadoop.hadoop-client>
<slf4j.version>1.7.25</slf4j.version>
<jmapper.version>1.6.0.1</jmapper.version>
</properties>
</project>

View File

@ -7,6 +7,9 @@ import org.junit.Test;
import java.time.LocalDate;
import static com.googlecode.jmapper.api.JMapperAPI.*;
import static com.googlecode.jmapper.api.JMapperAPI.attribute;
import static com.googlecode.jmapper.api.JMapperAPI.global;
import static com.googlecode.jmapper.api.JMapperAPI.mappedClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

View File

@ -55,8 +55,8 @@ public class JMapperRelationalIntegrationTest {
public void givenUser_whenUseApi_thenConverted(){
JMapperAPI jmapperApi = new JMapperAPI()
.add(mappedClass(User.class)
.add(attribute("id").value("id").targetClasses(UserDto1.class,UserDto2.class))
.add(attribute("email").targetAttributes("username","email").targetClasses(UserDto1.class,UserDto2.class)) )
.add(attribute("id").value("id").targetClasses(UserDto1.class, UserDto2.class))
.add(attribute("email").targetAttributes("username","email").targetClasses(UserDto1.class, UserDto2.class)) )
;
RelationalJMapper<User> relationalMapper = new RelationalJMapper<>(User.class,jmapperApi);

View File

@ -0,0 +1,59 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.baeldung</groupId>
<artifactId>hexagonal-architecture</artifactId>
<version>1.0</version>
<name>hexagonal-architecture</name>
<description>Project for hexagonal architecture in java</description>
<properties>
<java.version>1.8</java.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-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung.pattern.hexagonal;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HexArchApplicationDemo {
public static void main(String[] args) {
SpringApplication.run(HexArchApplicationDemo.class, args);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.pattern.hexagonal.config;
import com.baeldung.pattern.hexagonal.domain.services.EmployeeService;
import com.baeldung.pattern.hexagonal.domain.services.EmployeeServiceImpl;
import com.baeldung.pattern.hexagonal.persistence.EmployeeRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public EmployeeService getEmployeeService(EmployeeRepository employeeRepository) {
return new EmployeeServiceImpl(employeeRepository);
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.pattern.hexagonal.config;
import com.baeldung.pattern.hexagonal.persistence.MongoRepoEx;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackageClasses = MongoRepoEx.class)
public class MongoConfig {
}

View File

@ -0,0 +1,25 @@
package com.baeldung.pattern.hexagonal.controller;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import com.baeldung.pattern.hexagonal.domain.services.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Employee addEmployee(@RequestBody Employee employee) {
return employeeService.addEmployee(employee);
}
@GetMapping(path = "/{employeeId}")
public Employee getEmployee(@PathVariable("employeeId") String employeeId) {
return employeeService.getEmployee(employeeId);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.pattern.hexagonal.domain.model;
import org.springframework.data.annotation.Id;
import java.util.Objects;
public class Employee {
@Id
private String empId;
private String empName;
private String empJobTitle;
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpJobTitle() {
return empJobTitle;
}
public void setEmpJobTitle(String empJobTitle) {
this.empJobTitle = empJobTitle;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Employee employee = (Employee) o;
return empId.equals(employee.empId);
}
@Override
public int hashCode() {
return Objects.hash(empId);
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.pattern.hexagonal.domain.services;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
public interface EmployeeService {
Employee addEmployee(Employee employee);
Employee getEmployee(String employeeId);
}

View File

@ -0,0 +1,34 @@
package com.baeldung.pattern.hexagonal.domain.services;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import com.baeldung.pattern.hexagonal.persistence.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Optional;
public class EmployeeServiceImpl implements EmployeeService {
private EmployeeRepository employeeRepository;
@Autowired
public EmployeeServiceImpl(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
@Override
public Employee addEmployee(Employee employee) {
return employeeRepository.add(employee);
}
@Override
public Employee getEmployee(String employeeId) {
Optional<Employee> employee = employeeRepository.findById(employeeId);
if (employee.isPresent()) {
return employee.get();
} else {
// throw
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.pattern.hexagonal.persistence;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface EmployeeRepository {
Employee add(Employee employee);
Optional<Employee> findById(String id);
}

View File

@ -0,0 +1,24 @@
package com.baeldung.pattern.hexagonal.persistence;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public class MongoDBRepository implements EmployeeRepository {
@Autowired
MongoRepoEx mongoRepository;
@Override
public Employee add(Employee employee) {
return mongoRepository.insert(employee);
}
@Override
public Optional<Employee> findById(String id) {
return mongoRepository.findById(id);
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.pattern.hexagonal.persistence;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MongoRepoEx extends MongoRepository<Employee, String> {
}

View File

@ -0,0 +1,46 @@
package com.baeldung.pattern.hexagonal.domain.services;
import com.baeldung.pattern.hexagonal.domain.model.Employee;
import com.baeldung.pattern.hexagonal.persistence.EmployeeRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class EmployeeServiceImplTest {
private EmployeeRepository employeeRepository;
private EmployeeService testService;
private Employee testModel;
@BeforeEach
void setUp() {
employeeRepository = mock(EmployeeRepository.class);
testService = new EmployeeServiceImpl(employeeRepository);
testModel = new Employee();
testModel.setEmpId("2000");
testModel.setEmpName("Test user 1");
testModel.setEmpJobTitle("Software engineer");
}
@Test
void addEmployee() {
when(employeeRepository.add(any(Employee.class))).thenReturn(testModel);
Employee testResponse = testService.addEmployee(testModel);
assertEquals(testModel, testResponse);
}
@Test
void getEmployee() {
when(employeeRepository.findById("2000")).thenReturn(Optional.of(testModel));
Employee testResponse = testService.getEmployee("2000");
assertEquals(testModel, testResponse);
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.statmentVsPreparedstatment;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatasourceFactory {
private Connection connection;
public Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("org.h2.Driver");
connection = DriverManager.getConnection("jdbc:h2:mem:db_basic", "SA", "");
connection.setAutoCommit(false);
return connection;
}
public boolean createTables() throws SQLException {
String query = "create table if not exists PERSONS (ID INT, NAME VARCHAR(45))";
return connection.createStatement().executeUpdate(query) == 0;
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.statmentVsPreparedstatment;
import java.util.Objects;
public class PersonEntity {
private int id;
private String name;
public PersonEntity(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PersonEntity that = (PersonEntity) o;
return id == that.id && Objects.equals(name, that.name);
}
@Override public int hashCode() {
return Objects.hash(id, name);
}
}

View File

@ -0,0 +1,88 @@
package com.baeldung.statmentVsPreparedstatment;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class PreparedStatementPersonDao {
private final Connection connection;
public PreparedStatementPersonDao(Connection connection) {
this.connection = connection;
}
public Optional<PersonEntity> getById(int id) throws SQLException {
String query = "SELECT id, name FROM persons WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.first()) {
PersonEntity result = new PersonEntity(resultSet.getInt("id"),
resultSet.getString("name"));
return Optional.of(result);
} else {
return Optional.empty();
}
}
public void insert(PersonEntity personEntity) throws SQLException {
String query = "INSERT INTO persons(id, name) VALUES( ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, personEntity.getId());
preparedStatement.setString(2, personEntity.getName());
preparedStatement.executeUpdate();
}
public void insert(List<PersonEntity> personEntities) throws SQLException {
String query = "INSERT INTO persons(id, name) VALUES( ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
for (PersonEntity personEntity : personEntities) {
preparedStatement.setInt(1, personEntity.getId());
preparedStatement.setString(2, personEntity.getName());
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
}
public void update(PersonEntity personEntity) throws SQLException {
String query = "UPDATE persons SET name = ? WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, personEntity.getName());
preparedStatement.setInt(2, personEntity.getId());
preparedStatement.executeUpdate();
}
public void deleteById(int id) throws SQLException {
String query = "DELETE FROM persons WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setInt(1, id);
preparedStatement.executeUpdate();
}
public List<PersonEntity> getAll() throws SQLException {
String query = "SELECT id, name FROM persons";
PreparedStatement preparedStatement = connection.prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
List<PersonEntity> result = new ArrayList<>();
while (resultSet.next()) {
result.add(new PersonEntity(resultSet.getInt("id"), resultSet.getString("name")));
}
return result;
}
}

View File

@ -0,0 +1,75 @@
package com.baeldung.statmentVsPreparedstatment;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class StatementPersonDao {
private final Connection connection;
public StatementPersonDao(Connection connection) {
this.connection = connection;
}
public Optional<PersonEntity> getById(int id) throws SQLException {
String query = "SELECT id, name, FROM persons WHERE id = '" + id + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.first()) {
PersonEntity result = new PersonEntity(resultSet.getInt("id"),
resultSet.getString("name"));
return Optional.of(result);
} else {
return Optional.empty();
}
}
public void insert(PersonEntity personEntity) throws SQLException {
String query = "INSERT INTO persons(id, name) VALUES(" + personEntity.getId() + ", '"
+ personEntity.getName() + "')";
Statement statement = connection.createStatement();
statement.executeUpdate(query);
}
public void insert(List<PersonEntity> personEntities) throws SQLException {
for (PersonEntity personEntity : personEntities) {
insert(personEntity);
}
}
public void update(PersonEntity personEntity) throws SQLException {
String query = "UPDATE persons SET name = '" + personEntity.getName() + "' WHERE id = "
+ personEntity.getId();
Statement statement = connection.createStatement();
statement.executeUpdate(query);
}
public void deleteById(int id) throws SQLException {
String query = "DELETE FROM persons WHERE id = " + id;
Statement statement = connection.createStatement();
statement.executeUpdate(query);
}
public List<PersonEntity> getAll() throws SQLException {
String query = "SELECT id, name, FROM persons";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
List<PersonEntity> result = new ArrayList<>();
while (resultSet.next()) {
result.add(new PersonEntity(resultSet.getInt("id"), resultSet.getString("name")));
}
return result;
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.statmentVsPreparedstatment;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.SQLException;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class DatasourceFactoryUnitTest {
@Test
void whenCreateConnectionAndTables_thenConnectionIsOpenAndTableIsCreated()
throws SQLException, ClassNotFoundException {
DatasourceFactory factory = new DatasourceFactory();
Connection connection = factory.getConnection();
assertFalse(connection.isClosed());
assertTrue(factory.createTables());
}
}

View File

@ -0,0 +1,94 @@
package com.baeldung.statmentVsPreparedstatment;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
class PreparedStatementPersonDaoUnitTest {
private PreparedStatementPersonDao dao;
@BeforeEach
void setup() throws SQLException, ClassNotFoundException {
DatasourceFactory datasourceFactory = new DatasourceFactory();
Connection connection = datasourceFactory.getConnection();
datasourceFactory.createTables();
dao = new PreparedStatementPersonDao(connection);
}
@Test
void whenInsertAPerson_thenItNeverThrowsAnException() {
assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "john")));
}
@Test
void whenInsertAPersonWithQuoteInText_thenItNeverThrowsAnException() {
assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "O'Brien")));
}
@Test
void whenGetAPersonById_thenItReturnThePersonInDatabase() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
Optional<PersonEntity> maybeEmployee = dao.getById(1);
assertTrue(maybeEmployee.isPresent());
PersonEntity personEntity = maybeEmployee.get();
assertEquals(1, personEntity.getId());
assertEquals("john", personEntity.getName());
}
@Test
void whenInsertAndGetMultiplePersons_thenItNeverThrowsAnException() throws SQLException {
assertDoesNotThrow(() -> dao.insert(
Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skit"))));
List<PersonEntity> result = dao.getAll();
assertEquals(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skit")),
result);
}
@Test
void whenUpdateAnExistentPerson_thenItReturnsTheUpdatedPerson() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
dao.update(new PersonEntity(1, "johnny"));
Optional<PersonEntity> maybePerson = dao.getById(1);
assertTrue(maybePerson.isPresent());
PersonEntity personEntity = maybePerson.get();
assertEquals(1, personEntity.getId());
assertEquals("johnny", personEntity.getName());
}
@Test
void whenDeleteAPersonById_thenItWillBeAbsentInDatabase() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
dao.deleteById(1);
Optional<PersonEntity> maybePerson = dao.getById(1);
assertFalse(maybePerson.isPresent());
}
@Test
void whenAHackerUpdateAPerson_thenItUpdatesTheTargetPerson() throws SQLException {
dao.insert(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")));
dao.update(new PersonEntity(1, "hacker' --"));
List<PersonEntity> result = dao.getAll();
assertEquals(Arrays.asList(new PersonEntity(1, "hacker' --"), new PersonEntity(2, "skeet")),
result);
}
}

View File

@ -0,0 +1,96 @@
package com.baeldung.statmentVsPreparedstatment;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
class StatementPersonDaoUnitTest {
private StatementPersonDao dao;
@BeforeEach
void setup() throws SQLException, ClassNotFoundException {
DatasourceFactory datasourceFactory = new DatasourceFactory();
Connection connection = datasourceFactory.getConnection();
datasourceFactory.createTables();
dao = new StatementPersonDao(connection);
}
@Test
void whenInsertAPerson_thenItNeverThrowsAnException() {
assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "john")));
}
@Test
void whenInsertAPersonWithQuoteInText_thenItWillThrowAnException() {
assertThrows(SQLException.class, () -> dao.insert(new PersonEntity(1, "O'Brien")));
}
@Test
void whenGetAPersonById_thenItReturnThePersonInDatabase() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
Optional<PersonEntity> maybeEmployee = dao.getById(1);
assertTrue(maybeEmployee.isPresent());
PersonEntity personEntity = maybeEmployee.get();
assertEquals(1, personEntity.getId());
assertEquals("john", personEntity.getName());
}
@Test
void whenInsertAndGetMultiplePersons_thenItNeverThrowsAnException() throws SQLException {
assertDoesNotThrow(() -> dao.insert(
Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet"))));
List<PersonEntity> result = dao.getAll();
assertEquals(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")),
result);
}
@Test
void whenUpdateAnExistentPerson_thenItReturnsTheUpdatedPerson() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
dao.update(new PersonEntity(1, "johnny"));
Optional<PersonEntity> maybePerson = dao.getById(1);
assertTrue(maybePerson.isPresent());
PersonEntity personEntity = maybePerson.get();
assertEquals(1, personEntity.getId());
assertEquals("johnny", personEntity.getName());
}
@Test
void whenDeleteAPersonById_thenItWillBeAbsentInDatabase() throws SQLException {
dao.insert(new PersonEntity(1, "john"));
dao.deleteById(1);
Optional<PersonEntity> maybePerson = dao.getById(1);
assertFalse(maybePerson.isPresent());
}
@Test
void whenAHackerUpdateAPerson_thenItAllPersonsAreUpdated() throws SQLException {
dao.insert(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")));
dao.update(new PersonEntity(1, "hacker' --"));
List<PersonEntity> result = dao.getAll();
assertEquals(Arrays.asList(new PersonEntity(1, "hacker"), new PersonEntity(2, "hacker")),
result);
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.assume;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;
import org.junit.Test;
public class ConditionallyIgnoreTestsUnitTest {
@Test
public void whenAssumeThatCodeVersionIsNot2_thenIgnore() {
final int codeVersion = 1;
assumeThat(codeVersion, is(2));
assertEquals("hello", "HELLO".toLowerCase());
}
@Test
public void whenAssumeTrueOnCondition_thenIgnore() {
final int codeVersion = 1;
assumeTrue(isCodeVersion2(codeVersion));
assertEquals("hello", "HELLO".toLowerCase());
}
@Test
public void whenAssumeFalseOnCondition_thenIgnore() {
final int codeVersion = 2;
assumeFalse(isCodeVersion2(codeVersion));
assertEquals("hello", "HELLO".toLowerCase());
}
private boolean isCodeVersion2(final int codeVersion) {
return codeVersion == 2;
}
}