From b623297829c113a80b571e25e5680ff5e9bcfaf6 Mon Sep 17 00:00:00 2001
From: mbarriola <85458535+mbarriola@users.noreply.github.com>
Date: Thu, 5 Aug 2021 15:50:37 -0400
Subject: [PATCH] Core java 12 improvements (#11090)
* Commit source code to branch
* Fix to BAEL-5072
Change package definition and implementation of compactValues junit
* BAEL-5053 Compare file contents
---
core-java-modules/core-java-12/pom.xml | 93 ++++++++-------
.../comparison/CompareFileContents.java | 88 ++++++++++++++
.../CampareFileContentsApacheIOUnitTest.java | 88 ++++++++++++++
.../CompareByMemoryMappedFilesUnitTest.java | 42 +++++++
.../CompareFileContentsByBytesUnitTest.java | 96 +++++++++++++++
.../CompareFileContentsByLinesUnitTest.java | 94 +++++++++++++++
.../newfeatures/CompactNumbersUnitTest.java | 6 +-
.../newfeatures/FileMismatchUnitTest.java | 4 +-
.../baeldung/newfeatures/StringUnitTest.java | 4 +-
.../newfeatures/TeeingCollectorUnitTest.java | 6 +-
patterns/simplehexagonalexample/pom.xml | 31 +++++
.../simplehexagonalex/DailyQuoteMain.java | 32 +++++
.../controller/QuoteCliController.java | 24 ++++
.../controller/QuoteRestController.java | 24 ++++
.../domain/QuoteOfTheDay.java | 56 +++++++++
.../repository/QuoteOfTheDayFromProvider.java | 8 ++
.../domain/service/QuoteAggregator.java | 22 ++++
.../domain/service/QuoteService.java | 8 ++
.../primary/quoteadapter/ProviderQuote.java | 109 ++++++++++++++++++
.../quoteadapter/ProviderQuoteAdapter.java | 54 +++++++++
.../quoteadapter/ProviderQuoteEnvelope.java | 68 +++++++++++
.../mock/quoteadapter/MockQuoteAdapter.java | 20 ++++
.../src/main/resources/application.properties | 1 +
.../MockAccessProviderUnitTest.java | 22 ++++
.../PrimaryAccessProviderIntegrationTest.java | 28 +++++
.../QuoteRequestIntegrationTest.java | 36 ++++++
.../src/test/resources/application.properties | 1 +
27 files changed, 1014 insertions(+), 51 deletions(-)
create mode 100644 core-java-modules/core-java-12/src/main/java/com/baeldung/file/content/comparison/CompareFileContents.java
create mode 100644 core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CampareFileContentsApacheIOUnitTest.java
create mode 100644 core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareByMemoryMappedFilesUnitTest.java
create mode 100644 core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByBytesUnitTest.java
create mode 100644 core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByLinesUnitTest.java
create mode 100644 patterns/simplehexagonalexample/pom.xml
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java
create mode 100644 patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java
create mode 100644 patterns/simplehexagonalexample/src/main/resources/application.properties
create mode 100644 patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java
create mode 100644 patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java
create mode 100644 patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java
create mode 100644 patterns/simplehexagonalexample/src/test/resources/application.properties
diff --git a/core-java-modules/core-java-12/pom.xml b/core-java-modules/core-java-12/pom.xml
index 8f6abdda5b..ce7ec72aeb 100644
--- a/core-java-modules/core-java-12/pom.xml
+++ b/core-java-modules/core-java-12/pom.xml
@@ -1,49 +1,60 @@
- 4.0.0
- core-java-12
- 0.1.0-SNAPSHOT
- core-java-12
- jar
- http://maven.apache.org
+ 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">
+ 4.0.0
+ core-java-12
+ 0.1.0-SNAPSHOT
+ core-java-12
+ jar
+ http://maven.apache.org
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
- ../../
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../
+
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
-
- ${maven.compiler.target.version}
- --enable-preview
-
-
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ ${maven.compiler.target.version}
+ --enable-preview
+
+
+
+ maven-surefire-plugin
+
+ --enable-preview
+
+
+
+
-
- 12
- 12
- 3.6.1
-
+
+ 12
+ 12
+ 3.6.1
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-12/src/main/java/com/baeldung/file/content/comparison/CompareFileContents.java b/core-java-modules/core-java-12/src/main/java/com/baeldung/file/content/comparison/CompareFileContents.java
new file mode 100644
index 0000000000..637ddb4a91
--- /dev/null
+++ b/core-java-modules/core-java-12/src/main/java/com/baeldung/file/content/comparison/CompareFileContents.java
@@ -0,0 +1,88 @@
+package com.baeldung.file.content.comparison;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class CompareFileContents {
+
+ public static long filesCompareByByte(Path path1, Path path2) throws IOException {
+
+ if (path1.getFileSystem()
+ .provider()
+ .isSameFile(path1, path2)) {
+ return -1;
+ }
+
+ try (BufferedInputStream fis1 = new BufferedInputStream(new FileInputStream(path1.toFile()));
+ BufferedInputStream fis2 = new BufferedInputStream(new FileInputStream(path2.toFile()))) {
+ int ch = 0;
+ long pos = 1;
+ while ((ch = fis1.read()) != -1) {
+ if (ch != fis2.read()) {
+ return pos;
+ }
+ pos++;
+ }
+ if (fis2.read() == -1) {
+ return -1;
+ } else {
+ return pos;
+ }
+ }
+ }
+
+ public static long filesCompareByLine(Path path1, Path path2) throws IOException {
+
+ if (path1.getFileSystem()
+ .provider()
+ .isSameFile(path1, path2)) {
+ return -1;
+ }
+
+ try (BufferedReader bf1 = Files.newBufferedReader(path1);
+ BufferedReader bf2 = Files.newBufferedReader(path2)) {
+
+ long lineNumber = 1;
+ String line1 = "", line2 = "";
+ while ((line1 = bf1.readLine()) != null) {
+ line2 = bf2.readLine();
+ if (line2 == null || !line1.equals(line2)) {
+ return lineNumber;
+ }
+ lineNumber++;
+ }
+ if (bf2.readLine() == null) {
+ return -1;
+ } else {
+ return lineNumber;
+ }
+ }
+ }
+
+ public static boolean compareByMemoryMappedFiles(Path path1, Path path2) throws IOException {
+
+ try (RandomAccessFile randomAccessFile1 = new RandomAccessFile(path1.toFile(), "r");
+ RandomAccessFile randomAccessFile2 = new RandomAccessFile(path2.toFile(), "r")) {
+
+ FileChannel ch1 = randomAccessFile1.getChannel();
+ FileChannel ch2 = randomAccessFile2.getChannel();
+ if (ch1.size() != ch2.size()) {
+
+ return false;
+ }
+ long size = ch1.size();
+ MappedByteBuffer m1 = ch1.map(FileChannel.MapMode.READ_ONLY, 0L, size);
+ MappedByteBuffer m2 = ch2.map(FileChannel.MapMode.READ_ONLY, 0L, size);
+
+ return m1.equals(m2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CampareFileContentsApacheIOUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CampareFileContentsApacheIOUnitTest.java
new file mode 100644
index 0000000000..0d86abae11
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CampareFileContentsApacheIOUnitTest.java
@@ -0,0 +1,88 @@
+package com.baeldung.file.content.comparison;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class CampareFileContentsApacheIOUnitTest {
+
+ public static Path path1 = null;
+ public static Path path2 = null;
+
+ @BeforeAll
+ public static void setup() throws IOException {
+
+ path1 = Files.createTempFile("file1Test", ".txt");
+ path2 = Files.createTempFile("file2Test", ".txt");
+ }
+
+ @Test
+ public void whenFilesIdentical_thenReturnTrue() throws IOException {
+
+ InputStream inputStream1 = new FileInputStream(path1.toFile());
+ InputStream inputStream2 = new FileInputStream(path2.toFile());
+
+ Files.writeString(path1, "testing line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing line 1" + System.lineSeparator() + "line 2");
+
+ assertTrue(IOUtils.contentEquals(inputStream1, inputStream2));
+ }
+
+ @Test
+ public void whenFilesDifferent_thenReturnFalse() throws IOException {
+
+ InputStream inputStream1 = new FileInputStream(path1.toFile());
+ InputStream inputStream2 = new FileInputStream(path2.toFile());
+
+ Files.writeString(path1, "testing line " + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing line 1" + System.lineSeparator() + "line 2");
+
+ assertFalse(IOUtils.contentEquals(inputStream1, inputStream2));
+ }
+
+ @Test
+ public void whenFilesIdenticalIgnoreEOF_thenReturnTrue() throws IOException {
+
+ Files.writeString(path1, "testing line 1 \n line 2");
+ Files.writeString(path2, "testing line 1 \r\n line 2");
+
+ Reader reader1 = new BufferedReader(new FileReader(path1.toFile()));
+ Reader reader2 = new BufferedReader(new FileReader(path2.toFile()));
+
+ assertTrue(IOUtils.contentEqualsIgnoreEOL(reader1, reader2));
+ }
+
+ @Test
+ public void whenFilesNotIdenticalIgnoreEOF_thenReturnFalse() throws IOException {
+
+ Files.writeString(path1, "testing line \n line 2");
+ Files.writeString(path2, "testing line 1 \r\n line 2");
+
+ Reader reader1 = new BufferedReader(new FileReader(path1.toFile()));
+ Reader reader2 = new BufferedReader(new FileReader(path2.toFile()));
+
+ assertFalse(IOUtils.contentEqualsIgnoreEOL(reader1, reader2));
+ }
+
+ @AfterAll
+ public static void shutDown() {
+
+ path1.toFile()
+ .deleteOnExit();
+ path2.toFile()
+ .deleteOnExit();
+ }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareByMemoryMappedFilesUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareByMemoryMappedFilesUnitTest.java
new file mode 100644
index 0000000000..0405ac3b52
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareByMemoryMappedFilesUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.file.content.comparison;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class CompareByMemoryMappedFilesUnitTest {
+
+ public static Path path1 = null;
+ public static Path path2 = null;
+
+ @BeforeAll
+ public static void setup() throws IOException {
+
+ path1 = Files.createTempFile("file1Test", ".txt");
+ path2 = Files.createTempFile("file2Test", ".txt");
+ }
+
+ @Test
+ public void whenFilesIdentical_thenReturnTrue() throws IOException {
+
+ Files.writeString(path1, "testing line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing line 1" + System.lineSeparator() + "line 2");
+
+ assertTrue(CompareFileContents.compareByMemoryMappedFiles(path1, path2));
+ }
+
+ @Test
+ public void whenFilesDifferent_thenReturnFalse() throws IOException {
+
+ Files.writeString(path1, "testing line " + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing line 1" + System.lineSeparator() + "line 2");
+
+ assertFalse(CompareFileContents.compareByMemoryMappedFiles(path1, path2));
+ }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByBytesUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByBytesUnitTest.java
new file mode 100644
index 0000000000..15efc952c2
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByBytesUnitTest.java
@@ -0,0 +1,96 @@
+package com.baeldung.file.content.comparison;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class CompareFileContentsByBytesUnitTest {
+
+ public static Path path1 = null;
+ public static Path path2 = null;
+
+ @BeforeAll
+ public static void setup() throws IOException {
+
+ path1 = Files.createTempFile("file1Test", ".txt");
+ path2 = Files.createTempFile("file2Test", ".txt");
+ }
+
+ @Test
+ public void whenFirstFileShorter_thenPositionInSecondFile() throws IOException {
+
+ Files.writeString(path1, "testing");
+ Files.writeString(path2, "testing1");
+
+ assertEquals(8, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenSecondFileShorter_thenPositionInFirstFile() throws IOException {
+
+ Files.writeString(path1, "testing1");
+ Files.writeString(path2, "testing");
+
+ assertEquals(8, CompareFileContents.filesCompareByByte(path1, path2));
+
+ }
+
+ @Test
+ public void whenFilesIdentical_thenSuccess() throws IOException {
+
+ Files.writeString(path1, "testing");
+ Files.writeString(path2, "testing");
+
+ assertEquals(-1, CompareFileContents.filesCompareByByte(path1, path2));
+
+ }
+
+ @Test
+ public void whenFilesDifferent_thenPosition() throws IOException {
+
+ Files.writeString(path1, "tesXing");
+ Files.writeString(path2, "testing");
+
+ assertEquals(4, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenBothFilesEmpty_thenEqual() throws IOException {
+
+ Files.writeString(path1, "");
+ Files.writeString(path2, "");
+
+ assertEquals(-1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenFirstEmpty_thenPositionFirst() throws IOException {
+
+ Files.writeString(path1, "");
+ Files.writeString(path2, "test");
+
+ assertEquals(1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenSecondEmpty_thenPositionFirst() throws IOException {
+
+ Files.writeString(path1, "test");
+ Files.writeString(path2, "");
+
+ assertEquals(1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @AfterAll
+ public static void shutDown() {
+
+ path1.toFile().deleteOnExit();
+ path2.toFile().deleteOnExit();
+ }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByLinesUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByLinesUnitTest.java
new file mode 100644
index 0000000000..63170221d3
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/file/content/comparison/CompareFileContentsByLinesUnitTest.java
@@ -0,0 +1,94 @@
+package com.baeldung.file.content.comparison;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class CompareFileContentsByLinesUnitTest {
+
+ public static Path path1 = null;
+ public static Path path2 = null;
+
+ @BeforeAll
+ public static void setup() throws IOException {
+
+ path1 = Files.createTempFile("file1Test", ".txt");
+ path2 = Files.createTempFile("file2Test", ".txt");
+ }
+
+ @Test
+ public void whenFirstFileShorter_thenLineNumbersFirstFile() throws IOException {
+
+ Files.writeString(path1, "testing line 1");
+ Files.writeString(path2, "testing1 line 1" + System.lineSeparator() + "line 2");
+
+ assertEquals(1, CompareFileContents.filesCompareByLine(path1, path2));
+ }
+
+ @Test
+ public void whenSecondFileShorter_thenLineNumbersSecondFile() throws IOException {
+
+ Files.writeString(path1, "testing1 line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing line 1");
+
+ assertEquals(1, CompareFileContents.filesCompareByLine(path1, path2));
+ }
+
+ @Test
+ public void whenFileIdentical_thenLineSuccess() throws IOException {
+
+ Files.writeString(path1, "testing1 line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing1 line 1" + System.lineSeparator() + "line 2");
+
+ assertEquals(-1, CompareFileContents.filesCompareByLine(path1, path2));
+ }
+
+ @Test
+ public void whenFilesDifferent_thenLineNumber() throws IOException {
+
+ Files.writeString(path1, "testing1 line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "testing1 line 1" + System.lineSeparator() + "linX 2");
+
+ assertEquals(2, CompareFileContents.filesCompareByLine(path1, path2));
+ }
+
+ @Test
+ public void whenBothFilesEmpty_thenEqual() throws IOException {
+
+ Files.writeString(path1, "");
+ Files.writeString(path2, "");
+
+ assertEquals(-1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenFirstEmpty_thenPositionFirst() throws IOException {
+
+ Files.writeString(path1, "");
+ Files.writeString(path2, "testing1 line 1" + System.lineSeparator() + "line 2");
+
+ assertEquals(1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @Test
+ public void whenSecondEmpty_thenPositionFirst() throws IOException {
+
+ Files.writeString(path1, "testing1 line 1" + System.lineSeparator() + "line 2");
+ Files.writeString(path2, "");
+
+ assertEquals(1, CompareFileContents.filesCompareByByte(path1, path2));
+ }
+
+ @AfterAll
+ public static void shutDown() {
+
+ path1.toFile().deleteOnExit();
+ path2.toFile().deleteOnExit();
+ }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java
index 08a6d58d72..a557ce5545 100644
--- a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java
@@ -1,6 +1,6 @@
-package java.com.baeldung.newfeatures;
+package com.baeldung.newfeatures;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.text.NumberFormat;
import java.util.Locale;
@@ -16,6 +16,6 @@ public class CompactNumbersUnitTest {
assertEquals("2.59K", likesShort.format(2592));
NumberFormat likesLong = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
likesLong.setMaximumFractionDigits(2);
- assertEquals("2.59 thousand", likesShort.format(2592));
+ assertEquals("2.59 thousand", likesLong.format(2592));
}
}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java
index 7f081fe399..93fcfbda02 100644
--- a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java
@@ -1,6 +1,6 @@
-package java.com.baeldung.newfeatures;
+package com.baeldung.newfeatures;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java
index 5ae51bd960..1651fe0ee6 100644
--- a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java
@@ -1,6 +1,6 @@
-package java.com.baeldung.newfeatures;
+package com.baeldung.newfeatures;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java
index 30a5cb40a7..a925e693ff 100644
--- a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java
@@ -1,6 +1,6 @@
-package java.com.baeldung.newfeatures;
+package com.baeldung.newfeatures;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -13,6 +13,6 @@ public class TeeingCollectorUnitTest {
public void givenSetOfNumbers_thenCalculateAverage() {
double mean = Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, count) -> sum / count));
- assertEquals(3.0, mean);
+ assertEquals(3.0, mean, 0);
}
}
diff --git a/patterns/simplehexagonalexample/pom.xml b/patterns/simplehexagonalexample/pom.xml
new file mode 100644
index 0000000000..b73e81be44
--- /dev/null
+++ b/patterns/simplehexagonalexample/pom.xml
@@ -0,0 +1,31 @@
+
+ 4.0.0
+ 1.0.0-SNAPSHOT
+ simple-hexagonal-example
+ simpleHexagonalExample
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java
new file mode 100644
index 0000000000..de8b2f4793
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/DailyQuoteMain.java
@@ -0,0 +1,32 @@
+package com.baeldung.simplehexagonalex;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.baeldung.simplehexagonalex.controller.QuoteCliController;
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+
+@SpringBootApplication
+public class DailyQuoteMain implements CommandLineRunner {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DailyQuoteMain.class);
+ @Autowired
+ private QuoteCliController quoteCliController;
+
+ public static void main(final String[] args) {
+
+ SpringApplication.run(DailyQuoteMain.class, args);
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ QuoteOfTheDay quoteOfTheDay = quoteCliController.getQuote("cliController");
+
+ LOG.info(quoteOfTheDay.toString());
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java
new file mode 100644
index 0000000000..9ecb2bf822
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteCliController.java
@@ -0,0 +1,24 @@
+package com.baeldung.simplehexagonalex.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.service.QuoteService;
+
+@Component
+public class QuoteCliController {
+
+ private static final Logger LOG = LoggerFactory.getLogger(QuoteCliController.class);
+
+ @Autowired
+ private QuoteService quoteService;
+
+ public QuoteOfTheDay getQuote(String userId) {
+
+ LOG.info("Getting quote");
+ return quoteService.getQuote(userId);
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java
new file mode 100644
index 0000000000..061cff8cec
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/controller/QuoteRestController.java
@@ -0,0 +1,24 @@
+package com.baeldung.simplehexagonalex.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.service.QuoteService;
+
+@RestController
+@RequestMapping("/quote")
+public class QuoteRestController {
+
+ @Autowired
+ private QuoteService quoteService;
+
+ @GetMapping(path = "/{userId}")
+ public QuoteOfTheDay getEmployee(@PathVariable("userId") String userId) {
+ return quoteService.getQuote(userId);
+ }
+
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java
new file mode 100644
index 0000000000..c74c224c70
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/QuoteOfTheDay.java
@@ -0,0 +1,56 @@
+package com.baeldung.simplehexagonalex.domain;
+
+import java.util.Objects;
+
+public class QuoteOfTheDay {
+
+ private String userName;
+ private String quote;
+ private String provider;
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getQuote() {
+ return quote;
+ }
+
+ public void setQuote(String quote) {
+ this.quote = quote;
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(provider, quote, userName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ QuoteOfTheDay other = (QuoteOfTheDay) obj;
+ return Objects.equals(provider, other.provider) && Objects.equals(quote, other.quote) && Objects.equals(userName, other.userName);
+ }
+
+ @Override
+ public String toString() {
+ return "QuoteOfTheDay [userName=" + userName + ", quote=" + quote + ", provider=" + provider + "]";
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java
new file mode 100644
index 0000000000..7e70cebd12
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/repository/QuoteOfTheDayFromProvider.java
@@ -0,0 +1,8 @@
+package com.baeldung.simplehexagonalex.domain.repository;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+
+public interface QuoteOfTheDayFromProvider {
+
+ QuoteOfTheDay getQuote();
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java
new file mode 100644
index 0000000000..16f7015ace
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteAggregator.java
@@ -0,0 +1,22 @@
+package com.baeldung.simplehexagonalex.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
+
+@Service
+public class QuoteAggregator implements QuoteService {
+
+ @Autowired
+ private QuoteOfTheDayFromProvider quoteOfTheDayFromProvider;
+
+ @Override
+ public QuoteOfTheDay getQuote(String userName) {
+
+ QuoteOfTheDay quoteOfTheDay = quoteOfTheDayFromProvider.getQuote();
+ quoteOfTheDay.setUserName(userName);
+ return quoteOfTheDay;
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java
new file mode 100644
index 0000000000..300387a41d
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/domain/service/QuoteService.java
@@ -0,0 +1,8 @@
+package com.baeldung.simplehexagonalex.domain.service;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+
+public interface QuoteService {
+
+ QuoteOfTheDay getQuote(String userName);
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java
new file mode 100644
index 0000000000..0cbbc60726
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuote.java
@@ -0,0 +1,109 @@
+package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
+
+import java.util.List;
+import java.util.Objects;
+
+public class ProviderQuote {
+
+ private String quote;
+ private String length;
+ private String author;
+ private List tags;
+ private String category;
+ private String language;
+ private String date;
+ private String permalink;
+ private String id;
+ private String background;
+ private String title;
+
+ public ProviderQuote() {
+
+ }
+
+ public ProviderQuote(String quote, String length, String author, List tags, String category, String language, String date, String permalink, String id, String background, String title) {
+ super();
+ this.quote = quote;
+ this.length = length;
+ this.author = author;
+ this.tags = tags;
+ this.category = category;
+ this.language = language;
+ this.date = date;
+ this.permalink = permalink;
+ this.id = id;
+ this.background = background;
+ this.title = title;
+ }
+
+ public String getQuote() {
+ return quote;
+ }
+
+ public String getLength() {
+ return length;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public List getTags() {
+ return tags;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public String getPermalink() {
+ return permalink;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getBackground() {
+ return background;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ProviderQuote other = (ProviderQuote) obj;
+ return Objects.equals(id, other.id);
+ }
+
+ @Override
+ public String toString() {
+ return "TheysaysoQuote [quote=" + quote + ", length=" + length + ", " + "author=" + author + ", tags=" + tags + ", category=" + category + ", language=" + language + ", date=" + date + ", permalink=" + permalink + ", id=" + id + ", background="
+ + background + ", title=" + title + "]";
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java
new file mode 100644
index 0000000000..ded08f7b18
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteAdapter.java
@@ -0,0 +1,54 @@
+package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
+
+import java.net.URI;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Service("providerQuoteAdapter")
+@Primary
+public class ProviderQuoteAdapter implements QuoteOfTheDayFromProvider {
+
+ @Autowired
+ private Environment env;
+
+ @Override
+ public QuoteOfTheDay getQuote() {
+
+ QuoteOfTheDay quoteOfTheDay = new QuoteOfTheDay();
+ ProviderQuoteEnvelope providerQuote;
+ try {
+ providerQuote = getProviderQuote();
+ quoteOfTheDay.setQuote(providerQuote.getContents()
+ .getQuotes()
+ .get(0)
+ .getQuote());
+ quoteOfTheDay.setProvider(providerQuote.getCopyright()
+ .getUrl());
+ } catch (Exception e) {
+ quoteOfTheDay.setQuote("Unable to get the quote");
+ quoteOfTheDay.setProvider("none");
+ }
+ return quoteOfTheDay;
+ }
+
+ private ProviderQuoteEnvelope getProviderQuote() throws Exception {
+
+ HttpGet request = new HttpGet(URI.create(env.getProperty("theysayso.quote.provider.url")));
+ CloseableHttpClient client = HttpClients.createDefault();
+ CloseableHttpResponse response = client.execute(request);
+ ProviderQuoteEnvelope providersQuote = new ObjectMapper().readValue(response.getEntity()
+ .getContent(), ProviderQuoteEnvelope.class);
+ return providersQuote;
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java
new file mode 100644
index 0000000000..611549f23d
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/repository/primary/quoteadapter/ProviderQuoteEnvelope.java
@@ -0,0 +1,68 @@
+package com.baeldung.simplehexagonalex.repository.primary.quoteadapter;
+
+import java.util.List;
+
+public class ProviderQuoteEnvelope {
+
+ private Success success;
+ private Contents contents;
+ private String baseurl;
+ private Copyright copyright;
+
+ public ProviderQuoteEnvelope() {
+
+ }
+
+ public ProviderQuoteEnvelope(Success success, Contents contents, String baseurl, Copyright copyright) {
+ super();
+ this.success = success;
+ this.contents = contents;
+ this.baseurl = baseurl;
+ this.copyright = copyright;
+ }
+
+ public Success getSuccess() {
+ return success;
+ }
+
+ public Contents getContents() {
+ return contents;
+ }
+
+ public String getBaseurl() {
+ return baseurl;
+ }
+
+ public Copyright getCopyright() {
+ return copyright;
+ }
+
+ public class Contents {
+ private List quotes;
+
+ public List getQuotes() {
+ return quotes;
+ }
+ }
+
+ public class Copyright {
+ private int year;
+ private String url;
+
+ public int getYear() {
+ return year;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+ }
+
+ public class Success {
+ private int total;
+
+ public int getTotal() {
+ return total;
+ }
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java
new file mode 100644
index 0000000000..54c28fc94e
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/java/com/baeldung/simplehexagonalex/reposity/mock/quoteadapter/MockQuoteAdapter.java
@@ -0,0 +1,20 @@
+package com.baeldung.simplehexagonalex.reposity.mock.quoteadapter;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
+
+@Service
+public class MockQuoteAdapter implements QuoteOfTheDayFromProvider {
+
+ @Override
+ public QuoteOfTheDay getQuote() {
+
+ QuoteOfTheDay quoteOfTheDay = new QuoteOfTheDay();
+ quoteOfTheDay.setQuote("Mock quote of the day");
+ quoteOfTheDay.setProvider("Mock Provider");
+
+ return quoteOfTheDay;
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/main/resources/application.properties b/patterns/simplehexagonalexample/src/main/resources/application.properties
new file mode 100644
index 0000000000..dd9413bfd5
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/main/resources/application.properties
@@ -0,0 +1 @@
+theysayso.quote.provider.url=https://quotes.rest/qod?language=en
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java
new file mode 100644
index 0000000000..602f7ea5d4
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/MockAccessProviderUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.reposity.mock.quoteadapter.MockQuoteAdapter;
+
+public class MockAccessProviderUnitTest {
+
+ @Test
+ public void givenProvider_whenConnect_thenResponse() throws Exception {
+
+ MockQuoteAdapter provider = new MockQuoteAdapter();
+ QuoteOfTheDay quote = provider.getQuote();
+ assertNotNull(quote);
+ assertEquals("Mock quote of the day", quote.getQuote());
+ assertEquals("Mock Provider", quote.getProvider());
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java
new file mode 100644
index 0000000000..47e1dde136
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/PrimaryAccessProviderIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.baeldung.simplehexagonalex.domain.QuoteOfTheDay;
+import com.baeldung.simplehexagonalex.domain.repository.QuoteOfTheDayFromProvider;
+
+@SpringBootTest
+public class PrimaryAccessProviderIntegrationTest {
+
+ @Autowired
+ @Qualifier("providerQuoteAdapter")
+ QuoteOfTheDayFromProvider provider;
+
+ @Test
+ public void whenQuoteProvider_thenResponse() throws Exception {
+
+ QuoteOfTheDay quote = provider.getQuote();
+ assertNotNull(quote);
+ assertThat(quote.getProvider()).contains("theysaidso");
+ }
+}
diff --git a/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java
new file mode 100644
index 0000000000..552b5d51c2
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/test/java/com/baeldung/simplehexagonalex/repository/primaryQuoteProvider/QuoteRequestIntegrationTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.simplehexagonalex.repository.primaryQuoteProvider;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+public class QuoteRequestIntegrationTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Test
+ public void whenRestQuoteRequest_thenResponse() throws Exception {
+
+ MvcResult result = this.mockMvc.perform(get("/quote/tester"))
+ .andDo(print())
+ .andExpect(status().isOk())
+ .andReturn();
+
+ String content = result.getResponse()
+ .getContentAsString();
+
+ assertThat(content).contains("tester");
+ assertThat(content).contains("theysaidso");
+ }
+}
\ No newline at end of file
diff --git a/patterns/simplehexagonalexample/src/test/resources/application.properties b/patterns/simplehexagonalexample/src/test/resources/application.properties
new file mode 100644
index 0000000000..dd9413bfd5
--- /dev/null
+++ b/patterns/simplehexagonalexample/src/test/resources/application.properties
@@ -0,0 +1 @@
+theysayso.quote.provider.url=https://quotes.rest/qod?language=en
\ No newline at end of file