From 002a571378a6214d0f6b02b7782877ab2fe05a2b Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Wed, 5 May 2021 19:03:02 +0300 Subject: [PATCH 01/11] iulian.manda@gmail evaluation article "A quick and practical example of Hexagonal Architecture in Java" --- patterns/hexagonal/pom.xml | 17 +++++++ .../hexagonal/WeatherForecasterApp.java | 17 +++++++ .../repository/MockWeatherRepository.java | 17 +++++++ .../repository/RepositoryFactory.java | 11 +++++ .../repository/WeatherRepository.java | 5 ++ .../service/WeatherForecasterService.java | 20 ++++++++ .../ui/WeatherForecasterConsoleUI.java | 48 +++++++++++++++++++ .../hexagonal/ui/WeatherForecasterUI.java | 5 ++ patterns/pom.xml | 3 +- 9 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 patterns/hexagonal/pom.xml create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java create mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java diff --git a/patterns/hexagonal/pom.xml b/patterns/hexagonal/pom.xml new file mode 100644 index 0000000000..7f6cbf176b --- /dev/null +++ b/patterns/hexagonal/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + hexagonal + 1.0 + hexagonal + A quick and practical example of Hexagonal Architecture in Java + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java new file mode 100644 index 0000000000..fb21f9a877 --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java @@ -0,0 +1,17 @@ +package com.baeldung.pattern.hexagonal; + +import com.baeldung.pattern.hexagonal.repository.RepositoryFactory; +import com.baeldung.pattern.hexagonal.repository.WeatherRepository; +import com.baeldung.pattern.hexagonal.service.WeatherForecasterService; +import com.baeldung.pattern.hexagonal.ui.WeatherForecasterConsoleUI; +import com.baeldung.pattern.hexagonal.ui.WeatherForecasterUI; + +public class WeatherForecasterApp { + public static void main(String[] args) { + WeatherRepository repository = RepositoryFactory.getMockWeatherRepository(); + WeatherForecasterService service = new WeatherForecasterService(repository); + WeatherForecasterUI ui = new WeatherForecasterConsoleUI(service); + + ui.start(); + } +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java new file mode 100644 index 0000000000..cdb68b9086 --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java @@ -0,0 +1,17 @@ +package com.baeldung.pattern.hexagonal.repository; + +public class MockWeatherRepository implements WeatherRepository { + @Override + public double getTemperature(String location) { + switch (location) { + case "cluj-napoca": + return 17; + case "bucharest": + return 22; + case "new york": + return 15; + default: + return 20; + } + } +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java new file mode 100644 index 0000000000..d1c74f4b6d --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java @@ -0,0 +1,11 @@ +package com.baeldung.pattern.hexagonal.repository; + +public class RepositoryFactory { + private RepositoryFactory() { + super(); + } + + public static WeatherRepository getMockWeatherRepository() { + return new MockWeatherRepository(); + } +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java new file mode 100644 index 0000000000..4c41c712ec --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java @@ -0,0 +1,5 @@ +package com.baeldung.pattern.hexagonal.repository; + +public interface WeatherRepository { + double getTemperature(String location); +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java new file mode 100644 index 0000000000..c39f01235b --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java @@ -0,0 +1,20 @@ +package com.baeldung.pattern.hexagonal.service; + +import com.baeldung.pattern.hexagonal.repository.WeatherRepository; + +public class WeatherForecasterService { + private final WeatherRepository repository; + + public WeatherForecasterService(WeatherRepository repository) { + this.repository = repository; + } + + public double forecast(String location) { + String normalizedLocation = getNormalizedLocation(location); + return repository.getTemperature(normalizedLocation); + } + + private String getNormalizedLocation(String location) { + return location == null ? "" : location.toLowerCase(); + } +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java new file mode 100644 index 0000000000..3877563694 --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java @@ -0,0 +1,48 @@ +package com.baeldung.pattern.hexagonal.ui; + +import com.baeldung.pattern.hexagonal.service.WeatherForecasterService; + +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; + +public class WeatherForecasterConsoleUI implements WeatherForecasterUI { + private WeatherForecasterService service; + private Scanner in; + private PrintStream out; + + public WeatherForecasterConsoleUI(WeatherForecasterService service) { + this.service = service; + this.in = new Scanner(System.in); + this.out = new PrintStream(System.out, true, StandardCharsets.UTF_8); + } + + @Override + public void start() { + String input = getInput(); + while (isNotExit(input)) { + showTemperature(input); + input = getInput(); + } + stop(); + } + + private String getInput() { + out.print("Location: "); + return in.nextLine(); + } + + private boolean isNotExit(String input) { + return !input.equalsIgnoreCase("exit"); + } + + private void showTemperature(String input) { + double temperature = service.forecast(input); + out.printf("%.2f\u00B0C%n", temperature); + } + + private void stop() { + in.close(); + out.close(); + } +} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java new file mode 100644 index 0000000000..da25cec7bb --- /dev/null +++ b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java @@ -0,0 +1,5 @@ +package com.baeldung.pattern.hexagonal.ui; + +public interface WeatherForecasterUI { + void start(); +} diff --git a/patterns/pom.xml b/patterns/pom.xml index 112eecb606..be419ace86 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 patterns @@ -22,6 +22,7 @@ cqrs-es front-controller hexagonal-architecture + hexagonal intercepting-filter solid clean-architecture From 08f8b8d19f7072ddc2ede5f0eb38979d16493563 Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Fri, 7 May 2021 17:05:31 +0300 Subject: [PATCH 02/11] Add tests --- patterns/hexagonal/pom.xml | 53 +++++++++++++++++++ .../MockWeatherRepositoryUnitTest.java | 39 ++++++++++++++ .../repository/RepositoryFactoryUnitTest.java | 14 +++++ .../WeatherForecasterServiceUnitTest.java | 39 ++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java create mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java create mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java diff --git a/patterns/hexagonal/pom.xml b/patterns/hexagonal/pom.xml index 7f6cbf176b..4b8dfcfeb4 100644 --- a/patterns/hexagonal/pom.xml +++ b/patterns/hexagonal/pom.xml @@ -4,6 +4,22 @@ 4.0.0 hexagonal 1.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 12 + 12 + + + + maven-surefire-plugin + 2.22.2 + + + hexagonal A quick and practical example of Hexagonal Architecture in Java @@ -14,4 +30,41 @@ ../../parent-java + + 12 + 12 + + + + + org.junit.jupiter + junit-jupiter-engine + 5.3.1 + test + + + org.mockito + mockito-core + 2.21.0 + test + + + org.junit.platform + junit-platform-runner + 1.2.0 + test + + + org.junit.vintage + junit-vintage-engine + 5.2.0 + test + + + org.mockito + mockito-junit-jupiter + 2.23.0 + test + + diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java new file mode 100644 index 0000000000..f8d0be5d8b --- /dev/null +++ b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.pattern.hexagonal.repository; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MockWeatherRepositoryUnitTest { + + private final WeatherRepository tested = new MockWeatherRepository(); + + @Test + void givenLocationClujNapoca_whenGetTemperature_thenExpect17() { + double result = tested.getTemperature("cluj-napoca"); + + assertEquals(17, result); + } + + @Test + void givenLocationBucharest_whenGetTemperature_thenExpect22() { + double result = tested.getTemperature("bucharest"); + + assertEquals(22, result); + } + + @Test + void givenLocationNewYork_whenGetTemperature_thenExpect15() { + double result = tested.getTemperature("new york"); + + assertEquals(15, result); + } + + @Test + void givenLocationDefault_whenGetTemperature_thenExpect20() { + double result = tested.getTemperature("default"); + + assertEquals(20, result); + } + +} \ No newline at end of file diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java new file mode 100644 index 0000000000..9fc32e5268 --- /dev/null +++ b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.pattern.hexagonal.repository; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RepositoryFactoryUnitTest { + @Test + void whenGetMockWeatherRepository_thenExpectMockWeatherRepositoryInstance() { + WeatherRepository result = RepositoryFactory.getMockWeatherRepository(); + + assertTrue(result instanceof MockWeatherRepository); + } +} \ No newline at end of file diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java new file mode 100644 index 0000000000..1959a815fb --- /dev/null +++ b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.pattern.hexagonal.service; + +import com.baeldung.pattern.hexagonal.repository.WeatherRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@RunWith(JUnitPlatform.class) +class WeatherForecasterServiceUnitTest { + + @Mock + private WeatherRepository repository; + @InjectMocks + private WeatherForecasterService tested; + + @Test + void givenLocation10_whenForecast_thenExpect10() { + when(repository.getTemperature("location")).thenReturn(10d); + + double result = tested.forecast("location"); + assertEquals(10d, result); + } + + @Test + void givenNullLocation_whenForecast_thenExpectEmptyString() { + when(repository.getTemperature("")).thenReturn(10d); + + double result = tested.forecast(null); + assertEquals(10d, result); + } +} \ No newline at end of file From e157492c8bb3a8ced1f1ff53f6d466fecc7e5529 Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Mon, 31 May 2021 15:50:11 +0300 Subject: [PATCH 03/11] Revert "Add tests" This reverts commit 08f8b8d1 --- patterns/hexagonal/pom.xml | 53 ------------------- .../MockWeatherRepositoryUnitTest.java | 39 -------------- .../repository/RepositoryFactoryUnitTest.java | 14 ----- .../WeatherForecasterServiceUnitTest.java | 39 -------------- 4 files changed, 145 deletions(-) delete mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java delete mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java delete mode 100644 patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java diff --git a/patterns/hexagonal/pom.xml b/patterns/hexagonal/pom.xml index 4b8dfcfeb4..7f6cbf176b 100644 --- a/patterns/hexagonal/pom.xml +++ b/patterns/hexagonal/pom.xml @@ -4,22 +4,6 @@ 4.0.0 hexagonal 1.0 - - - - org.apache.maven.plugins - maven-compiler-plugin - - 12 - 12 - - - - maven-surefire-plugin - 2.22.2 - - - hexagonal A quick and practical example of Hexagonal Architecture in Java @@ -30,41 +14,4 @@ ../../parent-java - - 12 - 12 - - - - - org.junit.jupiter - junit-jupiter-engine - 5.3.1 - test - - - org.mockito - mockito-core - 2.21.0 - test - - - org.junit.platform - junit-platform-runner - 1.2.0 - test - - - org.junit.vintage - junit-vintage-engine - 5.2.0 - test - - - org.mockito - mockito-junit-jupiter - 2.23.0 - test - - diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java deleted file mode 100644 index f8d0be5d8b..0000000000 --- a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepositoryUnitTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.pattern.hexagonal.repository; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class MockWeatherRepositoryUnitTest { - - private final WeatherRepository tested = new MockWeatherRepository(); - - @Test - void givenLocationClujNapoca_whenGetTemperature_thenExpect17() { - double result = tested.getTemperature("cluj-napoca"); - - assertEquals(17, result); - } - - @Test - void givenLocationBucharest_whenGetTemperature_thenExpect22() { - double result = tested.getTemperature("bucharest"); - - assertEquals(22, result); - } - - @Test - void givenLocationNewYork_whenGetTemperature_thenExpect15() { - double result = tested.getTemperature("new york"); - - assertEquals(15, result); - } - - @Test - void givenLocationDefault_whenGetTemperature_thenExpect20() { - double result = tested.getTemperature("default"); - - assertEquals(20, result); - } - -} \ No newline at end of file diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java deleted file mode 100644 index 9fc32e5268..0000000000 --- a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactoryUnitTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.pattern.hexagonal.repository; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -class RepositoryFactoryUnitTest { - @Test - void whenGetMockWeatherRepository_thenExpectMockWeatherRepositoryInstance() { - WeatherRepository result = RepositoryFactory.getMockWeatherRepository(); - - assertTrue(result instanceof MockWeatherRepository); - } -} \ No newline at end of file diff --git a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java b/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java deleted file mode 100644 index 1959a815fb..0000000000 --- a/patterns/hexagonal/src/test/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterServiceUnitTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.pattern.hexagonal.service; - -import com.baeldung.pattern.hexagonal.repository.WeatherRepository; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -@RunWith(JUnitPlatform.class) -class WeatherForecasterServiceUnitTest { - - @Mock - private WeatherRepository repository; - @InjectMocks - private WeatherForecasterService tested; - - @Test - void givenLocation10_whenForecast_thenExpect10() { - when(repository.getTemperature("location")).thenReturn(10d); - - double result = tested.forecast("location"); - assertEquals(10d, result); - } - - @Test - void givenNullLocation_whenForecast_thenExpectEmptyString() { - when(repository.getTemperature("")).thenReturn(10d); - - double result = tested.forecast(null); - assertEquals(10d, result); - } -} \ No newline at end of file From 050c53be0bccf2b02865d0571c21db420d4ee9f7 Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Mon, 31 May 2021 15:50:18 +0300 Subject: [PATCH 04/11] Revert "iulian.manda@gmail evaluation article "A quick and practical example of Hexagonal Architecture in Java"" This reverts commit 002a5713 --- patterns/hexagonal/pom.xml | 17 ------- .../hexagonal/WeatherForecasterApp.java | 17 ------- .../repository/MockWeatherRepository.java | 17 ------- .../repository/RepositoryFactory.java | 11 ----- .../repository/WeatherRepository.java | 5 -- .../service/WeatherForecasterService.java | 20 -------- .../ui/WeatherForecasterConsoleUI.java | 48 ------------------- .../hexagonal/ui/WeatherForecasterUI.java | 5 -- patterns/pom.xml | 3 +- 9 files changed, 1 insertion(+), 142 deletions(-) delete mode 100644 patterns/hexagonal/pom.xml delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java delete mode 100644 patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java diff --git a/patterns/hexagonal/pom.xml b/patterns/hexagonal/pom.xml deleted file mode 100644 index 7f6cbf176b..0000000000 --- a/patterns/hexagonal/pom.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - 4.0.0 - hexagonal - 1.0 - hexagonal - A quick and practical example of Hexagonal Architecture in Java - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../../parent-java - - - diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java deleted file mode 100644 index fb21f9a877..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/WeatherForecasterApp.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.pattern.hexagonal; - -import com.baeldung.pattern.hexagonal.repository.RepositoryFactory; -import com.baeldung.pattern.hexagonal.repository.WeatherRepository; -import com.baeldung.pattern.hexagonal.service.WeatherForecasterService; -import com.baeldung.pattern.hexagonal.ui.WeatherForecasterConsoleUI; -import com.baeldung.pattern.hexagonal.ui.WeatherForecasterUI; - -public class WeatherForecasterApp { - public static void main(String[] args) { - WeatherRepository repository = RepositoryFactory.getMockWeatherRepository(); - WeatherForecasterService service = new WeatherForecasterService(repository); - WeatherForecasterUI ui = new WeatherForecasterConsoleUI(service); - - ui.start(); - } -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java deleted file mode 100644 index cdb68b9086..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/MockWeatherRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.pattern.hexagonal.repository; - -public class MockWeatherRepository implements WeatherRepository { - @Override - public double getTemperature(String location) { - switch (location) { - case "cluj-napoca": - return 17; - case "bucharest": - return 22; - case "new york": - return 15; - default: - return 20; - } - } -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java deleted file mode 100644 index d1c74f4b6d..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/RepositoryFactory.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.pattern.hexagonal.repository; - -public class RepositoryFactory { - private RepositoryFactory() { - super(); - } - - public static WeatherRepository getMockWeatherRepository() { - return new MockWeatherRepository(); - } -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java deleted file mode 100644 index 4c41c712ec..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/repository/WeatherRepository.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.pattern.hexagonal.repository; - -public interface WeatherRepository { - double getTemperature(String location); -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java deleted file mode 100644 index c39f01235b..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/service/WeatherForecasterService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.pattern.hexagonal.service; - -import com.baeldung.pattern.hexagonal.repository.WeatherRepository; - -public class WeatherForecasterService { - private final WeatherRepository repository; - - public WeatherForecasterService(WeatherRepository repository) { - this.repository = repository; - } - - public double forecast(String location) { - String normalizedLocation = getNormalizedLocation(location); - return repository.getTemperature(normalizedLocation); - } - - private String getNormalizedLocation(String location) { - return location == null ? "" : location.toLowerCase(); - } -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java deleted file mode 100644 index 3877563694..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterConsoleUI.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.baeldung.pattern.hexagonal.ui; - -import com.baeldung.pattern.hexagonal.service.WeatherForecasterService; - -import java.io.PrintStream; -import java.nio.charset.StandardCharsets; -import java.util.Scanner; - -public class WeatherForecasterConsoleUI implements WeatherForecasterUI { - private WeatherForecasterService service; - private Scanner in; - private PrintStream out; - - public WeatherForecasterConsoleUI(WeatherForecasterService service) { - this.service = service; - this.in = new Scanner(System.in); - this.out = new PrintStream(System.out, true, StandardCharsets.UTF_8); - } - - @Override - public void start() { - String input = getInput(); - while (isNotExit(input)) { - showTemperature(input); - input = getInput(); - } - stop(); - } - - private String getInput() { - out.print("Location: "); - return in.nextLine(); - } - - private boolean isNotExit(String input) { - return !input.equalsIgnoreCase("exit"); - } - - private void showTemperature(String input) { - double temperature = service.forecast(input); - out.printf("%.2f\u00B0C%n", temperature); - } - - private void stop() { - in.close(); - out.close(); - } -} diff --git a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java b/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java deleted file mode 100644 index da25cec7bb..0000000000 --- a/patterns/hexagonal/src/main/java/com/baeldung/pattern/hexagonal/ui/WeatherForecasterUI.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.pattern.hexagonal.ui; - -public interface WeatherForecasterUI { - void start(); -} diff --git a/patterns/pom.xml b/patterns/pom.xml index be419ace86..112eecb606 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -1,5 +1,5 @@ - 4.0.0 patterns @@ -22,7 +22,6 @@ cqrs-es front-controller hexagonal-architecture - hexagonal intercepting-filter solid clean-architecture From bf171adee14c8e05aa6b2bcf9bbd94623b562bbc Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Mon, 31 May 2021 15:51:38 +0300 Subject: [PATCH 05/11] BAEL-4856 Download a binary file using OkHttp --- .../BinaryFileDownloadApplication.java | 26 ++++++ .../okhttp/download/BinaryFileDownloader.java | 54 +++++++++++++ .../okhttp/download/BinaryFileWriter.java | 34 ++++++++ .../download/BinaryFileDownloaderTest.java | 80 +++++++++++++++++++ .../okhttp/download/BinaryFileWriterTest.java | 55 +++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java create mode 100644 libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java create mode 100644 libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java create mode 100644 libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java create mode 100644 libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java new file mode 100644 index 0000000000..f350fe6f6e --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java @@ -0,0 +1,26 @@ +package com.baeldung.okhttp.download; + +import okhttp3.OkHttpClient; + +import java.io.FileOutputStream; + +public class BinaryFileDownloadApplication { + + public static void main(String[] args) { + String url = args[0]; + String file = args[1]; + try (BinaryFileDownloader downloader = new BinaryFileDownloader(new OkHttpClient(), + new BinaryFileWriter(new FileOutputStream(file)))) { + long downloadSize = downloader.download(url); + double downloadSizeInMB = convertToMB(downloadSize); + System.out.printf("Successfully downloaded file %s from %s. Total size %.2fMB%n", file, url, downloadSizeInMB); + } catch (Exception ex) { + System.err.printf("Could not download file %s from %s. %nError: %s%n", file, url, ex); + } + } + + private static double convertToMB(double downloadSize) { + return downloadSize / (1024.0 * 1024.0); + } + +} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java new file mode 100644 index 0000000000..f4c98751f4 --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java @@ -0,0 +1,54 @@ +package com.baeldung.okhttp.download; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class BinaryFileDownloader implements AutoCloseable { + + private final OkHttpClient client; + private final BinaryFileWriter writer; + + public BinaryFileDownloader(OkHttpClient client, BinaryFileWriter writer) { + this.client = client; + this.writer = writer; + } + + public long download(String url) throws IOException { + Request request = createRequest(url); + Response response = executeRequest(request); + ResponseBody responseBody = getResponseBodyOrFail(response); + return write(responseBody); + } + + @NotNull + private Request createRequest(String url) { + return new Request.Builder().url(url).build(); + } + + @NotNull + private Response executeRequest(Request request) throws IOException { + return client.newCall(request).execute(); + } + + private ResponseBody getResponseBodyOrFail(Response response) { + ResponseBody responseBody = response.body(); + if (responseBody == null) { + throw new IllegalStateException("Response doesn't contain a file"); + } + return responseBody; + } + + private long write(ResponseBody responseBody) throws IOException { + return writer.write(responseBody.byteStream()); + } + + @Override + public void close() throws Exception { + writer.close(); + } +} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java new file mode 100644 index 0000000000..95f91e26b2 --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java @@ -0,0 +1,34 @@ +package com.baeldung.okhttp.download; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class BinaryFileWriter implements AutoCloseable { + + private static final int CHUNK_SIZE = 1024; + private final OutputStream outputStream; + + public BinaryFileWriter(OutputStream outputStream) { + this.outputStream = outputStream; + } + + public long write(InputStream inputStream) throws IOException { + try (BufferedInputStream input = new BufferedInputStream(inputStream)) { + byte[] dataBuffer = new byte[CHUNK_SIZE]; + int readBytes; + long totalBytes = 0; + while ((readBytes = input.read(dataBuffer)) != -1) { + totalBytes += readBytes; + outputStream.write(dataBuffer, 0, readBytes); + } + return totalBytes; + } + } + + @Override + public void close() throws IOException { + outputStream.close(); + } +} diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java new file mode 100644 index 0000000000..aa189a9ff0 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java @@ -0,0 +1,80 @@ +package com.baeldung.okhttp.download; + +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class BinaryFileDownloaderTest { + + @Mock + private OkHttpClient client; + @Mock + private BinaryFileWriter writer; + @InjectMocks + private BinaryFileDownloader tested; + + @Test + public void givenUrlAndResponse_whenDownload_thenExpectFileWritten() throws Exception { + String url = "http://example.com/file"; + Call call = mock(Call.class); + when(client.newCall(any(Request.class))).thenReturn(call); + ResponseBody body = ResponseBody.create("BODY", MediaType.get("application/text")); + Response response = createResponse(url, body); + when(call.execute()).thenReturn(response); + when(writer.write(any())).thenReturn(1L); + + try (BinaryFileDownloader tested = new BinaryFileDownloader(client, writer)) { + long size = tested.download(url); + assertEquals(1L, size); + verify(writer).write(any(InputStream.class)); + } + verify(writer).close(); + } + + @Test + public void givenUrlAndResponseWithNullBody_whenDownload_thenExpectIllegalStateException() throws Exception { + String url = "http://example.com/file"; + Call call = mock(Call.class); + when(client.newCall(any(Request.class))).thenReturn(call); + Response response = createResponse(url, null); + when(call.execute()).thenReturn(response); + + assertThrows(IllegalStateException.class, () -> tested.download(url)); + + verify(writer, times(0)).write(any(InputStream.class)); + } + + @NotNull + private Response createResponse(String url, ResponseBody body) { + Request request = new Request.Builder().url(url).build(); + return new Response.Builder() + .code(200) + .request(request) + .protocol(Protocol.HTTP_2) + .message("Message") + .body(body) + .build(); + } + +} \ No newline at end of file diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java new file mode 100644 index 0000000000..b74b2d1987 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java @@ -0,0 +1,55 @@ +package com.baeldung.okhttp.download; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.InputStream; +import java.io.OutputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class BinaryFileWriterTest { + + @Mock + private OutputStream outputStream; + + @Test + public void givenInputStream_whenWrite_thenExpectWritten() throws Exception { + InputStream inputStream = mock(InputStream.class); + when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1); + + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { + long result = tested.write(inputStream); + + assertEquals(10, result); + verify(outputStream).write(any(), eq(0), eq(10)); + verify(inputStream).close(); + } + verify(outputStream).close(); + } + + @Test + public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception { + InputStream inputStream = mock(InputStream.class); + + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { + long result = tested.write(inputStream); + + assertEquals(0, result); + verify(outputStream, times(0)).write(any(), anyInt(), anyInt()); + verify(inputStream).close(); + } + verify(outputStream).close(); + } + +} \ No newline at end of file From 4e8e10b5f9b047e434a4c4466d9f8d9b7be6715c Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Mon, 31 May 2021 16:02:20 +0300 Subject: [PATCH 06/11] BAEL-4856 Update test names --- ...ileDownloaderTest.java => BinaryFileDownloaderUnitTest.java} | 2 +- ...{BinaryFileWriterTest.java => BinaryFileWriterUnitTest.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename libraries-http-2/src/test/java/com/baeldung/okhttp/download/{BinaryFileDownloaderTest.java => BinaryFileDownloaderUnitTest.java} (98%) rename libraries-http-2/src/test/java/com/baeldung/okhttp/download/{BinaryFileWriterTest.java => BinaryFileWriterUnitTest.java} (97%) diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java similarity index 98% rename from libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java rename to libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java index aa189a9ff0..5472eaefee 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java @@ -25,7 +25,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) -public class BinaryFileDownloaderTest { +public class BinaryFileDownloaderUnitTest { @Mock private OkHttpClient client; diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java similarity index 97% rename from libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java rename to libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java index b74b2d1987..51012311da 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java @@ -18,7 +18,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) -public class BinaryFileWriterTest { +public class BinaryFileWriterUnitTest { @Mock private OutputStream outputStream; From f5c92c40f6ba7073f263e2ad1a8b38c778538dd0 Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Thu, 3 Jun 2021 18:13:09 +0300 Subject: [PATCH 07/11] BAEL-4856 Remove BinaryFileDownloadApplication.java and use correct indentation --- .../BinaryFileDownloadApplication.java | 26 ------- .../okhttp/download/BinaryFileDownloader.java | 74 +++++++++--------- .../okhttp/download/BinaryFileWriter.java | 42 +++++----- .../BinaryFileDownloaderUnitTest.java | 78 +++++++++---------- .../download/BinaryFileWriterUnitTest.java | 46 +++++------ 5 files changed, 117 insertions(+), 149 deletions(-) delete mode 100644 libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java deleted file mode 100644 index f350fe6f6e..0000000000 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloadApplication.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.baeldung.okhttp.download; - -import okhttp3.OkHttpClient; - -import java.io.FileOutputStream; - -public class BinaryFileDownloadApplication { - - public static void main(String[] args) { - String url = args[0]; - String file = args[1]; - try (BinaryFileDownloader downloader = new BinaryFileDownloader(new OkHttpClient(), - new BinaryFileWriter(new FileOutputStream(file)))) { - long downloadSize = downloader.download(url); - double downloadSizeInMB = convertToMB(downloadSize); - System.out.printf("Successfully downloaded file %s from %s. Total size %.2fMB%n", file, url, downloadSizeInMB); - } catch (Exception ex) { - System.err.printf("Could not download file %s from %s. %nError: %s%n", file, url, ex); - } - } - - private static double convertToMB(double downloadSize) { - return downloadSize / (1024.0 * 1024.0); - } - -} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java index f4c98751f4..e9fb42185b 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java @@ -10,45 +10,45 @@ import java.io.IOException; public class BinaryFileDownloader implements AutoCloseable { - private final OkHttpClient client; - private final BinaryFileWriter writer; + private final OkHttpClient client; + private final BinaryFileWriter writer; - public BinaryFileDownloader(OkHttpClient client, BinaryFileWriter writer) { - this.client = client; - this.writer = writer; - } - - public long download(String url) throws IOException { - Request request = createRequest(url); - Response response = executeRequest(request); - ResponseBody responseBody = getResponseBodyOrFail(response); - return write(responseBody); - } - - @NotNull - private Request createRequest(String url) { - return new Request.Builder().url(url).build(); - } - - @NotNull - private Response executeRequest(Request request) throws IOException { - return client.newCall(request).execute(); - } - - private ResponseBody getResponseBodyOrFail(Response response) { - ResponseBody responseBody = response.body(); - if (responseBody == null) { - throw new IllegalStateException("Response doesn't contain a file"); + public BinaryFileDownloader(OkHttpClient client, BinaryFileWriter writer) { + this.client = client; + this.writer = writer; } - return responseBody; - } - private long write(ResponseBody responseBody) throws IOException { - return writer.write(responseBody.byteStream()); - } + public long download(String url) throws IOException { + Request request = createRequest(url); + Response response = executeRequest(request); + ResponseBody responseBody = getResponseBodyOrFail(response); + return write(responseBody); + } - @Override - public void close() throws Exception { - writer.close(); - } + @NotNull + private Request createRequest(String url) { + return new Request.Builder().url(url).build(); + } + + @NotNull + private Response executeRequest(Request request) throws IOException { + return client.newCall(request).execute(); + } + + private ResponseBody getResponseBodyOrFail(Response response) { + ResponseBody responseBody = response.body(); + if (responseBody == null) { + throw new IllegalStateException("Response doesn't contain a file"); + } + return responseBody; + } + + private long write(ResponseBody responseBody) throws IOException { + return writer.write(responseBody.byteStream()); + } + + @Override + public void close() throws Exception { + writer.close(); + } } diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java index 95f91e26b2..653cd07449 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java @@ -7,28 +7,28 @@ import java.io.OutputStream; public class BinaryFileWriter implements AutoCloseable { - private static final int CHUNK_SIZE = 1024; - private final OutputStream outputStream; + private static final int CHUNK_SIZE = 1024; + private final OutputStream outputStream; - public BinaryFileWriter(OutputStream outputStream) { - this.outputStream = outputStream; - } - - public long write(InputStream inputStream) throws IOException { - try (BufferedInputStream input = new BufferedInputStream(inputStream)) { - byte[] dataBuffer = new byte[CHUNK_SIZE]; - int readBytes; - long totalBytes = 0; - while ((readBytes = input.read(dataBuffer)) != -1) { - totalBytes += readBytes; - outputStream.write(dataBuffer, 0, readBytes); - } - return totalBytes; + public BinaryFileWriter(OutputStream outputStream) { + this.outputStream = outputStream; } - } - @Override - public void close() throws IOException { - outputStream.close(); - } + public long write(InputStream inputStream) throws IOException { + try (BufferedInputStream input = new BufferedInputStream(inputStream)) { + byte[] dataBuffer = new byte[CHUNK_SIZE]; + int readBytes; + long totalBytes = 0; + while ((readBytes = input.read(dataBuffer)) != -1) { + totalBytes += readBytes; + outputStream.write(dataBuffer, 0, readBytes); + } + return totalBytes; + } + } + + @Override + public void close() throws IOException { + outputStream.close(); + } } diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java index 5472eaefee..6a7d7aca7e 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java @@ -27,54 +27,48 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class BinaryFileDownloaderUnitTest { - @Mock - private OkHttpClient client; - @Mock - private BinaryFileWriter writer; - @InjectMocks - private BinaryFileDownloader tested; + @Mock + private OkHttpClient client; + @Mock + private BinaryFileWriter writer; + @InjectMocks + private BinaryFileDownloader tested; - @Test - public void givenUrlAndResponse_whenDownload_thenExpectFileWritten() throws Exception { - String url = "http://example.com/file"; - Call call = mock(Call.class); - when(client.newCall(any(Request.class))).thenReturn(call); - ResponseBody body = ResponseBody.create("BODY", MediaType.get("application/text")); - Response response = createResponse(url, body); - when(call.execute()).thenReturn(response); - when(writer.write(any())).thenReturn(1L); + @Test + public void givenUrlAndResponse_whenDownload_thenExpectFileWritten() throws Exception { + String url = "http://example.com/file"; + Call call = mock(Call.class); + when(client.newCall(any(Request.class))).thenReturn(call); + ResponseBody body = ResponseBody.create("BODY", MediaType.get("application/text")); + Response response = createResponse(url, body); + when(call.execute()).thenReturn(response); + when(writer.write(any())).thenReturn(1L); - try (BinaryFileDownloader tested = new BinaryFileDownloader(client, writer)) { - long size = tested.download(url); - assertEquals(1L, size); - verify(writer).write(any(InputStream.class)); + try (BinaryFileDownloader tested = new BinaryFileDownloader(client, writer)) { + long size = tested.download(url); + assertEquals(1L, size); + verify(writer).write(any(InputStream.class)); + } + verify(writer).close(); } - verify(writer).close(); - } - @Test - public void givenUrlAndResponseWithNullBody_whenDownload_thenExpectIllegalStateException() throws Exception { - String url = "http://example.com/file"; - Call call = mock(Call.class); - when(client.newCall(any(Request.class))).thenReturn(call); - Response response = createResponse(url, null); - when(call.execute()).thenReturn(response); + @Test + public void givenUrlAndResponseWithNullBody_whenDownload_thenExpectIllegalStateException() throws Exception { + String url = "http://example.com/file"; + Call call = mock(Call.class); + when(client.newCall(any(Request.class))).thenReturn(call); + Response response = createResponse(url, null); + when(call.execute()).thenReturn(response); - assertThrows(IllegalStateException.class, () -> tested.download(url)); + assertThrows(IllegalStateException.class, () -> tested.download(url)); - verify(writer, times(0)).write(any(InputStream.class)); - } + verify(writer, times(0)).write(any(InputStream.class)); + } - @NotNull - private Response createResponse(String url, ResponseBody body) { - Request request = new Request.Builder().url(url).build(); - return new Response.Builder() - .code(200) - .request(request) - .protocol(Protocol.HTTP_2) - .message("Message") - .body(body) - .build(); - } + @NotNull + private Response createResponse(String url, ResponseBody body) { + Request request = new Request.Builder().url(url).build(); + return new Response.Builder().code(200).request(request).protocol(Protocol.HTTP_2).message("Message").body(body).build(); + } } \ No newline at end of file diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java index 51012311da..e4b823f843 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java @@ -20,36 +20,36 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class BinaryFileWriterUnitTest { - @Mock - private OutputStream outputStream; + @Mock + private OutputStream outputStream; - @Test - public void givenInputStream_whenWrite_thenExpectWritten() throws Exception { - InputStream inputStream = mock(InputStream.class); - when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1); + @Test + public void givenInputStream_whenWrite_thenExpectWritten() throws Exception { + InputStream inputStream = mock(InputStream.class); + when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { - long result = tested.write(inputStream); + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { + long result = tested.write(inputStream); - assertEquals(10, result); - verify(outputStream).write(any(), eq(0), eq(10)); - verify(inputStream).close(); + assertEquals(10, result); + verify(outputStream).write(any(), eq(0), eq(10)); + verify(inputStream).close(); + } + verify(outputStream).close(); } - verify(outputStream).close(); - } - @Test - public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception { - InputStream inputStream = mock(InputStream.class); + @Test + public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception { + InputStream inputStream = mock(InputStream.class); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { - long result = tested.write(inputStream); + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { + long result = tested.write(inputStream); - assertEquals(0, result); - verify(outputStream, times(0)).write(any(), anyInt(), anyInt()); - verify(inputStream).close(); + assertEquals(0, result); + verify(outputStream, times(0)).write(any(), anyInt(), anyInt()); + verify(inputStream).close(); + } + verify(outputStream).close(); } - verify(outputStream).close(); - } } \ No newline at end of file From a67bfd3b9fa204215734a077da9ad24d32be9f3b Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Sat, 5 Jun 2021 15:33:25 +0300 Subject: [PATCH 08/11] BAEL-4856 Integrate progress when downloading --- .../okhttp/download/BinaryFileDownloader.java | 14 +++++-- .../okhttp/download/BinaryFileWriter.java | 7 +++- .../okhttp/download/ProgressCallable.java | 7 ++++ .../BinaryFileDownloaderIntegrationTest.java | 37 +++++++++++++++++++ .../BinaryFileDownloaderUnitTest.java | 7 ++-- .../download/BinaryFileWriterUnitTest.java | 8 ++-- 6 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java create mode 100644 libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java index e9fb42185b..a2e02c3be8 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java @@ -7,6 +7,9 @@ import okhttp3.ResponseBody; import org.jetbrains.annotations.NotNull; import java.io.IOException; +import java.util.Objects; + +import static org.springframework.http.HttpHeaders.CONTENT_LENGTH; public class BinaryFileDownloader implements AutoCloseable { @@ -22,7 +25,8 @@ public class BinaryFileDownloader implements AutoCloseable { Request request = createRequest(url); Response response = executeRequest(request); ResponseBody responseBody = getResponseBodyOrFail(response); - return write(responseBody); + double length = getResponseLength(response); + return write(responseBody, length); } @NotNull @@ -43,8 +47,12 @@ public class BinaryFileDownloader implements AutoCloseable { return responseBody; } - private long write(ResponseBody responseBody) throws IOException { - return writer.write(responseBody.byteStream()); + private double getResponseLength(Response response) { + return Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1"))); + } + + private long write(ResponseBody responseBody, double length) throws IOException { + return writer.write(responseBody.byteStream(), length); } @Override diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java index 653cd07449..274778b952 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java @@ -9,12 +9,14 @@ public class BinaryFileWriter implements AutoCloseable { private static final int CHUNK_SIZE = 1024; private final OutputStream outputStream; + private final ProgressCallable progressCallable; - public BinaryFileWriter(OutputStream outputStream) { + public BinaryFileWriter(OutputStream outputStream, ProgressCallable progressCallable) { this.outputStream = outputStream; + this.progressCallable = progressCallable; } - public long write(InputStream inputStream) throws IOException { + public long write(InputStream inputStream, double length) throws IOException { try (BufferedInputStream input = new BufferedInputStream(inputStream)) { byte[] dataBuffer = new byte[CHUNK_SIZE]; int readBytes; @@ -22,6 +24,7 @@ public class BinaryFileWriter implements AutoCloseable { while ((readBytes = input.read(dataBuffer)) != -1) { totalBytes += readBytes; outputStream.write(dataBuffer, 0, readBytes); + progressCallable.onProgress(totalBytes / length * 100.0); } return totalBytes; } diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java new file mode 100644 index 0000000000..8e1569a1c2 --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java @@ -0,0 +1,7 @@ +package com.baeldung.okhttp.download; + +public interface ProgressCallable { + + void onProgress(double progress); + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java new file mode 100644 index 0000000000..4fa6c0a466 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java @@ -0,0 +1,37 @@ +package com.baeldung.okhttp.download; + +import okhttp3.OkHttpClient; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.Rule; +import org.junit.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class BinaryFileDownloaderIntegrationTest { + + @Rule + public MockWebServer server = new MockWebServer(); + + @Test + public void givenATextFile_whenDownload_thenExpectFileDownloaded() throws IOException { + String body = "Hello Baeldung Readers!"; + server.enqueue(new MockResponse().setBody(body)); + String fileName = "download.txt"; + BinaryFileWriter writer = new BinaryFileWriter(new FileOutputStream(fileName), progress -> assertEquals(100.0, progress, .0)); + BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer); + + long downloaded = tested.download(server.url("/greetings").toString()); + + assertEquals(body.length(), downloaded); + File downloadedFile = new File(fileName); + assertTrue(downloadedFile.isFile()); + assertTrue(downloadedFile.delete()); + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java index 6a7d7aca7e..20240febb3 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java @@ -19,6 +19,7 @@ import java.io.InputStream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -42,12 +43,12 @@ public class BinaryFileDownloaderUnitTest { ResponseBody body = ResponseBody.create("BODY", MediaType.get("application/text")); Response response = createResponse(url, body); when(call.execute()).thenReturn(response); - when(writer.write(any())).thenReturn(1L); + when(writer.write(any(), anyDouble())).thenReturn(1L); try (BinaryFileDownloader tested = new BinaryFileDownloader(client, writer)) { long size = tested.download(url); assertEquals(1L, size); - verify(writer).write(any(InputStream.class)); + verify(writer).write(any(InputStream.class), anyDouble()); } verify(writer).close(); } @@ -62,7 +63,7 @@ public class BinaryFileDownloaderUnitTest { assertThrows(IllegalStateException.class, () -> tested.download(url)); - verify(writer, times(0)).write(any(InputStream.class)); + verify(writer, times(0)).write(any(InputStream.class), anyDouble()); } @NotNull diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java index e4b823f843..19e3d321c2 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java @@ -28,8 +28,8 @@ public class BinaryFileWriterUnitTest { InputStream inputStream = mock(InputStream.class); when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { - long result = tested.write(inputStream); + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) { + long result = tested.write(inputStream, 10); assertEquals(10, result); verify(outputStream).write(any(), eq(0), eq(10)); @@ -42,8 +42,8 @@ public class BinaryFileWriterUnitTest { public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception { InputStream inputStream = mock(InputStream.class); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream)) { - long result = tested.write(inputStream); + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) { + long result = tested.write(inputStream, 1); assertEquals(0, result); verify(outputStream, times(0)).write(any(), anyInt(), anyInt()); From 146291f5351754910b553ea3502b95a500b2c73b Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Sat, 5 Jun 2021 15:49:46 +0300 Subject: [PATCH 09/11] BAEL-4856 Rename ProgressCallable to ProgressCallback --- .../com/baeldung/okhttp/download/BinaryFileWriter.java | 8 ++++---- .../{ProgressCallable.java => ProgressCallback.java} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename libraries-http-2/src/main/java/com/baeldung/okhttp/download/{ProgressCallable.java => ProgressCallback.java} (69%) diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java index 274778b952..fb3664c08e 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileWriter.java @@ -9,11 +9,11 @@ public class BinaryFileWriter implements AutoCloseable { private static final int CHUNK_SIZE = 1024; private final OutputStream outputStream; - private final ProgressCallable progressCallable; + private final ProgressCallback progressCallback; - public BinaryFileWriter(OutputStream outputStream, ProgressCallable progressCallable) { + public BinaryFileWriter(OutputStream outputStream, ProgressCallback progressCallback) { this.outputStream = outputStream; - this.progressCallable = progressCallable; + this.progressCallback = progressCallback; } public long write(InputStream inputStream, double length) throws IOException { @@ -24,7 +24,7 @@ public class BinaryFileWriter implements AutoCloseable { while ((readBytes = input.read(dataBuffer)) != -1) { totalBytes += readBytes; outputStream.write(dataBuffer, 0, readBytes); - progressCallable.onProgress(totalBytes / length * 100.0); + progressCallback.onProgress(totalBytes / length * 100.0); } return totalBytes; } diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallback.java similarity index 69% rename from libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java rename to libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallback.java index 8e1569a1c2..b57cabf854 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallable.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/ProgressCallback.java @@ -1,6 +1,6 @@ package com.baeldung.okhttp.download; -public interface ProgressCallable { +public interface ProgressCallback { void onProgress(double progress); From 9dcb5147b528c1e5fcdd00d463a49c799c0c71ad Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Sun, 6 Jun 2021 17:55:51 +0300 Subject: [PATCH 10/11] BAEL-4856 Code review --- .../BinaryFileDownloaderIntegrationTest.java | 22 ++++++++++--------- .../BinaryFileDownloaderUnitTest.java | 7 +++--- .../download/BinaryFileWriterUnitTest.java | 6 ++--- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java index 4fa6c0a466..6f0f705350 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderIntegrationTest.java @@ -8,10 +8,10 @@ import org.junit.Test; import java.io.File; import java.io.FileOutputStream; -import java.io.IOException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class BinaryFileDownloaderIntegrationTest { @@ -19,19 +19,21 @@ public class BinaryFileDownloaderIntegrationTest { public MockWebServer server = new MockWebServer(); @Test - public void givenATextFile_whenDownload_thenExpectFileDownloaded() throws IOException { + public void givenATextFile_whenDownload_thenExpectFileDownloaded() { String body = "Hello Baeldung Readers!"; server.enqueue(new MockResponse().setBody(body)); String fileName = "download.txt"; - BinaryFileWriter writer = new BinaryFileWriter(new FileOutputStream(fileName), progress -> assertEquals(100.0, progress, .0)); - BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer); - long downloaded = tested.download(server.url("/greetings").toString()); - - assertEquals(body.length(), downloaded); - File downloadedFile = new File(fileName); - assertTrue(downloadedFile.isFile()); - assertTrue(downloadedFile.delete()); + ProgressCallback progressCallback = progress -> assertEquals(100.0, progress, .0); + try (BinaryFileWriter writer = new BinaryFileWriter(new FileOutputStream(fileName), progressCallback); BinaryFileDownloader tested = new BinaryFileDownloader(new OkHttpClient(), writer)) { + long downloaded = tested.download(server.url("/greetings").toString()); + assertEquals(body.length(), downloaded); + File downloadedFile = new File(fileName); + assertTrue(downloadedFile.isFile()); + assertTrue(downloadedFile.delete()); + } catch (Exception e) { + fail("An unexpected exception has occurred: " + e); + } } } diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java index 20240febb3..15dda3a471 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileDownloaderUnitTest.java @@ -16,8 +16,7 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.InputStream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.Mockito.mock; @@ -53,7 +52,7 @@ public class BinaryFileDownloaderUnitTest { verify(writer).close(); } - @Test + @Test(expected = IllegalStateException.class) public void givenUrlAndResponseWithNullBody_whenDownload_thenExpectIllegalStateException() throws Exception { String url = "http://example.com/file"; Call call = mock(Call.class); @@ -61,7 +60,7 @@ public class BinaryFileDownloaderUnitTest { Response response = createResponse(url, null); when(call.execute()).thenReturn(response); - assertThrows(IllegalStateException.class, () -> tested.download(url)); + tested.download(url); verify(writer, times(0)).write(any(InputStream.class), anyDouble()); } diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java index 19e3d321c2..2b3f0a1313 100644 --- a/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/download/BinaryFileWriterUnitTest.java @@ -8,7 +8,7 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.InputStream; import java.io.OutputStream; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -28,7 +28,7 @@ public class BinaryFileWriterUnitTest { InputStream inputStream = mock(InputStream.class); when(inputStream.read(any(), anyInt(), anyInt())).thenReturn(10, -1); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) { + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress, .0))) { long result = tested.write(inputStream, 10); assertEquals(10, result); @@ -42,7 +42,7 @@ public class BinaryFileWriterUnitTest { public void givenInputStreamEmpty_whenWrite_thenExpectNotWritten() throws Exception { InputStream inputStream = mock(InputStream.class); - try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress))) { + try (BinaryFileWriter tested = new BinaryFileWriter(outputStream, progress -> assertEquals(100.0, progress, .0))) { long result = tested.write(inputStream, 1); assertEquals(0, result); From 4f01c374b97e360c9415e8a4beb0d217d9b2fb1e Mon Sep 17 00:00:00 2001 From: Iulian Manda Date: Wed, 16 Jun 2021 19:19:45 +0300 Subject: [PATCH 11/11] BAEL-4856 Code review --- .../okhttp/download/BinaryFileDownloader.java | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java index a2e02c3be8..a7ef60f124 100644 --- a/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/download/BinaryFileDownloader.java @@ -4,7 +4,6 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; -import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.Objects; @@ -22,36 +21,13 @@ public class BinaryFileDownloader implements AutoCloseable { } public long download(String url) throws IOException { - Request request = createRequest(url); - Response response = executeRequest(request); - ResponseBody responseBody = getResponseBodyOrFail(response); - double length = getResponseLength(response); - return write(responseBody, length); - } - - @NotNull - private Request createRequest(String url) { - return new Request.Builder().url(url).build(); - } - - @NotNull - private Response executeRequest(Request request) throws IOException { - return client.newCall(request).execute(); - } - - private ResponseBody getResponseBodyOrFail(Response response) { + Request request = new Request.Builder().url(url).build(); + Response response = client.newCall(request).execute(); ResponseBody responseBody = response.body(); if (responseBody == null) { throw new IllegalStateException("Response doesn't contain a file"); } - return responseBody; - } - - private double getResponseLength(Response response) { - return Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1"))); - } - - private long write(ResponseBody responseBody, double length) throws IOException { + double length = Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1"))); return writer.write(responseBody.byteStream(), length); }