From 78d8f62ef7f5453f02522eba2999b124338bc126 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 26 Sep 2023 10:05:04 +0700 Subject: [PATCH 01/13] [Add] completablefuture timeout test --- .../core-java-concurrency-simple/pom.xml | 9 ++ .../CompletableFutureTimeoutUnitTest.java | 83 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java diff --git a/core-java-modules/core-java-concurrency-simple/pom.xml b/core-java-modules/core-java-concurrency-simple/pom.xml index a16df4fc97..720ab5a0ed 100644 --- a/core-java-modules/core-java-concurrency-simple/pom.xml +++ b/core-java-modules/core-java-concurrency-simple/pom.xml @@ -12,6 +12,15 @@ 0.0.1-SNAPSHOT + + + org.wiremock + wiremock + 3.1.0 + test + + + core-java-concurrency-simple diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java new file mode 100644 index 0000000000..f54e5f4af5 --- /dev/null +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.concurrent.completablefuture; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.*; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +public class CompletableFutureTimeoutUnitTest { + private static WireMockServer wireMockServer; + private static ScheduledExecutorService executorService; + private static final int DEFAULT_TIMEOUT = 500; //0.5 seconds + private static final int TIMEOUT_STATUS_CODE = 408; //0.5 seconds + + @BeforeAll + public static void setUp() { + wireMockServer = new WireMockServer(8080); + wireMockServer.start(); + WireMock.configureFor("localhost", 8080); + + stubFor(get(urlEqualTo("/api/dummy")) + .willReturn(aResponse() + .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. + .withStatus(408))); + + executorService = Executors.newScheduledThreadPool(1); + } + + + @AfterAll + public static void tearDown() { + executorService.shutdown(); + wireMockServer.stop(); + } + + private CompletableFuture createDummyRequest() { + return CompletableFuture.supplyAsync(() -> { + try { + URL url = new URL("http://localhost:8080/api/dummy"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + try { + return connection.getResponseCode(); + } finally { + connection.disconnect(); + } + } catch (IOException e) { + return TIMEOUT_STATUS_CODE; + } + }); + } + + @Test + public void whenorTimeout_thenGetThrow() { + CompletableFuture completableFuture = createDummyRequest() + .orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertThrows(ExecutionException.class, completableFuture::get); + } + + @Test + public void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = createDummyRequest() + .completeOnTimeout(TIMEOUT_STATUS_CODE, DEFAULT_TIMEOUT, + TimeUnit.MILLISECONDS); + assertEquals(TIMEOUT_STATUS_CODE, completableFuture.get()); + } + + @Test + public void whencompleteExceptionally_thenGetThrow() { + CompletableFuture completableFuture = createDummyRequest(); + executorService.schedule(() -> completableFuture + .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertThrows(ExecutionException.class, completableFuture::get); + } + +} From e9536ff0c4709a54c89d5b3f08e58c29bb7dd62b Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Wed, 27 Sep 2023 09:20:07 +0700 Subject: [PATCH 02/13] [Update] set DEFAULT_TIMEOUT to 1000 --- .../completablefuture/CompletableFutureTimeoutUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index f54e5f4af5..43b8075ebd 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -17,7 +17,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class CompletableFutureTimeoutUnitTest { private static WireMockServer wireMockServer; private static ScheduledExecutorService executorService; - private static final int DEFAULT_TIMEOUT = 500; //0.5 seconds + private static final int DEFAULT_TIMEOUT = 1000; //1 seconds private static final int TIMEOUT_STATUS_CODE = 408; //0.5 seconds @BeforeAll From 05f4487d6357ebfc6eb017b026483876a9e6bd02 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Sun, 8 Oct 2023 05:12:47 +0700 Subject: [PATCH 03/13] [Update] no need to be public --- .../CompletableFutureTimeoutUnitTest.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 43b8075ebd..99f572f25a 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -14,14 +14,15 @@ import java.util.concurrent.*; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -public class CompletableFutureTimeoutUnitTest { + +class CompletableFutureTimeoutUnitTest { private static WireMockServer wireMockServer; private static ScheduledExecutorService executorService; private static final int DEFAULT_TIMEOUT = 1000; //1 seconds private static final int TIMEOUT_STATUS_CODE = 408; //0.5 seconds @BeforeAll - public static void setUp() { + static void setUp() { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); @@ -36,7 +37,7 @@ public class CompletableFutureTimeoutUnitTest { @AfterAll - public static void tearDown() { + static void tearDown() { executorService.shutdown(); wireMockServer.stop(); } @@ -58,14 +59,14 @@ public class CompletableFutureTimeoutUnitTest { } @Test - public void whenorTimeout_thenGetThrow() { + void whenorTimeout_thenGetThrow() { CompletableFuture completableFuture = createDummyRequest() .orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); assertThrows(ExecutionException.class, completableFuture::get); } @Test - public void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { + void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { CompletableFuture completableFuture = createDummyRequest() .completeOnTimeout(TIMEOUT_STATUS_CODE, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); @@ -73,7 +74,7 @@ public class CompletableFutureTimeoutUnitTest { } @Test - public void whencompleteExceptionally_thenGetThrow() { + void whencompleteExceptionally_thenGetThrow() { CompletableFuture completableFuture = createDummyRequest(); executorService.schedule(() -> completableFuture .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); From 92d038dc3caca20feb9cd72293fbca02e99daca6 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Sun, 8 Oct 2023 20:33:43 +0700 Subject: [PATCH 04/13] add default --- .../CompletableFutureTimeoutUnitTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 99f572f25a..f41730f7df 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -81,4 +81,16 @@ class CompletableFutureTimeoutUnitTest { assertThrows(ExecutionException.class, completableFuture::get); } + @Test + void whencompletableDefault_thenGetReturn() { + CompletableFuture completableFuture = createDummyRequest(); + try { + int result = completableFuture.get(); + assertEquals(TIMEOUT_STATUS_CODE, result); + } catch (InterruptedException | ExecutionException e) { + //System.out.println("ERROR->"+e.getMessage()); + throw new RuntimeException(e); + } + } + } From 70e6dcd47b4eea4c9f6b57265ff114f4d5f03644 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Mon, 9 Oct 2023 20:16:40 +0700 Subject: [PATCH 05/13] non static --- .../CompletableFutureTimeoutUnitTest.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index f41730f7df..449ebc5bbc 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -80,17 +80,4 @@ class CompletableFutureTimeoutUnitTest { .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); assertThrows(ExecutionException.class, completableFuture::get); } - - @Test - void whencompletableDefault_thenGetReturn() { - CompletableFuture completableFuture = createDummyRequest(); - try { - int result = completableFuture.get(); - assertEquals(TIMEOUT_STATUS_CODE, result); - } catch (InterruptedException | ExecutionException e) { - //System.out.println("ERROR->"+e.getMessage()); - throw new RuntimeException(e); - } - } - } From e3ef6b62759b7651fac57ab072fdc5a92c7c614a Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Mon, 9 Oct 2023 20:40:45 +0700 Subject: [PATCH 06/13] [Update] non static --- .../CompletableFutureTimeoutUnitTest.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 449ebc5bbc..8070ef620a 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -5,6 +5,7 @@ import com.github.tomakehurst.wiremock.client.WireMock; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import java.io.IOException; import java.net.HttpURLConnection; @@ -15,14 +16,15 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class CompletableFutureTimeoutUnitTest { - private static WireMockServer wireMockServer; - private static ScheduledExecutorService executorService; + private WireMockServer wireMockServer; + private ScheduledExecutorService executorService; private static final int DEFAULT_TIMEOUT = 1000; //1 seconds private static final int TIMEOUT_STATUS_CODE = 408; //0.5 seconds @BeforeAll - static void setUp() { + void setUp() { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); @@ -37,7 +39,7 @@ class CompletableFutureTimeoutUnitTest { @AfterAll - static void tearDown() { + void tearDown() { executorService.shutdown(); wireMockServer.stop(); } @@ -52,7 +54,7 @@ class CompletableFutureTimeoutUnitTest { } finally { connection.disconnect(); } - } catch (IOException e) { + } catch (Exception e) { return TIMEOUT_STATUS_CODE; } }); @@ -60,16 +62,15 @@ class CompletableFutureTimeoutUnitTest { @Test void whenorTimeout_thenGetThrow() { - CompletableFuture completableFuture = createDummyRequest() - .orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + CompletableFuture completableFuture = createDummyRequest(); + completableFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); assertThrows(ExecutionException.class, completableFuture::get); } @Test void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { - CompletableFuture completableFuture = createDummyRequest() - .completeOnTimeout(TIMEOUT_STATUS_CODE, DEFAULT_TIMEOUT, - TimeUnit.MILLISECONDS); + CompletableFuture completableFuture = createDummyRequest(); + completableFuture.completeOnTimeout(TIMEOUT_STATUS_CODE, DEFAULT_TIMEOUT,TimeUnit.MILLISECONDS); assertEquals(TIMEOUT_STATUS_CODE, completableFuture.get()); } From 7e924cefe4a2bb82bd54100095ed2e486e238196 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Mon, 16 Oct 2023 17:31:19 +0700 Subject: [PATCH 07/13] [update] method name, result, flow --- .../CompletableFutureTimeoutUnitTest.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 8070ef620a..a332f816b2 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -7,7 +7,9 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.*; @@ -21,18 +23,19 @@ class CompletableFutureTimeoutUnitTest { private WireMockServer wireMockServer; private ScheduledExecutorService executorService; private static final int DEFAULT_TIMEOUT = 1000; //1 seconds - private static final int TIMEOUT_STATUS_CODE = 408; //0.5 seconds + private static final String DEFAULT_PRODUCT = "default_product"; + private static final String PRODUCT_OFFERS = "product_offers"; @BeforeAll void setUp() { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); - + System.out.println("stubing"); stubFor(get(urlEqualTo("/api/dummy")) .willReturn(aResponse() .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. - .withStatus(408))); + .withBody(PRODUCT_OFFERS))); executorService = Executors.newScheduledThreadPool(1); } @@ -44,39 +47,47 @@ class CompletableFutureTimeoutUnitTest { wireMockServer.stop(); } - private CompletableFuture createDummyRequest() { + private CompletableFuture fetchProductData() { return CompletableFuture.supplyAsync(() -> { try { URL url = new URL("http://localhost:8080/api/dummy"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { - return connection.getResponseCode(); + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + return response.toString(); } finally { connection.disconnect(); } - } catch (Exception e) { - return TIMEOUT_STATUS_CODE; + } catch (IOException e) { + return ""; } }); } @Test void whenorTimeout_thenGetThrow() { - CompletableFuture completableFuture = createDummyRequest(); + CompletableFuture completableFuture = fetchProductData(); completableFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); assertThrows(ExecutionException.class, completableFuture::get); } @Test void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { - CompletableFuture completableFuture = createDummyRequest(); - completableFuture.completeOnTimeout(TIMEOUT_STATUS_CODE, DEFAULT_TIMEOUT,TimeUnit.MILLISECONDS); - assertEquals(TIMEOUT_STATUS_CODE, completableFuture.get()); + CompletableFuture completableFuture = fetchProductData(); + completableFuture.completeOnTimeout(DEFAULT_PRODUCT, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertEquals(DEFAULT_PRODUCT, completableFuture.get()); } @Test void whencompleteExceptionally_thenGetThrow() { - CompletableFuture completableFuture = createDummyRequest(); + CompletableFuture completableFuture = fetchProductData(); executorService.schedule(() -> completableFuture .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); assertThrows(ExecutionException.class, completableFuture::get); From c1f53973cd2ae694d7c672fb5f105bea888c31cc Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Mon, 16 Oct 2023 18:33:15 +0700 Subject: [PATCH 08/13] [Update] clean trash --- .../completablefuture/CompletableFutureTimeoutUnitTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index a332f816b2..c1de38ad37 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -31,7 +31,7 @@ class CompletableFutureTimeoutUnitTest { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); - System.out.println("stubing"); + stubFor(get(urlEqualTo("/api/dummy")) .willReturn(aResponse() .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. @@ -61,6 +61,7 @@ class CompletableFutureTimeoutUnitTest { response.append(inputLine); } in.close(); + return response.toString(); } finally { connection.disconnect(); From 2efe2c7987e399c75e52c0eb528e47a81838ed4d Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 17 Oct 2023 13:50:31 +0700 Subject: [PATCH 09/13] using json body for sample --- .../CompletableFutureTimeoutUnitTest.java | 93 ++++++++++++++++++- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index c1de38ad37..62cf00930b 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -1,7 +1,9 @@ package com.baeldung.concurrent.completablefuture; +import com.fasterxml.jackson.databind.JsonNode; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; +import net.minidev.json.writer.JsonReader; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -13,6 +15,7 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.*; +import java.util.function.Supplier; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -23,8 +26,93 @@ class CompletableFutureTimeoutUnitTest { private WireMockServer wireMockServer; private ScheduledExecutorService executorService; private static final int DEFAULT_TIMEOUT = 1000; //1 seconds - private static final String DEFAULT_PRODUCT = "default_product"; - private static final String PRODUCT_OFFERS = "product_offers"; + private static final String DEFAULT_PRODUCT = "{\n" + + " \"products\": [\n" + + " {\n" + + " \"id\": 2,\n" + + " \"title\": \"iPhone X\",\n" + + " \"description\": \"SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...\",\n" + + " \"price\": 899,\n" + + " \"discountPercentage\": 0.0,\n" + + " \"rating\": 4.44,\n" + + " \"stock\": 34,\n" + + " \"brand\": \"Apple\",\n" + + " \"category\": \"smartphones\"\n" + + " },\n" + + " {\n" + + " \"id\": 3,\n" + + " \"title\": \"Samsung Universe 9\",\n" + + " \"description\": \"Samsung's new variant which goes beyond Galaxy to the Universe\",\n" + + " \"price\": 1249,\n" + + " \"discountPercentage\": 0.0,\n" + + " \"rating\": 4.09,\n" + + " \"stock\": 36,\n" + + " \"brand\": \"Samsung\",\n" + + " \"category\": \"smartphones\"\n" + + " }\n" + + " ],\n" + + " \"total\": 2\n" + + "}"; + private static final String PRODUCT_OFFERS = "{\n" + + " \"products\": [\n" + + " {\n" + + " \"id\": 1,\n" + + " \"title\": \"iPhone 9\",\n" + + " \"description\": \"An apple mobile which is nothing like apple\",\n" + + " \"price\": 549,\n" + + " \"discountPercentage\": 12.96,\n" + + " \"rating\": 4.69,\n" + + " \"stock\": 94,\n" + + " \"brand\": \"Apple\",\n" + + " \"category\": \"smartphones\"\n" + + " },\n" + + " {\n" + + " \"id\": 2,\n" + + " \"title\": \"iPhone X\",\n" + + " \"description\": \"SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...\",\n" + + " \"price\": 899,\n" + + " \"discountPercentage\": 17.94,\n" + + " \"rating\": 4.44,\n" + + " \"stock\": 34,\n" + + " \"brand\": \"Apple\",\n" + + " \"category\": \"smartphones\"\n" + + " },\n" + + " {\n" + + " \"id\": 3,\n" + + " \"title\": \"Samsung Universe 9\",\n" + + " \"description\": \"Samsung's new variant which goes beyond Galaxy to the Universe\",\n" + + " \"price\": 1249,\n" + + " \"discountPercentage\": 15.46,\n" + + " \"rating\": 4.09,\n" + + " \"stock\": 36,\n" + + " \"brand\": \"Samsung\",\n" + + " \"category\": \"smartphones\"\n" + + " },\n" + + " {\n" + + " \"id\": 4,\n" + + " \"title\": \"OPPOF19\",\n" + + " \"description\": \"OPPO F19 is officially announced on April 2021.\",\n" + + " \"price\": 280,\n" + + " \"discountPercentage\": 17.91,\n" + + " \"rating\": 4.3,\n" + + " \"stock\": 123,\n" + + " \"brand\": \"OPPO\",\n" + + " \"category\": \"smartphones\"\n" + + " },\n" + + " {\n" + + " \"id\": 5,\n" + + " \"title\": \"Huawei P30\",\n" + + " \"description\": \"Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.\",\n" + + " \"price\": 499,\n" + + " \"discountPercentage\": 10.58,\n" + + " \"rating\": 4.09,\n" + + " \"stock\": 32,\n" + + " \"brand\": \"Huawei\",\n" + + " \"category\": \"smartphones\"\n" + + " }\n" + + " ],\n" + + " \"total\": 5\n" + + "}"; @BeforeAll void setUp() { @@ -40,7 +128,6 @@ class CompletableFutureTimeoutUnitTest { executorService = Executors.newScheduledThreadPool(1); } - @AfterAll void tearDown() { executorService.shutdown(); From 38d4d8f621f8fc91f72979d0ad5790b1e585a654 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 17 Oct 2023 18:24:02 +0700 Subject: [PATCH 10/13] text block --- .../CompletableFutureTimeoutUnitTest.java | 181 +++++++++--------- 1 file changed, 90 insertions(+), 91 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 62cf00930b..bb538f2584 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -1,9 +1,7 @@ package com.baeldung.concurrent.completablefuture; -import com.fasterxml.jackson.databind.JsonNode; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; -import net.minidev.json.writer.JsonReader; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -15,7 +13,6 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.*; -import java.util.function.Supplier; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -26,100 +23,102 @@ class CompletableFutureTimeoutUnitTest { private WireMockServer wireMockServer; private ScheduledExecutorService executorService; private static final int DEFAULT_TIMEOUT = 1000; //1 seconds - private static final String DEFAULT_PRODUCT = "{\n" + - " \"products\": [\n" + - " {\n" + - " \"id\": 2,\n" + - " \"title\": \"iPhone X\",\n" + - " \"description\": \"SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...\",\n" + - " \"price\": 899,\n" + - " \"discountPercentage\": 0.0,\n" + - " \"rating\": 4.44,\n" + - " \"stock\": 34,\n" + - " \"brand\": \"Apple\",\n" + - " \"category\": \"smartphones\"\n" + - " },\n" + - " {\n" + - " \"id\": 3,\n" + - " \"title\": \"Samsung Universe 9\",\n" + - " \"description\": \"Samsung's new variant which goes beyond Galaxy to the Universe\",\n" + - " \"price\": 1249,\n" + - " \"discountPercentage\": 0.0,\n" + - " \"rating\": 4.09,\n" + - " \"stock\": 36,\n" + - " \"brand\": \"Samsung\",\n" + - " \"category\": \"smartphones\"\n" + - " }\n" + - " ],\n" + - " \"total\": 2\n" + - "}"; - private static final String PRODUCT_OFFERS = "{\n" + - " \"products\": [\n" + - " {\n" + - " \"id\": 1,\n" + - " \"title\": \"iPhone 9\",\n" + - " \"description\": \"An apple mobile which is nothing like apple\",\n" + - " \"price\": 549,\n" + - " \"discountPercentage\": 12.96,\n" + - " \"rating\": 4.69,\n" + - " \"stock\": 94,\n" + - " \"brand\": \"Apple\",\n" + - " \"category\": \"smartphones\"\n" + - " },\n" + - " {\n" + - " \"id\": 2,\n" + - " \"title\": \"iPhone X\",\n" + - " \"description\": \"SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...\",\n" + - " \"price\": 899,\n" + - " \"discountPercentage\": 17.94,\n" + - " \"rating\": 4.44,\n" + - " \"stock\": 34,\n" + - " \"brand\": \"Apple\",\n" + - " \"category\": \"smartphones\"\n" + - " },\n" + - " {\n" + - " \"id\": 3,\n" + - " \"title\": \"Samsung Universe 9\",\n" + - " \"description\": \"Samsung's new variant which goes beyond Galaxy to the Universe\",\n" + - " \"price\": 1249,\n" + - " \"discountPercentage\": 15.46,\n" + - " \"rating\": 4.09,\n" + - " \"stock\": 36,\n" + - " \"brand\": \"Samsung\",\n" + - " \"category\": \"smartphones\"\n" + - " },\n" + - " {\n" + - " \"id\": 4,\n" + - " \"title\": \"OPPOF19\",\n" + - " \"description\": \"OPPO F19 is officially announced on April 2021.\",\n" + - " \"price\": 280,\n" + - " \"discountPercentage\": 17.91,\n" + - " \"rating\": 4.3,\n" + - " \"stock\": 123,\n" + - " \"brand\": \"OPPO\",\n" + - " \"category\": \"smartphones\"\n" + - " },\n" + - " {\n" + - " \"id\": 5,\n" + - " \"title\": \"Huawei P30\",\n" + - " \"description\": \"Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.\",\n" + - " \"price\": 499,\n" + - " \"discountPercentage\": 10.58,\n" + - " \"rating\": 4.09,\n" + - " \"stock\": 32,\n" + - " \"brand\": \"Huawei\",\n" + - " \"category\": \"smartphones\"\n" + - " }\n" + - " ],\n" + - " \"total\": 5\n" + - "}"; + private static final String DEFAULT_PRODUCT = """ + { + "products": [ + { + "id": 2, + "title": "iPhone X", + "description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...", + "price": 899, + "discountPercentage": 0.0, + "rating": 4.44, + "stock": 34, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 3, + "title": "Samsung Universe 9", + "description": "Samsung's new variant which goes beyond Galaxy to the Universe", + "price": 1249, + "discountPercentage": 0.0, + "rating": 4.09, + "stock": 36, + "brand": "Samsung", + "category": "smartphones" + } + ], + "total": 2 + }"""; + private static final String PRODUCT_OFFERS = """ + { + "products": [ + { + "id": 1, + "title": "iPhone 9", + "description": "An apple mobile which is nothing like apple", + "price": 549, + "discountPercentage": 12.96, + "rating": 4.69, + "stock": 94, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 2, + "title": "iPhone X", + "description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...", + "price": 899, + "discountPercentage": 17.94, + "rating": 4.44, + "stock": 34, + "brand": "Apple", + "category": "smartphones" + }, + { + "id": 3, + "title": "Samsung Universe 9", + "description": "Samsung's new variant which goes beyond Galaxy to the Universe", + "price": 1249, + "discountPercentage": 15.46, + "rating": 4.09, + "stock": 36, + "brand": "Samsung", + "category": "smartphones" + }, + { + "id": 4, + "title": "OPPOF19", + "description": "OPPO F19 is officially announced on April 2021.", + "price": 280, + "discountPercentage": 17.91, + "rating": 4.3, + "stock": 123, + "brand": "OPPO", + "category": "smartphones" + }, + { + "id": 5, + "title": "Huawei P30", + "description": "Huawei’s re-badged P30 Pro New Edition was officially unveiled yesterday in Germany and now the device has made its way to the UK.", + "price": 499, + "discountPercentage": 10.58, + "rating": 4.09, + "stock": 32, + "brand": "Huawei", + "category": "smartphones" + } + ], + "total": 5 + }"""; @BeforeAll void setUp() { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); - + System.out.println(PRODUCT_OFFERS); stubFor(get(urlEqualTo("/api/dummy")) .willReturn(aResponse() .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. From 3f40e66508517cb871ca166f39795fb80ee1aa9b Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 17 Oct 2023 18:29:26 +0700 Subject: [PATCH 11/13] clean unused --- .../completablefuture/CompletableFutureTimeoutUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index bb538f2584..1932c03486 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -118,7 +118,7 @@ class CompletableFutureTimeoutUnitTest { wireMockServer = new WireMockServer(8080); wireMockServer.start(); WireMock.configureFor("localhost", 8080); - System.out.println(PRODUCT_OFFERS); + stubFor(get(urlEqualTo("/api/dummy")) .willReturn(aResponse() .withFixedDelay(5000) // must be > DEFAULT_TIMEOUT for a timeout to occur. From 223c0bd32f661914004053038213bcfc423629fc Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 17 Oct 2023 18:45:08 +0700 Subject: [PATCH 12/13] [Update] rename completableFuture to productDataFuture --- .../CompletableFutureTimeoutUnitTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 1932c03486..116093b6c3 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -160,23 +160,23 @@ class CompletableFutureTimeoutUnitTest { @Test void whenorTimeout_thenGetThrow() { - CompletableFuture completableFuture = fetchProductData(); - completableFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - assertThrows(ExecutionException.class, completableFuture::get); + CompletableFuture productDataFuture = fetchProductData(); + productDataFuture.orTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertThrows(ExecutionException.class, productDataFuture::get); } @Test void whencompleteOnTimeout_thenReturnValue() throws ExecutionException, InterruptedException { - CompletableFuture completableFuture = fetchProductData(); - completableFuture.completeOnTimeout(DEFAULT_PRODUCT, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - assertEquals(DEFAULT_PRODUCT, completableFuture.get()); + CompletableFuture productDataFuture = fetchProductData(); + productDataFuture.completeOnTimeout(DEFAULT_PRODUCT, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); + assertEquals(DEFAULT_PRODUCT, productDataFuture.get()); } @Test void whencompleteExceptionally_thenGetThrow() { - CompletableFuture completableFuture = fetchProductData(); - executorService.schedule(() -> completableFuture + CompletableFuture productDataFuture = fetchProductData(); + executorService.schedule(() -> productDataFuture .completeExceptionally(new TimeoutException("Timeout occurred")), DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - assertThrows(ExecutionException.class, completableFuture::get); + assertThrows(ExecutionException.class, productDataFuture::get); } } From 7eef9b46b7be751e72c79e0c528fe8cfda49e5a1 Mon Sep 17 00:00:00 2001 From: "@hangga" Date: Tue, 17 Oct 2023 20:18:28 +0700 Subject: [PATCH 13/13] [Optimize] using try-with-resources --- .../completablefuture/CompletableFutureTimeoutUnitTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java index 116093b6c3..d04865026b 100644 --- a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/completablefuture/CompletableFutureTimeoutUnitTest.java @@ -138,15 +138,14 @@ class CompletableFutureTimeoutUnitTest { try { URL url = new URL("http://localhost:8080/api/dummy"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - try { - BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } - in.close(); return response.toString(); } finally { @@ -158,6 +157,7 @@ class CompletableFutureTimeoutUnitTest { }); } + @Test void whenorTimeout_thenGetThrow() { CompletableFuture productDataFuture = fetchProductData();