diff --git a/README.md b/README.md index aecd561645..3c31b7fba1 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,9 @@ Next, they are segregated further on the basis of the tests that we want to exec Additionally, there are 2 profiles dedicated for JDK9 and above builds. -Therefore, we have a total of 8 profiles: +We also have a parents profile to build only parent modules. + +Therefore, we have a total of 9 profiles: | Profile | Includes | Type of test enabled | | -------------------------- | --------------------------- | -------------------- | @@ -45,6 +47,7 @@ Therefore, we have a total of 8 profiles: | integration-heavy | Heavy/long running projects | *IntegrationTest | | default-jdk9-and-above | JDK9 and above projects | *UnitTest | | integration-jdk9-and-above | JDK9 and above projects | *IntegrationTest | +| parents | Set of parent modules | None | Building the project ==================== diff --git a/akka-modules/akka-http/pom.xml b/akka-modules/akka-http/pom.xml index 9372107fc9..3af7c492ca 100644 --- a/akka-modules/akka-http/pom.xml +++ b/akka-modules/akka-http/pom.xml @@ -36,6 +36,7 @@ + 10.0.11 2.5.11 diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml index 14bbc409e5..2a17242ee5 100644 --- a/annotations/annotation-processing/pom.xml +++ b/annotations/annotation-processing/pom.xml @@ -21,6 +21,7 @@ + 1.0-rc2 diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index 26eb319ac0..47dd41dce7 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -54,6 +54,42 @@ + + org.apache.httpcomponents.core5 + httpcore5 + ${httpcore5.version} + + + commons-logging + commons-logging + + + + + + org.apache.httpcomponents.client5 + httpclient5-fluent + ${httpclient5-fluent.version} + + + commons-logging + commons-logging + + + + + + org.apache.httpcomponents.client5 + httpclient5 + ${httpclient5.version} + + + commons-logging + commons-logging + + + + com.github.tomakehurst wiremock @@ -78,6 +114,10 @@ 2.5.1 4.5.8 + + 5.2 + 5.2 + 5.2 \ No newline at end of file diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java index 7576e49034..b5ede3ed60 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java @@ -1,19 +1,24 @@ package com.baeldung.httpclient; -import org.apache.http.HttpEntity; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.HttpMultipartMode; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.entity.mime.content.FileBody; -import org.apache.http.entity.mime.content.StringBody; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.entity.mime.FileBody; +import org.apache.hc.client5.http.entity.mime.HttpMultipartMode; +import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; +import org.apache.hc.client5.http.entity.mime.StringBody; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; + +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpStatus; import java.io.BufferedReader; import java.io.File; @@ -22,14 +27,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import com.baeldung.httpclient.handler.CustomHttpClientResponseHandler; -public class HttpClientMultipartLiveTest { +class HttpClientMultipartLiveTest { // No longer available // private static final String SERVER = "http://echo.200please.com"; @@ -38,41 +39,16 @@ public class HttpClientMultipartLiveTest { private static final String TEXTFILENAME = "temp.txt"; private static final String IMAGEFILENAME = "image.jpg"; private static final String ZIPFILENAME = "zipFile.zip"; - private static final Logger LOGGER = Logger.getLogger("com.baeldung.httpclient.HttpClientMultipartLiveTest"); - private CloseableHttpClient client; private HttpPost post; private BufferedReader rd; - private CloseableHttpResponse response; - @Before - public final void before() { - client = HttpClientBuilder.create() - .build(); + @BeforeEach + public void before() { post = new HttpPost(SERVER); } - @After - public final void after() throws IllegalStateException, IOException { - post.completed(); - try { - client.close(); - } catch (final IOException e1) { - LOGGER.log(Level.SEVERE, e1.getMessage(), e1); - throw e1; - } - try { - rd.close(); - } catch (final IOException e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - throw e; - } - ResponseUtil.closeResponse(response); - } - - // tests - @Test - public final void givenFileandMultipleTextParts_whenUploadwithAddPart_thenNoExceptions() throws IOException { + void givenFileandMultipleTextParts_whenUploadwithAddPart_thenNoExceptions() throws IOException { final URL url = Thread.currentThread() .getContextClassLoader() .getResource("uploads/" + TEXTFILENAME); @@ -83,53 +59,61 @@ public class HttpClientMultipartLiveTest { final StringBody stringBody2 = new StringBody("This is message 2", ContentType.MULTIPART_FORM_DATA); // final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); - builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.setMode(HttpMultipartMode.LEGACY); builder.addPart("file", fileBody); builder.addPart("text1", stringBody1); builder.addPart("text2", stringBody2); final HttpEntity entity = builder.build(); - // - post.setEntity(entity); - response = client.execute(post); - final int statusCode = response.getStatusLine() - .getStatusCode(); - final String responseString = getContent(); - final String contentTypeInHeader = getContentTypeHeader(); - assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); - assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); - System.out.println(responseString); - System.out.println("POST Content Type: " + contentTypeInHeader); + post.setEntity(entity); + try(CloseableHttpClient client = HttpClientBuilder.create() + .build(); + + CloseableHttpResponse response = (CloseableHttpResponse) client + .execute(post, new CustomHttpClientResponseHandler())){ + final int statusCode = response.getCode(); + final String responseString = getContent(response.getEntity()); + final String contentTypeInHeader = getContentTypeHeader(); + + assertThat(statusCode, equalTo(HttpStatus.SC_OK)); + assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); + System.out.println(responseString); + System.out.println("POST Content Type: " + contentTypeInHeader); + } } @Test - public final void givenFileandTextPart_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoExeption() throws IOException { + void givenFileandTextPart_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoExeption() throws IOException { final URL url = Thread.currentThread() .getContextClassLoader() .getResource("uploads/" + TEXTFILENAME); final File file = new File(url.getPath()); final String message = "This is a multipart post"; final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); - builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.setMode(HttpMultipartMode.LEGACY); builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, TEXTFILENAME); builder.addTextBody("text", message, ContentType.DEFAULT_BINARY); final HttpEntity entity = builder.build(); post.setEntity(entity); - response = client.execute(post); - final int statusCode = response.getStatusLine() - .getStatusCode(); - final String responseString = getContent(); - final String contentTypeInHeader = getContentTypeHeader(); - assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); - assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); - System.out.println(responseString); - System.out.println("POST Content Type: " + contentTypeInHeader); + + try(CloseableHttpClient client = HttpClientBuilder.create() + .build(); + + CloseableHttpResponse response = (CloseableHttpResponse) client + .execute(post, new CustomHttpClientResponseHandler())){ + + final int statusCode = response.getCode(); + final String responseString = getContent(response.getEntity()); + final String contentTypeInHeader = getContentTypeHeader(); + assertThat(statusCode, equalTo(HttpStatus.SC_OK)); + assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); + System.out.println(responseString); + System.out.println("POST Content Type: " + contentTypeInHeader); + } } @Test - public final void givenFileAndInputStreamandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException { + void givenFileAndInputStreamandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException { final URL url = Thread.currentThread() .getContextClassLoader() .getResource("uploads/" + ZIPFILENAME); @@ -140,64 +124,75 @@ public class HttpClientMultipartLiveTest { final File file = new File(url2.getPath()); final String message = "This is a multipart post"; final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); - builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.setMode(HttpMultipartMode.STRICT); builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, IMAGEFILENAME); builder.addBinaryBody("upstream", inputStream, ContentType.create("application/zip"), ZIPFILENAME); builder.addTextBody("text", message, ContentType.TEXT_PLAIN); final HttpEntity entity = builder.build(); post.setEntity(entity); - response = client.execute(post); - final int statusCode = response.getStatusLine() - .getStatusCode(); - final String responseString = getContent(); - final String contentTypeInHeader = getContentTypeHeader(); - assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); - assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); - System.out.println(responseString); - System.out.println("POST Content Type: " + contentTypeInHeader); - inputStream.close(); + + try(CloseableHttpClient client = HttpClientBuilder.create() + .build(); + + CloseableHttpResponse response = (CloseableHttpResponse) client + .execute(post, new CustomHttpClientResponseHandler())){ + + final int statusCode = response.getCode(); + final String responseString = getContent(response.getEntity()); + final String contentTypeInHeader = getContentTypeHeader(); + assertThat(statusCode, equalTo(HttpStatus.SC_OK)); + assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); + System.out.println(responseString); + System.out.println("POST Content Type: " + contentTypeInHeader); + inputStream.close(); + } } @Test - public final void givenCharArrayandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException { + void givenCharArrayandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException { final String message = "This is a multipart post"; final byte[] bytes = "binary code".getBytes(); final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); - builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + builder.setMode(HttpMultipartMode.STRICT); builder.addBinaryBody("file", bytes, ContentType.DEFAULT_BINARY, TEXTFILENAME); builder.addTextBody("text", message, ContentType.TEXT_PLAIN); final HttpEntity entity = builder.build(); post.setEntity(entity); - response = client.execute(post); - final int statusCode = response.getStatusLine() - .getStatusCode(); - final String responseString = getContent(); - final String contentTypeInHeader = getContentTypeHeader(); - assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); - assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); - System.out.println(responseString); - System.out.println("POST Content Type: " + contentTypeInHeader); + + try(CloseableHttpClient client = HttpClientBuilder.create() + .build(); + + CloseableHttpResponse response = (CloseableHttpResponse) client + .execute(post, new CustomHttpClientResponseHandler())){ + + final int statusCode = response.getCode(); + final String responseString = getContent(response.getEntity()); + final String contentTypeInHeader = getContentTypeHeader(); + assertThat(statusCode, equalTo(HttpStatus.SC_OK)); + assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); + System.out.println(responseString); + System.out.println("POST Content Type: " + contentTypeInHeader); + } + } // UTIL - private String getContent() throws IOException { - rd = new BufferedReader(new InputStreamReader(response.getEntity() - .getContent())); + private String getContent(HttpEntity httpEntity) throws IOException { + rd = new BufferedReader(new InputStreamReader(httpEntity.getContent())); String body = ""; StringBuilder content = new StringBuilder(); while ((body = rd.readLine()) != null) { - content.append(body).append("\n"); + content.append(body) + .append("\n"); } - return content.toString().trim(); + return content.toString() + .trim(); } - private String getContentTypeHeader() throws IOException { + private String getContentTypeHeader() { return post.getEntity() - .getContentType() - .toString(); + .getContentType(); } } diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/handler/CustomHttpClientResponseHandler.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/handler/CustomHttpClientResponseHandler.java new file mode 100644 index 0000000000..0559854b35 --- /dev/null +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/handler/CustomHttpClientResponseHandler.java @@ -0,0 +1,11 @@ +package com.baeldung.httpclient.handler; + +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.io.HttpClientResponseHandler; + +public class CustomHttpClientResponseHandler implements HttpClientResponseHandler { + @Override + public ClassicHttpResponse handleResponse(ClassicHttpResponse response) { + return response; + } +} \ No newline at end of file diff --git a/axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointIntegrationTest.java b/axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointManualTest.java similarity index 98% rename from axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointIntegrationTest.java rename to axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointManualTest.java index a30e42766b..3b5c130c89 100644 --- a/axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointIntegrationTest.java +++ b/axon/src/test/java/com/baeldung/axon/gui/OrderRestEndpointManualTest.java @@ -27,7 +27,8 @@ import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(classes = OrderApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class OrderRestEndpointIntegrationTest { +//marked as manual as the test is unstable on Jenkins due to low resources +class OrderRestEndpointManualTest { @LocalServerPort private int port; diff --git a/core-java-modules/core-java-11-3/README.md b/core-java-modules/core-java-11-3/README.md index e77e5b7f3d..4f5eb3ea56 100644 --- a/core-java-modules/core-java-11-3/README.md +++ b/core-java-modules/core-java-11-3/README.md @@ -5,3 +5,4 @@ This module contains articles about Java 11 core features ### Relevant articles - [Adding Parameters to Java HttpClient Requests](https://www.baeldung.com/java-httpclient-request-parameters) - [Writing a List of Strings Into a Text File](https://www.baeldung.com/java-list-to-text-file) +- [Java HttpClient – Map JSON Response to Java Class](https://www.baeldung.com/java-httpclient-map-json-response) diff --git a/core-java-modules/core-java-19/README.md b/core-java-modules/core-java-19/README.md index 9663296da0..6a9c6c7fdd 100644 --- a/core-java-modules/core-java-19/README.md +++ b/core-java-modules/core-java-19/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Record Patterns in Java 19](https://www.baeldung.com/java-19-record-patterns) +- [Structured Concurrency in Java 19](https://www.baeldung.com/java-structured-concurrency) diff --git a/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/StringArrayToIntArrayUnitTest.java b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/StringArrayToIntArrayUnitTest.java new file mode 100644 index 0000000000..3675778f90 --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/StringArrayToIntArrayUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.array.conversions; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + + +public class StringArrayToIntArrayUnitTest { + private final String[] stringArray = new String[] { "1", "2", "3", "4", "5", "6", "42" }; + private final int[] expected = new int[] { 1, 2, 3, 4, 5, 6, 42 }; + + private final String[] stringArrayWithInvalidNum = new String[] { "1", "2", "hello", "4", "world", "6", "42" }; + private final int[] expectedWithInvalidInput = new int[] { 1, 2, Integer.MIN_VALUE, 4, Integer.MIN_VALUE, 6, 42 }; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Test + void givenStringArray_whenUseStreamApi_shouldGetExpectedIntArray() { + int[] result = Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray(); + assertArrayEquals(expected, result); + } + + @Test + void givenStringArrayWithInvalidNum_whenUseStreamApi_shouldGetExpectedIntArray() { + int[] result = Arrays.stream(stringArrayWithInvalidNum).mapToInt(s -> { + try { + return Integer.parseInt(s); + } catch (NumberFormatException ex) { + logger.warn("Invalid number format detected: {}, use Int.MinValue as the fallback", s); + return Integer.MIN_VALUE; + } + }).toArray(); + assertArrayEquals(expectedWithInvalidInput, result); + } + + @Test + void givenStringArray_whenConvertInLoop_shouldGetExpectedIntArray() { + int[] result = new int[stringArray.length]; + for (int i = 0; i < stringArray.length; i++) { + result[i] = Integer.parseInt(stringArray[i]); + } + assertArrayEquals(expected, result); + } + + @Test + void givenStringArrayWithInvalidNum_whenConvertInLoop_shouldGetExpectedIntArray() { + int[] result = new int[stringArrayWithInvalidNum.length]; + for (int i = 0; i < stringArrayWithInvalidNum.length; i++) { + try { + result[i] = Integer.parseInt(stringArrayWithInvalidNum[i]); + } catch (NumberFormatException exception) { + logger.warn("Invalid number format detected: [{}], use Int.MinValue as the fallback", stringArrayWithInvalidNum[i]); + result[i] = Integer.MIN_VALUE; + } + } + + assertArrayEquals(expectedWithInvalidInput, result); + } +} diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/AsynchronousCallbackUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/AsynchronousCallbackUnitTest.java index 494d7365d3..de9e386395 100644 --- a/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/AsynchronousCallbackUnitTest.java +++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/AsynchronousCallbackUnitTest.java @@ -6,8 +6,7 @@ import com.baeldung.callbackfunctions.EventListener; import com.baeldung.callbackfunctions.asynchronous.AsynchronousEventConsumer; import com.baeldung.callbackfunctions.asynchronous.AsynchronousEventListenerImpl; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; public class AsynchronousCallbackUnitTest { @@ -17,6 +16,6 @@ public class AsynchronousCallbackUnitTest { AsynchronousEventConsumer asynchronousEventListenerConsumer = new AsynchronousEventConsumer(listener); asynchronousEventListenerConsumer.doAsynchronousOperation(); - verify(listener, times(1)).onTrigger(); + verify(listener, timeout(1000).times(1)).onTrigger(); } } diff --git a/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/ConsumerCallbackUnitTest.java b/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/ConsumerCallbackUnitTest.java index ba09a7e50c..9ba5cdb6ef 100644 --- a/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/ConsumerCallbackUnitTest.java +++ b/core-java-modules/core-java-functional/src/test/java/com/baeldung/callbackfunctions/ConsumerCallbackUnitTest.java @@ -3,18 +3,25 @@ package com.baeldung.callbackfunctions; import org.junit.jupiter.api.Test; import com.baeldung.callbackfunctions.ConsumerCallback; +import java.util.concurrent.atomic.AtomicInteger; + import static org.junit.jupiter.api.Assertions.assertEquals; public class ConsumerCallbackUnitTest { @Test - public void whenIncreasingInitialAgeByGivenValueThroughCallback_shouldIncreaseAge(){ + void whenIncreasingInitialAgeByGivenValueThroughCallback_shouldIncreaseAge(){ ConsumerCallback consumerCallback = new ConsumerCallback(); - consumerCallback.getAge(20, (initialAge) -> { - int ageDifference = 10; + int ageDifference = 10; + AtomicInteger newAge1 = new AtomicInteger(); + int initialAge = 20; + consumerCallback.getAge(initialAge, (initialAge1) -> { consumerCallback.increaseAge(initialAge, ageDifference, (newAge) -> { - assertEquals(initialAge + ageDifference, newAge); + System.out.printf("New age ==> %s", newAge); + newAge1.set(newAge); + }); }); + assertEquals(initialAge + ageDifference, newAge1.get()); } } diff --git a/core-java-modules/core-java-lang-5/README.md b/core-java-modules/core-java-lang-5/README.md index b8deff199e..5ff3e83d2c 100644 --- a/core-java-modules/core-java-lang-5/README.md +++ b/core-java-modules/core-java-lang-5/README.md @@ -14,3 +14,4 @@ This module contains articles about core features in the Java language - [Convert Between int and char in Java](https://www.baeldung.com/java-convert-int-char) - [Converting a Number from One Base to Another in Java](https://www.baeldung.com/java-converting-a-number-from-one-base-to-another) - [Check if Command-Line Arguments Are Null in Java](https://www.baeldung.com/java-check-command-line-args) +- [Determine if a Class Implements an Interface in Java](https://www.baeldung.com/java-check-class-implements-interface) diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml index 6d3771bd31..767ebb6e35 100644 --- a/core-java-modules/core-java-lang-5/pom.xml +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -13,6 +13,12 @@ core-java-modules 0.0.1-SNAPSHOT + + + 3.12.0 + 0.10.2 + + core-java-lang-5 @@ -24,4 +30,18 @@ + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.reflections + reflections + ${reflections.version} + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass1.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass1.java new file mode 100644 index 0000000000..fb91223a97 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass1.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public class ChildClass1 implements ChildInterface1 { + +} diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass2.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass2.java new file mode 100644 index 0000000000..2d5958784d --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildClass2.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public class ChildClass2 implements ChildInterface2 { + +} diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface1.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface1.java new file mode 100644 index 0000000000..8a2ad5f345 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface1.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public interface ChildInterface1 extends MasterInterface { + +} diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface2.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface2.java new file mode 100644 index 0000000000..cff662edf0 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/ChildInterface2.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public interface ChildInterface2 extends MasterInterface { + +} diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterClass.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterClass.java new file mode 100644 index 0000000000..29f3ed5fe8 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterClass.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public class MasterClass implements MasterInterface { + +} diff --git a/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterInterface.java b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterInterface.java new file mode 100644 index 0000000000..6aefb8b6e6 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/main/java/com/baeldung/checkinterface/MasterInterface.java @@ -0,0 +1,5 @@ +package com.baeldung.checkinterface; + +public interface MasterInterface { + +} diff --git a/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/checkinterface/CheckInterfaceUnitTest.java b/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/checkinterface/CheckInterfaceUnitTest.java new file mode 100644 index 0000000000..dcbbb7eb05 --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/checkinterface/CheckInterfaceUnitTest.java @@ -0,0 +1,154 @@ +package com.baeldung.checkinterface; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang3.ClassUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.reflections.ReflectionUtils; +import org.reflections.Reflections; + +public class CheckInterfaceUnitTest { + + protected static Reflections reflections; + + @BeforeAll + public static void initializeReflectionsLibrary() { + + reflections = new Reflections("com.baeldung.checkinterface"); + } + + @Test + public void whenUsingReflectionGetInterfaces_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + List> interfaces = Arrays.asList(childClass2.getClass().getInterfaces()); + + assertEquals(1, interfaces.size()); + assertTrue(interfaces.contains(ChildInterface2.class)); + } + + @Test + public void whenUsingReflectionGetInterfaces_thenParentInterfaceIsNotFound() { + + ChildClass2 childClass2 = new ChildClass2(); + List> interfaces = Arrays.asList(childClass2.getClass().getInterfaces()); + + assertFalse(interfaces.contains(MasterInterface.class)); + } + + @Test + public void whenUsingReflectionGetInterfacesRecursively_thenParentInterfaceIsFound() { + + Set> interfaces = getAllExtendedOrImplementedInterfacesRecursively(ChildClass2.class); + + assertTrue(interfaces.contains(ChildInterface2.class)); + assertTrue(interfaces.contains(MasterInterface.class)); + } + + @Test + public void whenUsingReflectionIsAssignableFrom_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(ChildInterface2.class.isAssignableFrom(childClass2.getClass())); + } + + @Test + public void whenUsingReflectionIsAssignableFrom_thenParentInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(MasterInterface.class.isAssignableFrom(childClass2.getClass())); + } + + @Test + public void whenUsingReflectionIsInstance_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(ChildInterface2.class.isInstance(childClass2)); + } + + @Test + public void whenUsingReflectionIsInstance_thenParentInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(MasterInterface.class.isInstance(childClass2)); + } + + @Test + public void whenUsingReflectionInstanceOf_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(childClass2 instanceof ChildInterface2); + } + + @Test + public void whenUsingReflectionInstanceOf_thenParentInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + + assertTrue(childClass2 instanceof MasterInterface); + } + + @Test + public void whenUsingCommons_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + List> interfaces = ClassUtils.getAllInterfaces(childClass2.getClass()); + + assertTrue(interfaces.contains(ChildInterface2.class)); + } + + @Test + public void whenUsingCommons_thenParentInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + List> interfaces = ClassUtils.getAllInterfaces(childClass2.getClass()); + + assertTrue(interfaces.contains(MasterInterface.class)); + } + + @Test + public void whenUsingReflections_thenDirectlyImplementedInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + Set> interfaces = reflections.get(ReflectionUtils.Interfaces.of(childClass2.getClass())); + + assertTrue(interfaces.contains(ChildInterface2.class)); + } + + @Test + public void whenUsingReflections_thenParentInterfaceIsFound() { + + ChildClass2 childClass2 = new ChildClass2(); + Set> interfaces = reflections.get(ReflectionUtils.Interfaces.of(childClass2.getClass())); + + assertTrue(interfaces.contains(MasterInterface.class)); + } + + static Set> getAllExtendedOrImplementedInterfacesRecursively(Class clazz) { + + Set> res = new HashSet>(); + Class[] interfaces = clazz.getInterfaces(); + + if (interfaces.length > 0) { + res.addAll(Arrays.asList(interfaces)); + for (Class interfaze : interfaces) { + res.addAll(getAllExtendedOrImplementedInterfacesRecursively(interfaze)); + } + } + + return res; + } +} diff --git a/core-java-modules/core-java-lang-oop-types-2/README.md b/core-java-modules/core-java-lang-oop-types-2/README.md index 61b2853af9..ca8742d6c0 100644 --- a/core-java-modules/core-java-lang-oop-types-2/README.md +++ b/core-java-modules/core-java-lang-oop-types-2/README.md @@ -8,3 +8,4 @@ This module contains articles about types in Java - [Check if an Enum Value Exists in Java](https://www.baeldung.com/java-search-enum-values) - [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value) - [Filling a List With All Enum Values in Java](https://www.baeldung.com/java-enum-values-to-list) +- [Comparing a String to an Enum Value in Java](https://www.baeldung.com/java-comparing-string-to-enum) diff --git a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/InstanceOfUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/InstanceOfUnitTest.java index 0e082b69d3..6ba8ed024c 100644 --- a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/InstanceOfUnitTest.java +++ b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/keyword/InstanceOfUnitTest.java @@ -1,55 +1,67 @@ package com.baeldung.keyword; -import org.junit.Assert; import org.junit.jupiter.api.Test; -import com.baeldung.keyword.Circle; -import com.baeldung.keyword.Ring; -import com.baeldung.keyword.Round; -import com.baeldung.keyword.Shape; -import com.baeldung.keyword.Triangle; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; public class InstanceOfUnitTest { @Test - public void giveWhenInstanceIsCorrect_thenReturnTrue() { + void giveWhenInstanceIsCorrect_thenReturnTrue() { Ring ring = new Ring(); - Assert.assertTrue("ring is instance of Round ", ring instanceof Round); + assertTrue(ring instanceof Round); } @Test - public void giveWhenObjectIsInstanceOfType_thenReturnTrue() { + void giveWhenObjectIsInstanceOfType_thenReturnTrue() { Circle circle = new Circle(); - Assert.assertTrue("circle is instance of Circle ", circle instanceof Circle); + assertTrue(circle instanceof Circle); } - + @Test - public void giveWhenInstanceIsOfSubtype_thenReturnTrue() { + void giveWhenInstanceIsOfSubtype_thenReturnTrue() { Circle circle = new Circle(); - Assert.assertTrue("circle is instance of Round", circle instanceof Round); + assertTrue(circle instanceof Round); } @Test - public void giveWhenTypeIsInterface_thenReturnTrue() { + void giveWhenTypeIsInterface_thenReturnTrue() { Circle circle = new Circle(); - Assert.assertTrue("circle is instance of Shape", circle instanceof Shape); + assertTrue(circle instanceof Shape); } - + @Test - public void giveWhenTypeIsOfObjectType_thenReturnTrue() { + void giveWhenTypeIsOfObjectType_thenReturnTrue() { Thread thread = new Thread(); - Assert.assertTrue("thread is instance of Object", thread instanceof Object); + assertTrue(thread instanceof Object); } @Test - public void giveWhenInstanceValueIsNull_thenReturnFalse() { + void giveWhenInstanceValueIsNull_thenReturnFalse() { Circle circle = null; - Assert.assertFalse("circle is instance of Round", circle instanceof Round); + assertFalse(circle instanceof Round); } @Test - public void giveWhenComparingClassInDiffHierarchy_thenCompilationError() { - // Assert.assertFalse("circle is instance of Triangle", circle instanceof Triangle); + void giveWhenComparingClassInDiffHierarchy_thenCompilationError() { + //assertFalse( circle instanceof Triangle); } -} + + @Test + void giveWhenStream_whenCastWithoutInstanceOfChk_thenGetException() { + Stream roundStream = Stream.of(new Ring(), new Ring(), new Circle()); + assertThrows(ClassCastException.class, () -> roundStream.map(it -> (Ring) it).collect(Collectors.toList())); + } + + @Test + void giveWhenStream_whenCastAfterInstanceOfChk_thenGetExpectedResult() { + Stream roundStream = Stream.of(new Ring(), new Ring(), new Circle()); + List ringList = roundStream.filter(it -> it instanceof Ring).map(it -> (Ring) it).collect(Collectors.toList()); + assertEquals(2, ringList.size()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 77f23be97c..982f4fa346 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -25,15 +25,20 @@ ${commons-lang3.version} - javax.mail - mail - ${javax.mail.version} + org.eclipse.angus + angus-mail + ${angus.mail.version} org.asynchttpclient async-http-client ${async-http-client.version} + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.bind.version} + com.icegreen greenmail @@ -48,9 +53,10 @@ 4.5.9 - 1.5.0-b01 + 2.0.1 2.4.5 - 1.5.8 + 2.3.3 + 2.0.0-alpha-3 \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java index 3e40cf53f7..b2d8e6b710 100644 --- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/EmailService.java @@ -1,19 +1,20 @@ package com.baeldung.mail; -import javax.mail.Authenticator; -import javax.mail.Message; -import javax.mail.Multipart; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; import java.io.File; import java.net.URI; import java.util.Properties; +import jakarta.mail.Authenticator; +import jakarta.mail.Message; +import jakarta.mail.Multipart; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; + public class EmailService { private String username; diff --git a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java index fbe8a54bbe..66e1372ac1 100644 --- a/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java +++ b/core-java-modules/core-java-networking-2/src/main/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentService.java @@ -1,21 +1,23 @@ package com.baeldung.mail.mailwithattachment; -import javax.mail.BodyPart; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.PasswordAuthentication; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.Properties; +import jakarta.mail.Authenticator; +import jakarta.mail.BodyPart; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; +import jakarta.mail.Transport; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeBodyPart; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; + public class MailWithAttachmentService { private final String username; @@ -37,7 +39,7 @@ public class MailWithAttachmentService { props.put("mail.smtp.host", this.host); props.put("mail.smtp.port", this.port); - return Session.getInstance(props, new javax.mail.Authenticator() { + return Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java index 8fe50efd69..a8670bb01e 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java @@ -1,10 +1,7 @@ package com.baeldung.download; -import org.junit.After; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.Assert.assertTrue; -import javax.xml.bind.DatatypeConverter; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -13,7 +10,11 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.concurrent.ExecutionException; -import static org.junit.Assert.assertTrue; +import javax.xml.bind.DatatypeConverter; + +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; public class FileDownloadIntegrationTest { diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java index cec4cfcb55..184df8428a 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/EmailServiceLiveTest.java @@ -1,17 +1,19 @@ package com.baeldung.mail; -import com.icegreen.greenmail.junit.GreenMailRule; -import com.icegreen.greenmail.util.ServerSetupTest; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.io.IOException; +import com.icegreen.greenmail.junit.GreenMailRule; +import com.icegreen.greenmail.util.ServerSetupTest; -import static org.junit.Assert.assertEquals; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; public class EmailServiceLiveTest { diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java index 04ad47875f..c6850461ae 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/mail/mailwithattachment/MailWithAttachmentServiceLiveTest.java @@ -1,20 +1,20 @@ package com.baeldung.mail.mailwithattachment; +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + import com.icegreen.greenmail.configuration.GreenMailConfiguration; import com.icegreen.greenmail.junit.GreenMailRule; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import javax.annotation.Resource; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import static org.junit.Assert.assertEquals; +import jakarta.mail.MessagingException; +import jakarta.mail.Session; +import jakarta.mail.internet.MimeMessage; +import jakarta.mail.internet.MimeMultipart; public class MailWithAttachmentServiceLiveTest { @@ -29,7 +29,6 @@ public class MailWithAttachmentServiceLiveTest { .withUser(USERNAME, PASSWORD) ); - @Resource private MailWithAttachmentService emailService; @Before @@ -73,5 +72,4 @@ public class MailWithAttachmentServiceLiveTest { return GreenMailUtil.getBody(((MimeMultipart) receivedMessage.getContent()) .getBodyPart(2)); } - } diff --git a/core-java-modules/core-java-networking-3/pom.xml b/core-java-modules/core-java-networking-3/pom.xml index 4f373238ee..6d0374c598 100644 --- a/core-java-modules/core-java-networking-3/pom.xml +++ b/core-java-modules/core-java-networking-3/pom.xml @@ -30,9 +30,9 @@ ${tomcat.embeded.version} - com.sun.mail - javax.mail - ${javax.mail.version} + org.eclipse.angus + angus-mail + ${angus.mail.version} @@ -95,7 +95,7 @@ 5.3.3 1.32 0.17 - 1.6.2 + 2.0.1 1.7 diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/downloadattachments/DownloadEmailAttachments.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/downloadattachments/DownloadEmailAttachments.java index 4030f3b983..de726f6cbf 100644 --- a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/downloadattachments/DownloadEmailAttachments.java +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/downloadattachments/DownloadEmailAttachments.java @@ -6,16 +6,16 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; -import javax.mail.Address; -import javax.mail.Folder; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.NoSuchProviderException; -import javax.mail.Part; -import javax.mail.Session; -import javax.mail.Store; -import javax.mail.internet.MimeBodyPart; +import jakarta.mail.Address; +import jakarta.mail.Folder; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; +import jakarta.mail.NoSuchProviderException; +import jakarta.mail.Part; +import jakarta.mail.Session; +import jakarta.mail.Store; +import jakarta.mail.internet.MimeBodyPart; public class DownloadEmailAttachments { private String downloadDirectory; @@ -24,7 +24,7 @@ public class DownloadEmailAttachments { this.downloadDirectory = dir; } - public void downloadEmailAttachments(String host, String port, String userName, String password) throws NoSuchProviderException, MessagingException, IOException { + public void downloadEmailAttachments(String host, String port, String userName, String password) throws MessagingException, IOException { Properties properties = setMailServerProperties(host, port); Store store = setSessionStoreProperties(userName, password, properties); Folder inbox = store.getFolder("INBOX"); @@ -67,7 +67,7 @@ public class DownloadEmailAttachments { return downloadedAttachments; } - public Store setSessionStoreProperties(String userName, String password, Properties properties) throws NoSuchProviderException, MessagingException { + public Store setSessionStoreProperties(String userName, String password, Properties properties) throws MessagingException { Session session = Session.getDefaultInstance(properties); Store store = session.getStore("pop3"); diff --git a/core-java-modules/core-java-networking-4/src/main/java/com/baeldung/urlvalidation/IPv4Validation.java b/core-java-modules/core-java-networking-4/src/main/java/com/baeldung/urlvalidation/IPv4Validation.java new file mode 100644 index 0000000000..5d72873745 --- /dev/null +++ b/core-java-modules/core-java-networking-4/src/main/java/com/baeldung/urlvalidation/IPv4Validation.java @@ -0,0 +1,27 @@ +package com.baeldung.urlvalidation; + +import com.google.common.net.InetAddresses; +import org.apache.commons.validator.routines.InetAddressValidator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class IPv4Validation { + + public static boolean validateWithApacheCommons(String ip) { + InetAddressValidator validator = InetAddressValidator.getInstance(); + return validator.isValid(ip); + } + + public static boolean validateWithGuava(String ip) { + return InetAddresses.isInetAddress(ip); + } + + public static boolean validateWithRegex(String ip) { + String regex = "^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}$"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(ip); + return matcher.matches(); + } + +} diff --git a/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/ipv4validation/IPv4ValidationUnitTest.java b/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/ipv4validation/IPv4ValidationUnitTest.java new file mode 100644 index 0000000000..367d70117a --- /dev/null +++ b/core-java-modules/core-java-networking-4/src/test/java/com/baeldung/ipv4validation/IPv4ValidationUnitTest.java @@ -0,0 +1,121 @@ +package com.baeldung.ipv4validation; + +import org.junit.Test; + +import static com.baeldung.urlvalidation.IPv4Validation.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class IPv4ValidationUnitTest { + + @Test + public void givenValidIPv4_whenValidate_thenReturnsTrue() { + String ip = "192.168.0.1"; + assertTrue(validateWithApacheCommons(ip)); + assertTrue(validateWithGuava(ip)); + assertTrue(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithThreeOctets_whenValidate_thenReturnsFalse() { + String ip = "192.168.0"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithLeadingZero_whenValidate_thenReturnsFalse() { + String ip = "192.168.0.01"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithInvalidCharacter_whenValidate_thenReturnsFalse() { + String ip = "a.168.0.01"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4HaveValueAbove255_whenValidate_thenReturnsFalse() { + String ip = "192.168.256.1"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenValidIPv4WithTwoDigitOctet_whenValidate_thenReturnsTrue() { + String ip = "192.168.42.1"; + assertTrue(validateWithApacheCommons(ip)); + assertTrue(validateWithGuava(ip)); + assertTrue(validateWithRegex(ip)); + } + @Test + public void givenValidIPv4WithNumberInRange200And249_whenValidate_thenReturnsTrue() { + String ip = "192.168.42.222"; + assertTrue(validateWithApacheCommons(ip)); + assertTrue(validateWithGuava(ip)); + assertTrue(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithFourDigitOctet_whenValidate_thenReturnsFalse() { + String ip = "1921.168.42.222"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithFiveOctets_whenValidate_thenReturnsFalse() { + String ip = "192.168.42.222.10"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4WithTwoConsecutiveDots_whenValidate_thenReturnsFalse() { + String ip = "192.168..1"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenOnlyDots_whenValidate_thenReturnsFalse() { + String ip = "..."; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenBlankString_whenValidate_thenReturnsFalse() { + String ip = " "; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + + @Test + public void givenIPv4StartWithDot_whenValidate_thenReturnsFalse() { + String ip = ".192.168.0.1"; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + @Test + public void givenIPv4EndWithDot_whenValidate_thenReturnsFalse() { + String ip = "192.168.0.1."; + assertFalse(validateWithApacheCommons(ip)); + assertFalse(validateWithGuava(ip)); + assertFalse(validateWithRegex(ip)); + } + +} diff --git a/core-java-modules/core-java-numbers-5/README.md b/core-java-modules/core-java-numbers-5/README.md index 7a010e2fbf..34651c8e6c 100644 --- a/core-java-modules/core-java-numbers-5/README.md +++ b/core-java-modules/core-java-numbers-5/README.md @@ -7,3 +7,4 @@ - [Make Division of Two Integers Result in a Float](https://www.baeldung.com/java-integer-division-float-result) - [Creating Random Numbers With No Duplicates in Java](https://www.baeldung.com/java-unique-random-numbers) - [Multiply a BigDecimal by an Integer in Java](https://www.baeldung.com/java-bigdecimal-multiply-integer) +- [Check if an Integer Value is null or Zero in Java](https://www.baeldung.com/java-check-integer-null-or-zero) diff --git a/core-java-modules/core-java-numbers-5/src/test/java/com/baeldung/absintdiff/AbsoluteDifferenceOfTwoIntUnitTest.java b/core-java-modules/core-java-numbers-5/src/test/java/com/baeldung/absintdiff/AbsoluteDifferenceOfTwoIntUnitTest.java new file mode 100644 index 0000000000..eec3924202 --- /dev/null +++ b/core-java-modules/core-java-numbers-5/src/test/java/com/baeldung/absintdiff/AbsoluteDifferenceOfTwoIntUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.absintdiff; + +import static com.baeldung.absintdiff.IntDiffUtil.absDiff; +import static com.baeldung.absintdiff.IntDiffUtil.absDiff2; +import static com.baeldung.absintdiff.IntDiffUtil.absDiffAsLong; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class IntDiffUtil { + static int absDiff(int num1, int num2) { + int result = Math.abs(num1 - num2); + System.out.println("Absolute diff: " + result); + return result; + } + + static int absDiff2(int num1, int num2) { + return Math.abs(Math.subtractExact(num1, num2)); + } + + static long absDiffAsLong(int num1, int num2) { + return Math.abs((long) num1 - num2); + } +} + +public class AbsoluteDifferenceOfTwoIntUnitTest { + + @Test + void givenTwoIntegers_whenCallingAbsDiff_shouldGetExpectedResult() { + int diff1 = absDiff(100, -200); + assertEquals(300, diff1); + + int diff2 = absDiff(100, 200); + assertEquals(100, diff2); + + //integer overflow! output: Absolute diff: 2147483449 + //absDiff(Integer.MAX_VALUE, -200); + } + + @Test + void givenTwoIntegers_whenCallingAbsDiff2_shouldThrowException() { + int diff1 = absDiff2(100, -200); + assertEquals(300, diff1); + + int diff2 = absDiff2(100, 200); + assertEquals(100, diff2); + + //overflow -> exception + assertThrows(ArithmeticException.class, () -> absDiff2(Integer.MAX_VALUE, -200)); + } + + @Test + void givenTwoIntegers_whenCallingAbsDiffAsLong_shouldThrowException() { + long diff = absDiffAsLong(Integer.MAX_VALUE, -200); + assertEquals(Integer.MAX_VALUE + 200L, diff); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-4/README.md b/core-java-modules/core-java-streams-4/README.md index b210c2775a..8e5e0652ef 100644 --- a/core-java-modules/core-java-streams-4/README.md +++ b/core-java-modules/core-java-streams-4/README.md @@ -6,3 +6,4 @@ - [Java 8 Streams: Multiple Filters vs. Complex Condition](https://www.baeldung.com/java-streams-multiple-filters-vs-condition) - [Finding Max Date in List Using Streams](https://www.baeldung.com/java-max-date-list-streams) - [Batch Processing of Stream Data in Java](https://www.baeldung.com/java-stream-batch-processing) +- [Stream to Iterable in Java](https://www.baeldung.com/java-stream-to-iterable) diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/processing/CustomBatchIterator.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/processing/CustomBatchIterator.java index b5407b7283..bfc7ffae3b 100644 --- a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/processing/CustomBatchIterator.java +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/processing/CustomBatchIterator.java @@ -14,20 +14,20 @@ public class CustomBatchIterator implements Iterator> { private List currentBatch; private final Iterator iterator; - public CustomBatchIterator(Iterator sourceIterator, int batchSize) { + private CustomBatchIterator(Iterator sourceIterator, int batchSize) { this.batchSize = batchSize; this.iterator = sourceIterator; } @Override public List next() { + prepareNextBatch(); return currentBatch; } @Override public boolean hasNext() { - prepareNextBatch(); - return currentBatch != null && !currentBatch.isEmpty(); + return iterator.hasNext(); } public static Stream> batchStreamOf(Stream stream, int batchSize) { diff --git a/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/streamtoiterable/StreamToIterable.java b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/streamtoiterable/StreamToIterable.java new file mode 100644 index 0000000000..cdba5ea91f --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/main/java/com/baeldung/streams/streamtoiterable/StreamToIterable.java @@ -0,0 +1,42 @@ +package com.baeldung.streams.streamtoiterable; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import joptsimple.internal.Strings; + +public class StreamToIterable { + public String streamToIterableLambda(List listOfStrings) { + Stream stringStream = listOfStrings.stream(); + StringBuilder sentence = new StringBuilder(); + for (String eachString : (Iterable) () -> stringStream.iterator()) { + doSomethingOnString(eachString, sentence); + } + return sentence.toString(); + } + + public String streamToIterableMethodReference(List listOfStrings) { + Stream stringStream = listOfStrings.stream(); + StringBuilder sentence = new StringBuilder(); + for (String eachString : (Iterable) stringStream::iterator) { + doSomethingOnString(eachString, sentence); + } + return sentence.toString(); + } + + public String streamToList(List listOfStrings) { + Stream stringStream = listOfStrings.stream(); + StringBuilder sentence = new StringBuilder(); + for (String eachString : stringStream.collect(Collectors.toList())) { + doSomethingOnString(eachString, sentence); + } + return sentence.toString(); + } + + private void doSomethingOnString(String s, StringBuilder sentence) { + if (!Strings.isNullOrEmpty(s)) { + sentence.append(s); + } + } +} diff --git a/core-java-modules/core-java-streams-4/src/test/java/com/baeldung/streams/streamtoiterable/StreamToIterableUnitTest.java b/core-java-modules/core-java-streams-4/src/test/java/com/baeldung/streams/streamtoiterable/StreamToIterableUnitTest.java new file mode 100644 index 0000000000..6715477cc3 --- /dev/null +++ b/core-java-modules/core-java-streams-4/src/test/java/com/baeldung/streams/streamtoiterable/StreamToIterableUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.streams.streamtoiterable; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +public class StreamToIterableUnitTest { + + @Test + public void givenList_whenLambdaIsUsed_ThenStreamAsIterable(){ + StreamToIterable streamToIterable = new StreamToIterable(); + String actualString = streamToIterable.streamToIterableLambda(getListOfStrings()); + String expectedString = "Thisisasentencewithnospaces"; + Assert.assertEquals(expectedString, actualString); + } + + @Test + public void givenList_whenMethodReferenceIsUsed_ThenStreamAsIterable(){ + StreamToIterable streamToIterable = new StreamToIterable(); + String actualString = streamToIterable.streamToIterableMethodReference(getListOfStrings()); + String expectedString = "Thisisasentencewithnospaces"; + Assert.assertEquals(expectedString, actualString); + } + + @Test + public void givenList_whenCollectedToList_ThenStreamAsIterable(){ + StreamToIterable streamToIterable = new StreamToIterable(); + String actualString = streamToIterable.streamToList(getListOfStrings()); + String expectedString = "Thisisasentencewithnospaces"; + Assert.assertEquals(expectedString, actualString); + } + + private List getListOfStrings(){ + List listOfStrings = new ArrayList<>(); + listOfStrings.add("This"); + listOfStrings.add("is"); + listOfStrings.add("a"); + listOfStrings.add(null); + listOfStrings.add("sentence"); + listOfStrings.add("with"); + listOfStrings.add("no"); + listOfStrings.add(null); + listOfStrings.add("spaces"); + return listOfStrings; + } +} diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java b/core-java-modules/core-java/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java index a58dbf9864..1ea85942ee 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/anonymousclass/AnonymousClassExample.java @@ -9,5 +9,6 @@ public class AnonymousClassExample{ System.out.println("Thread: "+Thread.currentThread().getName()+" started"); } }); + t1.start(); } } \ No newline at end of file diff --git a/discord4j/pom.xml b/discord4j/pom.xml index e15bd47583..3ea85c05c7 100644 --- a/discord4j/pom.xml +++ b/discord4j/pom.xml @@ -53,19 +53,10 @@ org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - 1.8 3.1.1 diff --git a/docker-modules/docker-compose-2/README.md b/docker-modules/docker-compose-2/README.md index 729105e3fd..353b85f154 100644 --- a/docker-modules/docker-compose-2/README.md +++ b/docker-modules/docker-compose-2/README.md @@ -1 +1,2 @@ ## Relevant Articles: +- [Communicating With Docker Containers on the Same Machine](https://www.baeldung.com/ops/docker-communicating-with-containers-on-same-machine) diff --git a/feign/pom.xml b/feign/pom.xml index 369fa00137..3ac816fc1d 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -116,7 +116,6 @@ - 1.8 11.8 1.6.3 diff --git a/gcp-firebase/src/main/resources/application.properties b/gcp-firebase/src/main/resources/application.properties index aacbde0d92..494aeb2444 100644 --- a/gcp-firebase/src/main/resources/application.properties +++ b/gcp-firebase/src/main/resources/application.properties @@ -1,2 +1,2 @@ -# Service account location. Can be a filesystem path or a classpath resource -gcp.firebase.service-account=file:firebase-service-account.json \ No newline at end of file +# Service account location. Can be a filesystem path or a classpath resource. NB: Generate and use your own firebase-service-account.json file. +gcp.firebase.service-account=classpath:firebase-service-account.json \ No newline at end of file diff --git a/gcp-firebase/src/main/resources/firebase-service-account.json b/gcp-firebase/src/main/resources/firebase-service-account.json new file mode 100644 index 0000000000..ed5afa9f13 --- /dev/null +++ b/gcp-firebase/src/main/resources/firebase-service-account.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "tutorials-2cdfb", + "private_key_id": "d9f6a684d6814f85ed2d0490585eb7bf590f983a", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDdJWTeGT2eBFo+\nXxzT9xFJYPtyawTAj0K1rVUNlWNUwj3zszK6P2sAsrpI2Rz1klwQ9aDz9i3+Opxv\n7UZ3pOzur6S58JnoswtNs6BZ9P7oeggLJJC6MPjioxwh8jLLIGMgdVtC2/iPYW3r\nGzurWlwkM8M8DyCgNq7KKJcx44pGcyy16ZGCYiijuTEmK6R+WHJTTyICzRFu3Org\nuHGlZUs/G4E76p10HanoFX2AIS/fDEEMP2DXBB73yoCal5GuvMY9yZWxnvV65Y5z\nGveY3NDB9EESbO2AAhDvHekWT17uWhymtO5N3gM8da48J9d51tVzi0D/NIPZnF0u\nTS64uxK3AgMBAAECggEAYuEQa7oPcfLyQscWRbRH1250n2E4e7zSkBcTW4J7Km+7\ncZajTOGEP4iqgF4Lc8XgQnkBYXOmdvDP97+47VAh3EtOtRDeUEyV9kUlonNH8rx1\nkj3kNEwnTHav4oG/slEl4WJ3zro6NinTEvdXQ7OgVVOLrPP6m4g3uQ5TJCxgLEUI\nTd3Hs3cg3P71mzEqfBF4NmGVmC1ea5lXFELd6giJJMvL7g+O2w22/fquGWOrreAM\ncj/G2Xv9/vmzeb9yzbgGxqCJyY6vspmd90fQLUu7bxkEY5/PPc6Zk8qay4AdEn47\nkL6hnJiR8H1wMCzV2RTUKE7ospriNVdBilXgxm9IMQKBgQD1TmF0Bg85zvXmEKBa\nLBhbc3xTtM7DOgKs+pI12sYDKwgL/QKEI/TKkYXua0aVGiQWc2Bk2/0sYhO6aB2f\n6AN1ZUrf4PRM8c53jebChc7beVLSjWI8Tx+kE+0t8864OwvELYZUzP35oSx3RdJD\nE/CvqBM7NQfJwx2Mw2VJK/YRGQKBgQDmyWLm/IWitehkITw6xMQpkkFs2m4Joq3A\nJvAyri58TRkw/7rqWaIxb5Wcy/7BOvjDN8PZNTHh4ZvhQiHpn7NGUks2/ULnWxUB\nWAA9YbeO9PNHJfZ6PjD2FSvwOXHj+vVkWt2GCXT8pDGYM2ImqXon85Oe3OH/h+N5\nktO9taesTwKBgQCSdPGKK/P7N61oZpTWQW1pbFHWSCUKOiBO1mtk6/E9AvwS7EQM\nUMteBfRInJPPgYP6Q3hRv2YwkX3l1TOavRMTjB5f/BbfuZ7jkj0r9mfCcXUZcIAu\nMa9abus0fFP3eolT3zpMdvdLiwbZTz5x/f29YkPZHZhAxdVmrWJThYOsQQKBgBDu\nZVsc25D8V3hBF/IXzWxfVn1t6PS8ApM+SBDvxmlIHrkBiez3dna6APfn32C9utJX\nnP6qcGZp7s2v1F0XYkeecfYuzmG6xOe8VQgryxOp1M87ccG2HlFvbDHLhRd8qdQa\n9nWG7BY81Yac/m5nsJaNwB6/hbUBeybIJtCcKxjxAoGBAJ3y+QSFb4AYmxLFtmMA\nklOvlT+r70w4RV/z4SEO1gjWEh9IozNSXknl5Q/8Zh9IVm3+/qYap//IzEv9JUc3\nv4+HlpZu0trxTpvRWWjPqVr3ssxRdiFLC0LCLEk4rzqWLBVyzJm8uHVIF9Inv8PE\naudInvdbnfAWi60+1Wi8u0Co\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-2afzd@tutorials-2cdfb.iam.gserviceaccount.com", + "client_id": "111111112074248894669", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-2afzd%40tutorials-2cdfb.iam.gserviceaccount.com" +} diff --git a/java-blockchain/pom.xml b/java-blockchain/pom.xml index 6d3910df80..2279a7ceff 100644 --- a/java-blockchain/pom.xml +++ b/java-blockchain/pom.xml @@ -24,22 +24,6 @@ true - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - 1.8 - 1.8 - - \ No newline at end of file diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index ffc2b0631e..7c3f32b092 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -28,6 +28,15 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + 1.1 2.8.0 diff --git a/javaxval-2/pom.xml b/javaxval-2/pom.xml index a63d21969b..5c311e10f8 100644 --- a/javaxval-2/pom.xml +++ b/javaxval-2/pom.xml @@ -60,9 +60,6 @@ 6.2.3.Final 6.2.0.Final - 3.6.1 - 1.8 - 1.8 3.0.0 5.3.21 2.7.1 diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 753a46cffe..76472e29fb 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -60,9 +60,6 @@ 6.2.3.Final 6.2.0.Final - 3.6.1 - 1.8 - 1.8 3.0.0 5.3.21 2.7.1 diff --git a/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java index df85e26b76..b158d63720 100644 --- a/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java +++ b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java @@ -9,10 +9,14 @@ import org.glassfish.grizzly.http.server.HttpServer; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; +import org.junit.jupiter.api.Disabled; import com.baeldung.jersey.server.http.EmbeddedHttpServer; +@Disabled +@Ignore public class ItemsUnitTest { private HttpServer server; diff --git a/jgit/pom.xml b/jgit/pom.xml index ca58709583..91881fbec8 100644 --- a/jgit/pom.xml +++ b/jgit/pom.xml @@ -36,6 +36,7 @@ + 4.5.0.201609210915-r diff --git a/jmeter/pom.xml b/jmeter/pom.xml index b2e4197dfc..c4b15405ec 100644 --- a/jmeter/pom.xml +++ b/jmeter/pom.xml @@ -68,5 +68,91 @@ 2.6.0 + + + + dashboard + + + env + dash + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + launch-web-app + + start + + + com.baeldung.dashboard.DashboardApplication + + + + + + com.lazerycode.jmeter + jmeter-maven-plugin + 3.7.0 + + + + configuration + + configure + + + + + jmeter-tests + + jmeter + results + + + + + ${project.basedir}/src/main/resources/dashboard + ${project.basedir}/src/main/resources/dashboard + true + true + false + + + + org.springframework.boot + spring-boot-maven-plugin + + + stop-web-app + + stop + + + + + + + + + 5.5 + + + \ No newline at end of file diff --git a/jmeter/src/main/java/com/baeldung/dashboard/DashboardApplication.java b/jmeter/src/main/java/com/baeldung/dashboard/DashboardApplication.java new file mode 100644 index 0000000000..a531b97be1 --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/dashboard/DashboardApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.dashboard; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, MongoAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class, MongoDataAutoConfiguration.class }) +public class DashboardApplication { + public static void main(String[] args) throws Exception { + SpringApplication.run(DashboardApplication.class, args); + } +} diff --git a/jmeter/src/main/java/com/baeldung/dashboard/controllers/Dashboard.java b/jmeter/src/main/java/com/baeldung/dashboard/controllers/Dashboard.java new file mode 100644 index 0000000000..8c749b21d8 --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/dashboard/controllers/Dashboard.java @@ -0,0 +1,42 @@ +package com.baeldung.dashboard.controllers; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Random; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +import com.baeldung.dashboard.models.Quotes; + +@Controller +public class Dashboard { + + @GetMapping("/greeting") + public String getGreeting(Model model) { + model.addAttribute("host", System.getProperty("os.name")); + return "greeting"; + } + + @GetMapping("/quote") + public String getQuote(Model model) throws InterruptedException { + Random r = new Random(); + int day = r.nextInt(7); + String quote = Quotes.list.get(day); + + int wait = r.nextInt(6); + Thread.currentThread().sleep(wait); + model.addAttribute("quote", quote); + + return "quote"; + } + + @GetMapping("/time") + public String getTime(Model model) { + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("hh:mm:ss a"); + LocalDateTime now = LocalDateTime.now(); + model.addAttribute("time", fmt.format(now)); + return "time"; + } +} diff --git a/jmeter/src/main/java/com/baeldung/dashboard/models/Quotes.java b/jmeter/src/main/java/com/baeldung/dashboard/models/Quotes.java new file mode 100644 index 0000000000..7c8e6a732d --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/dashboard/models/Quotes.java @@ -0,0 +1,13 @@ +package com.baeldung.dashboard.models; + +import java.util.Arrays; +import java.util.List; + +public class Quotes { + public static final List list = Arrays.asList("The greatest glory in living lies not in never falling, but in rising every time we fall. -Nelson Mandela\r\n", + "The way to get started is to quit talking and begin doing. -Walt Disney\r\n", + "Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma – which is living with the results of other people's thinking. -Steve Jobs\r\n", + "If life were predictable it would cease to be life, and be without flavor. -Eleanor Roosevelt\r\n", + "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough. -Oprah Winfrey\r\n", + "If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success. -James Cameron\r\n", "Life is what happens when you're busy making other plans. -John Lennon"); +} diff --git a/jmeter/src/main/resources/dashboard/ReportsDashboard.csv b/jmeter/src/main/resources/dashboard/ReportsDashboard.csv new file mode 100644 index 0000000000..046666ca2b --- /dev/null +++ b/jmeter/src/main/resources/dashboard/ReportsDashboard.csv @@ -0,0 +1,16 @@ +timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect +1674622105952,714,HTTP Request (/greeting),200,,Thread Group 1-4,text,true,,430,126,5,5,http://localhost:8080/greeting,705,0,7 +1674622105450,1216,HTTP Request (/greeting),200,,Thread Group 1-1,text,true,,430,126,5,5,http://localhost:8080/greeting,1207,0,54 +1674622105468,1198,HTTP Request (/greeting),200,,Thread Group 1-2,text,true,,430,126,5,5,http://localhost:8080/greeting,1189,0,36 +1674622106064,602,HTTP Request (/greeting),200,,Thread Group 1-5,text,true,,430,126,5,5,http://localhost:8080/greeting,593,0,2 +1674622105800,866,HTTP Request (/greeting),200,,Thread Group 1-3,text,true,,430,126,5,5,http://localhost:8080/greeting,857,0,1 +1674622106669,13,HTTP Request (/quote),200,,Thread Group 1-4,text,true,,515,123,5,5,http://localhost:8080/quote,12,0,0 +1674622106669,16,HTTP Request (/quote),200,,Thread Group 1-2,text,true,,548,123,5,5,http://localhost:8080/quote,16,0,0 +1674622106671,18,HTTP Request (/quote),200,,Thread Group 1-1,text,true,,629,123,5,5,http://localhost:8080/quote,18,0,0 +1674622106669,24,HTTP Request (/quote),200,,Thread Group 1-5,text,true,,602,123,5,5,http://localhost:8080/quote,24,0,0 +1674622106669,29,HTTP Request (/quote),200,,Thread Group 1-3,text,true,,515,123,5,5,http://localhost:8080/quote,29,0,0 +1674622106690,18,HTTP Request (/time),200,,Thread Group 1-1,text,true,,432,122,5,5,http://localhost:8080/time,18,0,0 +1674622106699,9,HTTP Request (/time),200,,Thread Group 1-3,text,true,,432,122,5,5,http://localhost:8080/time,9,0,0 +1674622106683,26,HTTP Request (/time),200,,Thread Group 1-4,text,true,,432,122,5,5,http://localhost:8080/time,25,0,0 +1674622106688,25,HTTP Request (/time),200,,Thread Group 1-2,text,true,,432,122,2,2,http://localhost:8080/time,25,0,0 +1674622106695,18,HTTP Request (/time),200,,Thread Group 1-5,text,true,,432,122,2,2,http://localhost:8080/time,17,0,0 diff --git a/jmeter/src/main/resources/dashboard/ReportsDashboard.jmx b/jmeter/src/main/resources/dashboard/ReportsDashboard.jmx new file mode 100644 index 0000000000..081920c671 --- /dev/null +++ b/jmeter/src/main/resources/dashboard/ReportsDashboard.jmx @@ -0,0 +1,127 @@ + + + + + + false + true + false + + + + + + + + Test Greetings Page + continue + + false + 1 + + 5 + 1 + false + + + true + + + + + + + localhost + 8080 + + + /greeting + GET + true + false + true + false + + + + + + + + + + localhost + 8080 + + + /quote + GET + true + false + true + false + + + + + + + + + + localhost + 8080 + + + /time + GET + true + false + true + false + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + dashapp + + + + + + diff --git a/jmeter/src/main/resources/static/index.html b/jmeter/src/main/resources/static/index.html new file mode 100644 index 0000000000..fe2e1bf095 --- /dev/null +++ b/jmeter/src/main/resources/static/index.html @@ -0,0 +1,15 @@ + + + + + Jmeter Dashboard Test APP + + + + +

Get your Quote here

+

Get your Time here

+

Get your greeting here

+ + + \ No newline at end of file diff --git a/jmeter/src/main/resources/templates/greeting.html b/jmeter/src/main/resources/templates/greeting.html new file mode 100644 index 0000000000..3b023db6b1 --- /dev/null +++ b/jmeter/src/main/resources/templates/greeting.html @@ -0,0 +1,10 @@ + + + + Jmeter Dashboard Test APP + + + +

+ + \ No newline at end of file diff --git a/jmeter/src/main/resources/templates/quote.html b/jmeter/src/main/resources/templates/quote.html new file mode 100644 index 0000000000..8d943c2a3d --- /dev/null +++ b/jmeter/src/main/resources/templates/quote.html @@ -0,0 +1,11 @@ + + + + Jmeter Dashboard Test APP + + + +

+

+ + \ No newline at end of file diff --git a/jmeter/src/main/resources/templates/time.html b/jmeter/src/main/resources/templates/time.html new file mode 100644 index 0000000000..d068bbe050 --- /dev/null +++ b/jmeter/src/main/resources/templates/time.html @@ -0,0 +1,10 @@ + + + + Jmeter Dashboard Test APP + + + +

+ + \ No newline at end of file diff --git a/kubernetes-modules/kubernetes-spring/pom.xml b/kubernetes-modules/kubernetes-spring/pom.xml index 01064fa384..05532ab0b0 100644 --- a/kubernetes-modules/kubernetes-spring/pom.xml +++ b/kubernetes-modules/kubernetes-spring/pom.xml @@ -3,11 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.example - demo + kubernetes-spring 0.0.1-SNAPSHOT - demo - Demo project for Spring Boot + kubernetes-spring + Intro to Kubernetes with Spring boot com.baeldung diff --git a/libraries-server-2/pom.xml b/libraries-server-2/pom.xml index 7377fa3fa9..359954a6d2 100644 --- a/libraries-server-2/pom.xml +++ b/libraries-server-2/pom.xml @@ -34,6 +34,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + org.eclipse.jetty jetty-maven-plugin diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index 937a88da09..bef4b25f1b 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -65,14 +65,14 @@ - com.sun.mail - javax.mail - ${javax.mail.version} + org.eclipse.angus + angus-mail + ${angus.mail.version} - javax.activation - javax.activation-api - ${javax.activation.version} + org.eclipse.angus + angus-activation + ${angus.activation.version} runtime @@ -116,8 +116,8 @@ 20180130 0.1.5 3.3.5 - 1.6.2 - 1.2.0 + 2.0.1 + 2.0.0 1.3.5 2.0.4 diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index cdcbc798a4..62c9ca5870 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -49,10 +49,7 @@ org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} - ${maven.compiler.source} - ${maven.compiler.target} org.mapstruct @@ -78,8 +75,6 @@ 1.5.3.Final 4.3.4.RELEASE - 1.8 - 1.8 0.2.0 diff --git a/pdf/sample.pdf b/pdf/sample.pdf new file mode 100644 index 0000000000..805a21e6e0 Binary files /dev/null and b/pdf/sample.pdf differ diff --git a/pdf/src/test/java/com/baeldung/pdfreadertest/ReadPdfFileUnitTest.java b/pdf/src/test/java/com/baeldung/pdfreadertest/ReadPdfFileUnitTest.java new file mode 100644 index 0000000000..83e3aa711a --- /dev/null +++ b/pdf/src/test/java/com/baeldung/pdfreadertest/ReadPdfFileUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.pdfreadertest; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.File; +import java.io.IOException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; +import org.junit.jupiter.api.Test; + +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.parser.PdfTextExtractor; + +class ReadPdfFileUnitTest { + + @Test + public void givenSamplePdf_whenUsingApachePdfBox_thenCompareOutput() throws IOException { + String expectedText = "Hello World!\n"; + + File file = new File("sample.pdf"); + PDDocument document = PDDocument.load(file); + + PDFTextStripper stripper = new PDFTextStripper(); + + String text = stripper.getText(document); + + document.close(); + + assertEquals(expectedText, text); + + } + + @Test + public void givenSamplePdf_whenUsingiTextPdf_thenCompareOutput() throws IOException { + String expectedText = "Hello World!"; + + PdfReader reader = new PdfReader("sample.pdf"); + int pages = reader.getNumberOfPages(); + StringBuilder text = new StringBuilder(); + + for (int i = 1; i <= pages; i++) { + + text.append(PdfTextExtractor.getTextFromPage(reader, i)); + + } + reader.close(); + assertEquals(expectedText, text.toString()); + + } + +} diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index 330f0d975a..ab133192a0 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -42,11 +42,6 @@ spring-boot-starter-test test - - org.junit.platform - junit-platform-runner - test - cglib cglib-nodep diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 83% rename from persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextLiveTest.java index 5167e63721..c370fdfecf 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/SpringContextLiveTest.java @@ -1,8 +1,8 @@ package com.baeldung; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; @@ -13,17 +13,17 @@ import redis.embedded.RedisServerBuilder; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisApplication.class) @DirtiesContext(classMode = ClassMode.BEFORE_CLASS) -public class SpringContextTest { +public class SpringContextLiveTest { private static redis.embedded.RedisServer redisServer; - @BeforeClass + @BeforeAll public static void startRedisServer() { redisServer = new RedisServerBuilder().port(6379).setting("maxmemory 256M").build(); redisServer.start(); } - @AfterClass + @AfterAll public static void stopRedisServer() { redisServer.stop(); } diff --git a/pom.xml b/pom.xml index 0b19c6eee6..431d712c6b 100644 --- a/pom.xml +++ b/pom.xml @@ -330,161 +330,104 @@ parent-spring-5 parent-java - akka-modules - algorithms-modules - annotations - antlr apache-cxf-modules - apache-kafka - apache-kafka-2 apache-libraries - apache-olingo apache-poi - apache-poi-2 - apache-rocketmq - apache-thrift - apache-tika apache-velocity - + di-modules asciidoctor - asm - - atomix aws-modules - axon - azure - - bazel checker-plugin - code-generation core-groovy-modules - core-java-modules - couchbase custom-pmd - data-structures - ddd deeplearning4j - di-modules - discord4j - disruptor - dozer drools - dubbo + - feign - + geotools - google-cloud + gradle-modules/gradle/maven-to-gradle - graphql-modules - grpc + guava-modules - hazelcast apache-httpclient httpclient-simple - hystrix + jackson-modules - jackson-simple - java-blockchain + javafx java-jdi - java-rmi - java-spi java-websocket - javax-sound - javaxval - javaxval-2 - javax-validation-advanced + jaxb jersey - jgit jhipster-5 - jib jmeter jmh - java-native + jsf json-modules - jsoup + kubernetes-modules - ksqldb + language-interop libraries-2 libraries-3 - libraries-7 - - libraries-apache-commons - libraries-apache-commons-collections - libraries-apache-commons-io libraries-data - libraries-data-2 + + libraries-data-db - libraries-data-io - libraries-files - libraries-http - libraries-http-2 - libraries-io - libraries-primitive - libraries-rpc libraries-security - libraries-server libraries-server-2 libraries-testing logging-modules lombok-modules - lucene - mapstruct maven-modules - mesos-marathon messaging-modules - metrics + microservices-modules muleesb - mustache - mybatis + netflix-modules - orika osgi + orika patterns-modules - pdf - pdf-2 + performance-tests persistence-modules - protobuffer + quarkus-modules - reactor-core - rsocket rule-engines-modules rxjava-modules - atomikos + reactive-systems security-modules - slack + vavr-modules web-modules @@ -533,93 +476,51 @@ saas-modules server-modules - spf4j - spring-4 - - spring-5 spring-reactive-modules - spring-5-webflux - spring-5-webflux-2 - - spring-activiti spring-aop spring-aop-2 - spring-batch - spring-batch-2 spring-bom spring-boot-modules spring-boot-rest - spring-caching - spring-caching-2 - spring-cloud-modules - spring-core - spring-core-2 - spring-core-3 spring-core-4 - spring-core-5 - spring-credhub - spring-cucumber - spring-di spring-di-2 - spring-di-3 spring-drools - spring-ejb-modules + spring-exceptions - spring-integration - spring-jenkins-pipeline spring-jersey spring-jinq - - spring-kafka spring-katharsis - spring-mobile - spring-native - spring-protobuf - spring-quartz - spring-remoting-modules + - spring-scheduling spring-security-modules spring-shell spring-soap spring-spel - spring-state-machine spring-static-resources spring-swagger-codegen - - spring-threads - spring-vault - spring-web-modules spring-websockets - static-analysis - - tensorflow-java testing-modules - vertx-modules video-tutorials - - webrtc xml xml-2 - xstream @@ -674,7 +575,6 @@ libraries-4 libraries-5 libraries-6 - spring-boot-modules/spring-boot-react spring-ejb-modules/ejb-beans @@ -715,161 +615,104 @@ parent-spring-5 parent-java - akka-modules - algorithms-modules - annotations - antlr apache-cxf-modules - apache-kafka - apache-kafka-2 apache-libraries - apache-olingo apache-poi - apache-poi-2 - apache-rocketmq - apache-thrift - apache-tika apache-velocity - + di-modules asciidoctor - asm - - atomix aws-modules - axon - azure - - bazel checker-plugin - code-generation core-groovy-modules - core-java-modules - couchbase custom-pmd - data-structures - ddd deeplearning4j - di-modules - discord4j - disruptor - dozer drools - dubbo + - feign - + geotools - google-cloud + gradle-modules/gradle/maven-to-gradle - graphql-modules - grpc + guava-modules - hazelcast apache-httpclient httpclient-simple - hystrix + jackson-modules - jackson-simple - java-blockchain + javafx java-jdi - java-rmi - java-spi java-websocket - javax-sound - javaxval - javaxval-2 - javax-validation-advanced + jaxb jersey - jgit jhipster-5 - jib jmeter jmh - java-native + jsf json-modules - jsoup + kubernetes-modules - ksqldb + language-interop libraries-2 libraries-3 - libraries-7 - - libraries-apache-commons - libraries-apache-commons-collections - libraries-apache-commons-io libraries-data - libraries-data-2 + + libraries-data-db - libraries-data-io - libraries-files - libraries-http - libraries-http-2 - libraries-io - libraries-primitive - libraries-rpc libraries-security - libraries-server libraries-server-2 libraries-testing logging-modules lombok-modules - lucene - mapstruct maven-modules - mesos-marathon messaging-modules - metrics + microservices-modules muleesb - mustache - mybatis + netflix-modules - orika osgi + orika patterns-modules - pdf - pdf-2 + performance-tests persistence-modules - protobuffer + quarkus-modules - reactor-core - rsocket rule-engines-modules rxjava-modules - atomikos + reactive-systems security-modules - slack + vavr-modules web-modules @@ -910,94 +753,50 @@ saas-modules server-modules - spf4j - spring-4 - - spring-5 spring-reactive-modules - spring-5-webflux - spring-5-webflux-2 - - - spring-activiti spring-aop spring-aop-2 - spring-batch - spring-batch-2 spring-bom spring-boot-modules spring-boot-rest - spring-caching - spring-caching-2 - spring-cloud-modules - spring-core - spring-core-2 - spring-core-3 spring-core-4 - spring-core-5 - spring-credhub - spring-cucumber - spring-di spring-di-2 - spring-di-3 spring-drools - spring-ejb-modules spring-exceptions - spring-integration - spring-jenkins-pipeline spring-jersey spring-jinq - - spring-kafka spring-katharsis - spring-mobile - spring-native - spring-protobuf - spring-quartz - spring-remoting-modules + - spring-scheduling spring-security-modules spring-shell spring-soap spring-spel - spring-state-machine spring-static-resources spring-swagger-codegen - - spring-threads - spring-vault - spring-web-modules spring-websockets - static-analysis - - tensorflow-java testing-modules - vertx-modules video-tutorials - - webrtc xml xml-2 - xstream @@ -1044,12 +843,10 @@ libraries-4 libraries-5 libraries-6 - spring-boot-modules/spring-boot-react spring-ejb-modules/ejb-beans - vaadin - vavr-modules + vavr-modules @@ -1119,64 +916,173 @@ core-java-modules/core-java-9-improvements core-java-modules/core-java-9-jigsaw - core-java-modules/core-java-9-streams - core-java-modules/core-java-10 - core-java-modules/core-java-11 - core-java-modules/core-java-11-2 - core-java-modules/core-java-11-3 - - - - - - - - core-java-modules/core-java-collections-set - core-java-modules/core-java-collections-list-4 - core-java-modules/core-java-collections-array-list - core-java-modules/core-java-collections-maps-4 - core-java-modules/core-java-collections-maps-5 - core-java-modules/core-java-concurrency-simple - core-java-modules/core-java-date-operations-1 - core-java-modules/core-java-datetime-conversion - core-java-modules/core-java-datetime-string - core-java-modules/core-java-io-conversions-2 - core-java-modules/core-java-jpms - core-java-modules/core-java-os - core-java-modules/core-java-streams-4 - core-java-modules/core-java-string-algorithms-3 - core-java-modules/core-java-string-operations-3 - core-java-modules/core-java-string-operations-4 - core-java-modules/core-java-string-operations-5 - core-java-modules/core-java-time-measurements - core-java-modules/core-java-networking-3 - core-java-modules/core-java-strings - core-java-modules/core-java-httpclient - spring-core-6 - ddd-contexts - docker-modules - apache-httpclient-2 - kubernetes-modules/kubernetes-spring - libraries-concurrency - maven-modules/compiler-plugin-java-9 - maven-modules/maven-generate-war - maven-modules/multimodulemavenproject - optaplanner - persistence-modules/sirix - persistence-modules/spring-data-cassandra-2 - quarkus-modules/quarkus-vs-springboot - quarkus-modules/quarkus-jandex - spring-boot-modules/spring-boot-cassandre - spring-boot-modules/spring-boot-camel - spring-boot-modules/spring-boot-3 - spring-boot-modules/spring-boot-3-native + core-java-modules/core-java-9-streams + core-java-modules/core-java-10 + core-java-modules/core-java-11 + core-java-modules/core-java-11-2 + core-java-modules/core-java-11-3 + + + + + + + + core-java-modules/core-java-collections-set + core-java-modules/core-java-collections-list-4 + core-java-modules/core-java-collections-array-list + core-java-modules/core-java-collections-maps-4 + core-java-modules/core-java-collections-maps-5 + core-java-modules/core-java-concurrency-simple + core-java-modules/core-java-date-operations-1 + core-java-modules/core-java-datetime-conversion + core-java-modules/core-java-datetime-string + core-java-modules/core-java-io-conversions-2 + core-java-modules/core-java-jpms + core-java-modules/core-java-os + core-java-modules/core-java-streams-4 + core-java-modules/core-java-string-algorithms-3 + core-java-modules/core-java-string-operations-3 + core-java-modules/core-java-string-operations-4 + core-java-modules/core-java-string-operations-5 + core-java-modules/core-java-time-measurements + core-java-modules/core-java-networking-3 + core-java-modules/core-java-strings + core-java-modules/core-java-httpclient + spring-core-6 + ddd-contexts + docker-modules + apache-httpclient-2 + kubernetes-modules/kubernetes-spring + libraries-concurrency + maven-modules/compiler-plugin-java-9 + maven-modules/maven-generate-war + maven-modules/multimodulemavenproject + optaplanner + persistence-modules/sirix + persistence-modules/spring-data-cassandra-2 + quarkus-modules/quarkus-vs-springboot + quarkus-modules/quarkus-jandex + spring-boot-modules/spring-boot-cassandre + spring-boot-modules/spring-boot-camel + spring-boot-modules/spring-boot-3 + spring-boot-modules/spring-boot-3-native spring-boot-modules/spring-boot-3-observation - spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules/testing-assertions - persistence-modules/fauna - lightrun - tablesaw + spring-swagger-codegen/custom-validations-opeanpi-codegen + testing-modules/testing-assertions + persistence-modules/fauna + lightrun + tablesaw + + + + akka-modules + annotations + apache-httpclient + antlr + apache-kafka + apache-kafka-2 + apache-olingo + + apache-poi-2 + apache-rocketmq + apache-thrift + apache-tika + + asm + atomikos + atomix + axon + + bazel + code-generation + ddd + discord4j + disruptor + dozer + dubbo + feign + google-cloud + graphql-modules + grpc + hazelcast + hystrix + jackson-simple + java-blockchain + + java-rmi + java-spi + javax-sound + javaxval + javaxval-2 + javax-validation-advanced + jgit + jib + + java-native + jsoup + ksqldb + libraries-7 + libraries-apache-commons + libraries-apache-commons-collections + libraries-apache-commons-io + libraries-data-2 + libraries-data-io + libraries-files + libraries-http + libraries-http-2 + libraries-io + libraries-primitive + libraries-rpc + libraries-server + + lucene + mapstruct + mesos-marathon + metrics + mustache + mybatis + pdf + pdf-2 + protobuffer + reactor-core + rsocket + slack + + + + spring-5 + spring-5-webflux + spring-5-webflux-2 + spring-activiti + spring-batch-2 + spring-caching-2 + spring-core-2 + spring-core-3 + spring-core-5 + spring-di-3 + spring-cucumber + + spring-kafka + + spring-native + spring-protobuf + spring-quartz + + spring-scheduling + + spring-state-machine + spring-threads + tensorflow-java + xstream + webrtc + + + UTF-8 + 11 + 11 + @@ -1217,8 +1123,10 @@ + core-java-modules/core-java-collections-set core-java-modules/core-java-collections-list-4 + core-java-modules/core-java-collections-array-list core-java-modules/core-java-collections-maps-4 core-java-modules/core-java-collections-maps-5 core-java-modules/core-java-concurrency-simple @@ -1237,6 +1145,7 @@ core-java-modules/core-java-networking-3 core-java-modules/core-java-strings core-java-modules/core-java-httpclient + spring-core-6 ddd-contexts docker-modules apache-httpclient-2 @@ -1259,9 +1168,132 @@ testing-modules/testing-assertions persistence-modules/fauna lightrun - spring-core-6 tablesaw + + + + akka-modules + annotations + apache-httpclient + antlr + apache-kafka + apache-kafka-2 + apache-olingo + + apache-poi-2 + apache-rocketmq + apache-thrift + apache-tika + + asm + atomikos + atomix + axon + + bazel + code-generation + ddd + discord4j + disruptor + dozer + + dubbo + feign + google-cloud + graphql-modules + grpc + hazelcast + hystrix + jackson-simple + java-blockchain + + java-rmi + java-spi + javax-sound + javaxval + javaxval-2 + javax-validation-advanced + jgit + jib + + java-native + jsoup + ksqldb + + libraries-7 + libraries-apache-commons + libraries-apache-commons-collections + libraries-apache-commons-io + libraries-data-2 + libraries-data-io + libraries-files + libraries-http + libraries-http-2 + libraries-io + libraries-primitive + libraries-rpc + libraries-server + + lucene + mapstruct + mesos-marathon + metrics + mustache + mybatis + pdf + pdf-2 + protobuffer + reactor-core + rsocket + slack + + + + + spring-5 + spring-5-webflux + spring-5-webflux-2 + spring-activiti + spring-batch-2 + spring-caching-2 + spring-core-2 + spring-core-3 + spring-core-5 + spring-di-3 + spring-cucumber + + spring-kafka + + spring-native + spring-protobuf + spring-quartz + + spring-scheduling + + spring-state-machine + spring-threads + tensorflow-java + xstream + webrtc + + + UTF-8 + 11 + 11 + + + + + parents + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java index 7fc3732ba5..9bf934b504 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java @@ -1,22 +1,22 @@ package com.baeldung.webflux.caching; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; -import reactor.cache.CacheMono; + import reactor.core.publisher.Mono; @Service public class ItemService { private final ItemRepository repository; - private final LoadingCache cache; + private final LoadingCache> cache; public ItemService(ItemRepository repository) { this.repository = repository; - this.cache = Caffeine.newBuilder() - .build(this::getItem_withAddons); + this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine); } @Cacheable("items") @@ -34,9 +34,7 @@ public class ItemService { } @Cacheable("items") - public Mono getItem_withAddons(String id) { - return CacheMono.lookup(cache.asMap(), id) - .onCacheMissResume(() -> repository.findById(id).cast(Object.class)).cast(Item.class); + public Mono getItem_withCaffeine(String id) { + return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class)); } - } diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java index 028a6d33a3..2075c1e77e 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java @@ -73,19 +73,19 @@ public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { } @Test - public void givenItem_whenGetItemWithAddonsIsCalled_thenMonoResultIsCached() { + public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); String id = glass.block().get_id(); - Mono mono = itemService.getItem_withAddons(id); + Mono mono = itemService.getItem_withCaffeine(id); Item item = mono.block(); assertThat(item).isNotNull(); assertThat(item.getName()).isEqualTo("glass"); assertThat(item.getPrice()).isEqualTo(1.00); - Mono mono2 = itemService.getItem_withAddons(id); + Mono mono2 = itemService.getItem_withCaffeine(id); Item item2 = mono2.block(); assertThat(item2).isNotNull(); diff --git a/spring-boot-modules/spring-boot-3-native/README.md b/spring-boot-modules/spring-boot-3-native/README.md index 6f46263257..025a40c1d0 100644 --- a/spring-boot-modules/spring-boot-3-native/README.md +++ b/spring-boot-modules/spring-boot-3-native/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Native Images with Spring Boot and GraalVM](https://www.baeldung.com/spring-native-intro) +- [Ahead of Time Optimizations in Spring 6](https://www.baeldung.com/spring-6-ahead-of-time-optimizations) diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java index 363b310c8c..11a75ba881 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java @@ -2,5 +2,5 @@ package com.baeldung.boot.readonlyrepository; import org.springframework.data.repository.CrudRepository; -public interface BookRepository extends BookReadOnlyRepository, CrudRepository { +public interface BookRepository extends CrudRepository { } diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index d13ef22345..34e93299ae 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -18,10 +18,6 @@ - - org.springframework.boot - spring-boot-starter - org.springframework.boot spring-boot-starter-oauth2-resource-server @@ -93,12 +89,16 @@ com.baeldung - src/main/resources/products.xsd + /${project.basedir}/src/main/resources/products.xsd + + + com.baeldung.keycloak.SpringBoot + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java index c85438952a..1ad22d9397 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -30,7 +30,7 @@ class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() - .antMatchers("/customers*", "/users*") + .antMatchers("/customers*") .hasRole("USER") .anyRequest() .permitAll(); diff --git a/spring-boot-modules/spring-boot-logging-log4j2/README.md b/spring-boot-modules/spring-boot-logging-log4j2/README.md index 9688f8f83c..45d6c0a2f5 100644 --- a/spring-boot-modules/spring-boot-logging-log4j2/README.md +++ b/spring-boot-modules/spring-boot-logging-log4j2/README.md @@ -7,3 +7,4 @@ This module contains articles about logging in Spring Boot projects with Log4j 2 - [Logging to Graylog with Spring Boot](https://www.baeldung.com/graylog-with-spring-boot) - [Log Groups in Spring Boot 2.1](https://www.baeldung.com/spring-boot-log-groups) - [Writing Log Data to Syslog Using Log4j2](https://www.baeldung.com/log4j-to-syslog) +- [Spring Boot Logback and Log4j2 Extensions](https://www.baeldung.com/spring-boot-logback-log4j2) diff --git a/spring-boot-modules/spring-boot-mvc-birt/pom.xml b/spring-boot-modules/spring-boot-mvc-birt/pom.xml index badf77735f..274932f06c 100644 --- a/spring-boot-modules/spring-boot-mvc-birt/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-birt/pom.xml @@ -9,13 +9,11 @@ jar Module For Spring Boot Integration with BIRT - - - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE - + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/Application.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/Application.java index 40f5341e29..24174815fa 100644 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/Application.java +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/Application.java @@ -1,19 +1,18 @@ package com.baeldung.web.log.app; -import javax.servlet.ServletRegistration; - import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.PropertySource; -import com.baeldung.web.log.config.CustomeRequestLoggingFilter; - -@EnableAutoConfiguration @ComponentScan("com.baeldung.web.log") @PropertySource("application-log.properties") -@SpringBootApplication +@SpringBootApplication(exclude = { + SecurityAutoConfiguration.class, + ManagementWebSecurityAutoConfiguration.class +}) public class Application { public static void main(final String[] args) { diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedHttpServletRequest.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedHttpServletRequest.java new file mode 100644 index 0000000000..51bbd51ea8 --- /dev/null +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedHttpServletRequest.java @@ -0,0 +1,30 @@ +package com.baeldung.web.log.app; + +import org.springframework.util.StreamUtils; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; + +public class CachedHttpServletRequest extends HttpServletRequestWrapper { + + private byte[] cachedPayload; + + public CachedHttpServletRequest(HttpServletRequest request) throws IOException { + super(request); + InputStream requestInputStream = request.getInputStream(); + this.cachedPayload = StreamUtils.copyToByteArray(requestInputStream); + } + + @Override + public ServletInputStream getInputStream() { + return new CachedServletInputStream(this.cachedPayload); + } + + @Override + public BufferedReader getReader() { + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedPayload); + return new BufferedReader(new InputStreamReader(byteArrayInputStream)); + } +} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedServletInputStream.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedServletInputStream.java new file mode 100644 index 0000000000..673d04876b --- /dev/null +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/CachedServletInputStream.java @@ -0,0 +1,45 @@ +package com.baeldung.web.log.app; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class CachedServletInputStream extends ServletInputStream { + + private final static Logger LOGGER = LoggerFactory.getLogger(CachedServletInputStream.class); + private InputStream cachedInputStream; + + public CachedServletInputStream(byte[] cachedBody) { + this.cachedInputStream = new ByteArrayInputStream(cachedBody); + } + + @Override + public boolean isFinished() { + try { + return cachedInputStream.available() == 0; + } catch (IOException exp) { + LOGGER.error(exp.getMessage()); + } + return false; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + throw new UnsupportedOperationException(); + } + + @Override + public int read() throws IOException { + return cachedInputStream.read(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/RequestCachingFilter.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/RequestCachingFilter.java new file mode 100644 index 0000000000..e0928550fc --- /dev/null +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/RequestCachingFilter.java @@ -0,0 +1,33 @@ +package com.baeldung.web.log.app; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@Order(value = Ordered.HIGHEST_PRECEDENCE) +@Component +@WebFilter(filterName = "RequestCachingFilter", urlPatterns = "/*") +public class RequestCachingFilter extends OncePerRequestFilter { + + private final static Logger LOGGER = LoggerFactory.getLogger(RequestCachingFilter.class); + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + CachedHttpServletRequest cachedHttpServletRequest = new CachedHttpServletRequest(request); + LOGGER.info("REQUEST DATA: " + IOUtils.toString(cachedHttpServletRequest.getInputStream(), StandardCharsets.UTF_8)); + filterChain.doFilter(cachedHttpServletRequest, response); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java deleted file mode 100644 index 2ea0204dc3..0000000000 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/app/TaxiFareRequestInterceptor.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.baeldung.web.log.app; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; -import org.springframework.web.util.ContentCachingRequestWrapper; - -import com.baeldung.web.log.util.RequestLoggingUtil; - -@Component -public class TaxiFareRequestInterceptor extends HandlerInterceptorAdapter { - - private final static Logger LOGGER = LoggerFactory.getLogger(TaxiFareRequestInterceptor.class); - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - String postData; - HttpServletRequest requestCacheWrapperObject = null; - try { - // Uncomment to produce the stream closed issue - // postData = RequestLoggingUtil.getStringFromInputStream(request.getInputStream()); - - // To overcome request stream closed issue - requestCacheWrapperObject = new ContentCachingRequestWrapper(request); - requestCacheWrapperObject.getParameterMap(); - } catch (Exception exception) { - exception.printStackTrace(); - } finally { - postData = RequestLoggingUtil.readPayload(requestCacheWrapperObject); - LOGGER.info("REQUEST DATA: " + postData); - } - return true; - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - LOGGER.info("RESPONSE: " + response.getStatus()); - } - -} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomWebAppInitializer.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomWebAppInitializer.java deleted file mode 100644 index 0f19c6dc48..0000000000 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomWebAppInitializer.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.web.log.config; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - -import org.springframework.web.context.ContextLoaderListener; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.WebApplicationInitializer; - -public class CustomWebAppInitializer implements WebApplicationInitializer { - - @Override - public void onStartup(ServletContext container) throws ServletException { - - AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - context.setConfigLocation("com.baeldung.web.log"); - container.addListener(new ContextLoaderListener(context)); - - ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(context)); - dispatcher.setLoadOnStartup(1); - dispatcher.addMapping("/"); - - container.addFilter("customRequestLoggingFilter", CustomeRequestLoggingFilter.class).addMappingForServletNames(null, false, "dispatcher"); - } -} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomeRequestLoggingFilter.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomeRequestLoggingFilter.java deleted file mode 100644 index 3accb0a06e..0000000000 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/CustomeRequestLoggingFilter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.web.log.config; - -import org.springframework.web.filter.CommonsRequestLoggingFilter; - -public class CustomeRequestLoggingFilter extends CommonsRequestLoggingFilter { - - public CustomeRequestLoggingFilter() { - super.setIncludeQueryString(true); - super.setIncludePayload(true); - super.setMaxPayloadLength(10000); - } -} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java index 85728729d5..a0622d45d2 100644 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/RequestLoggingFilterConfig.java @@ -14,7 +14,7 @@ public class RequestLoggingFilterConfig { filter.setIncludePayload(true); filter.setMaxPayloadLength(10000); filter.setIncludeHeaders(false); - filter.setAfterMessagePrefix("REQUEST DATA : "); + filter.setAfterMessagePrefix("REQUEST DATA: "); return filter; } } diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java deleted file mode 100644 index fda8a845e9..0000000000 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/config/TaxiFareMVCConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.web.log.config; - -import com.baeldung.web.log.app.TaxiFareRequestInterceptor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -public class TaxiFareMVCConfig implements WebMvcConfigurer { - - @Autowired - private TaxiFareRequestInterceptor taxiFareRequestInterceptor; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(taxiFareRequestInterceptor).addPathPatterns("/taxifare/*/"); - } -} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java deleted file mode 100644 index 70c4eaee90..0000000000 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/web/log/util/RequestLoggingUtil.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.web.log.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.io.IOUtils; -import org.springframework.web.util.ContentCachingRequestWrapper; -import org.springframework.web.util.WebUtils; - -public class RequestLoggingUtil { - - public static String getStringFromInputStream(InputStream is) { - StringWriter writer = new StringWriter(); - String encoding = "UTF-8"; - try { - IOUtils.copy(is, writer, encoding); - } catch (IOException e) { - e.printStackTrace(); - } - return writer.toString(); - } - - public static String readPayload(final HttpServletRequest request) throws IOException { - String payloadData = null; - ContentCachingRequestWrapper contentCachingRequestWrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class); - if (null != contentCachingRequestWrapper) { - byte[] buf = contentCachingRequestWrapper.getContentAsByteArray(); - if (buf.length > 0) { - payloadData = new String(buf, 0, buf.length, contentCachingRequestWrapper.getCharacterEncoding()); - } - } - return payloadData; - } - -} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-runtime/src/main/resources/logback.xml index 7d900d8ea8..4552282d23 100644 --- a/spring-boot-modules/spring-boot-runtime/src/main/resources/logback.xml +++ b/spring-boot-modules/spring-boot-runtime/src/main/resources/logback.xml @@ -7,6 +7,10 @@ + + + + diff --git a/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/web/controller/TaxiFareControllerIntegrationTest.java b/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/web/controller/TaxiFareControllerIntegrationTest.java index 97d669d3fa..b98c77ad2b 100644 --- a/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/web/controller/TaxiFareControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-runtime/src/test/java/com/baeldung/web/controller/TaxiFareControllerIntegrationTest.java @@ -1,23 +1,19 @@ package com.baeldung.web.controller; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - +import com.baeldung.web.log.app.Application; +import com.baeldung.web.log.data.TaxiRide; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.context.annotation.Configuration; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import com.baeldung.web.log.app.Application; -import com.baeldung.web.log.data.TaxiRide; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; @RunWith(SpringRunner.class) -@SpringBootTest(classes = { Application.class, TaxiFareControllerIntegrationTest.SecurityConfig.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = { Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class TaxiFareControllerIntegrationTest { @LocalServerPort @@ -25,8 +21,6 @@ public class TaxiFareControllerIntegrationTest { @Test public void givenRequest_whenFetchTaxiFareRateCard_thanOK() { - - System.out.println(port); String URL = "http://localhost:" + port + "/spring-rest"; TestRestTemplate testRestTemplate = new TestRestTemplate(); TaxiRide taxiRide = new TaxiRide(true, 10l); @@ -37,16 +31,4 @@ public class TaxiFareControllerIntegrationTest { assertThat(fare, equalTo("200")); } - @Configuration - static class SecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - System.out.println("security being set"); - http - .authorizeRequests() - .anyRequest().permitAll() - .and() - .csrf().disable(); - } - } } \ No newline at end of file diff --git a/spring-cloud-modules/pom.xml b/spring-cloud-modules/pom.xml index 68aa4cd2e5..43e2687d74 100644 --- a/spring-cloud-modules/pom.xml +++ b/spring-cloud-modules/pom.xml @@ -55,6 +55,7 @@ spring-cloud-data-flow spring-cloud-sleuth spring-cloud-openfeign-2 + spring-cloud-open-telemetry diff --git a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-additionalsources/pom.xml b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-additionalsources/pom.xml index f523e79bac..eee751b6a4 100644 --- a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-additionalsources/pom.xml +++ b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-additionalsources/pom.xml @@ -3,7 +3,7 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-cloud-archaius-additional-sources-simple + spring-cloud-archaius-additionalsources 1.0.0-SNAPSHOT spring-cloud-archaius-additionalsources jar diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/docker-compose.yml b/spring-cloud-modules/spring-cloud-open-telemetry/docker-compose.yml new file mode 100644 index 0000000000..8a6833095c --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/docker-compose.yml @@ -0,0 +1,30 @@ +version: "4.0" + +services: + product-service: + platform: linux/x86_64 + build: spring-cloud-open-telemetry1/ + ports: + - "8080:8080" + + price-service: + platform: linux/x86_64 + build: spring-cloud-open-telemetry2/ + ports: + - "8081" + + jaeger-service: + image: jaegertracing/all-in-one:latest + ports: + - "16686:16686" + - "14250" + + collector: + image: otel/opentelemetry-collector:0.47.0 + command: [ "--config=/etc/otel-collector-config.yml" ] + volumes: + - ./otel-config.yml:/etc/otel-collector-config.yml + ports: + - "4317:4317" + depends_on: + - jaeger-service \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/otel-config.yml b/spring-cloud-modules/spring-cloud-open-telemetry/otel-config.yml new file mode 100644 index 0000000000..886c10a1c3 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/otel-config.yml @@ -0,0 +1,23 @@ +receivers: + otlp: + protocols: + grpc: + http: + +processors: + batch: + +exporters: + logging: + logLevel: debug + jaeger: + endpoint: jaeger-service:14250 + tls: + insecure: true + +service: + pipelines: + traces: + receivers: [ otlp ] + processors: [ batch ] + exporters: [ logging, jaeger ] diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/pom.xml b/spring-cloud-modules/spring-cloud-open-telemetry/pom.xml new file mode 100644 index 0000000000..69b3a1a478 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/pom.xml @@ -0,0 +1,22 @@ + + 4.0.0 + com.baeldung.spring.cloud + spring-cloud-open-telemetry + 1.0.0-SNAPSHOT + spring-cloud-open-telemetry + pom + + + com.baeldung.spring.cloud + spring-cloud-modules + 1.0.0-SNAPSHOT + + + + spring-cloud-open-telemetry1 + spring-cloud-open-telemetry2 + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/Dockerfile b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/Dockerfile new file mode 100644 index 0000000000..8bae52cec4 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/Dockerfile @@ -0,0 +1,7 @@ +FROM adoptopenjdk/openjdk11:alpine + +COPY target/spring-cloud-open-telemetry1-1.0.0-SNAPSHOT.jar spring-cloud-open-telemetry.jar + +EXPOSE 8081 + +ENTRYPOINT ["java","-jar","/spring-cloud-open-telemetry.jar"] \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/pom.xml b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/pom.xml new file mode 100644 index 0000000000..5011590e73 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + spring-cloud-open-telemetry1 + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT + spring-cloud-open-telemetry1 + jar + + + com.baeldung.spring.cloud + spring-cloud-open-telemetry + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot-dependencies.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${release.train.version} + pom + import + + + org.springframework.cloud + spring-cloud-sleuth-otel-dependencies + ${spring-cloud-sleuth-otel.version} + import + pom + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-brave + + + + + org.springframework.cloud + spring-cloud-sleuth-otel-autoconfigure + + + io.opentelemetry + opentelemetry-exporter-otlp-trace + + + io.grpc + grpc-okhttp + ${grpc-okhttp.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + + spring-milestones + https://repo.spring.io/milestone + + + + + spring-milestones + https://repo.spring.io/milestone + + + + + 2.5.7 + 2020.0.4 + 1.0.0-M12 + 1.42.1 + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/ProductApplication.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/ProductApplication.java new file mode 100644 index 0000000000..8427603340 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/ProductApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.opentelemetry; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductApplication.class, args); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/api/client/PriceClient.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/api/client/PriceClient.java new file mode 100644 index 0000000000..d8b43b61a5 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/api/client/PriceClient.java @@ -0,0 +1,34 @@ +package com.baeldung.opentelemetry.api.client; + +import com.baeldung.opentelemetry.model.Price; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.client.RestTemplate; + +@Component +public class PriceClient { + + private static final Logger LOGGER = LoggerFactory.getLogger(PriceClient.class); + + private final RestTemplate restTemplate; + + @Autowired + public PriceClient(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + @Value("${priceClient.baseUrl}") + private String baseUrl; + + public Price getPrice(@PathVariable("id") long productId){ + LOGGER.info("Fetching Price Details With Product Id {}", productId); + String url = String.format("%s/price/%d", baseUrl, productId); + ResponseEntity price = restTemplate.getForEntity(url, Price.class); + return price.getBody(); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/configuration/RestConfiguration.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/configuration/RestConfiguration.java new file mode 100644 index 0000000000..5d8ba4beac --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/configuration/RestConfiguration.java @@ -0,0 +1,15 @@ +package com.baeldung.opentelemetry.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestConfiguration { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/controller/ProductController.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/controller/ProductController.java new file mode 100644 index 0000000000..5586f5e9d0 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/controller/ProductController.java @@ -0,0 +1,36 @@ +package com.baeldung.opentelemetry.controller; + +import com.baeldung.opentelemetry.api.client.PriceClient; +import com.baeldung.opentelemetry.model.Product; +import com.baeldung.opentelemetry.repository.ProductRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ProductController { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductController.class); + + private final PriceClient priceClient; + + private final ProductRepository productRepository; + + @Autowired + public ProductController(PriceClient priceClient, ProductRepository productRepository) { + this.priceClient = priceClient; + this.productRepository = productRepository; + } + + @GetMapping(path = "/product/{id}") + public Product getProductDetails(@PathVariable("id") long productId){ + LOGGER.info("Getting Product and Price Details With Product Id {}", productId); + Product product = productRepository.getProduct(productId); + product.setPrice(priceClient.getPrice(productId)); + + return product; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java new file mode 100644 index 0000000000..0ab031f517 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java @@ -0,0 +1,22 @@ +package com.baeldung.opentelemetry.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.client.HttpServerErrorException; + + +@RestControllerAdvice +public class ProductControllerAdvice { + + @ExceptionHandler(ProductNotFoundException.class) + public ResponseEntity handleProductNotFoundException(ProductNotFoundException exception) { + return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); + } + + @ExceptionHandler(HttpServerErrorException.ServiceUnavailable.class) + public ResponseEntity handleException(HttpServerErrorException.ServiceUnavailable exception) { + return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductNotFoundException.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductNotFoundException.java new file mode 100644 index 0000000000..9b698d5416 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/exception/ProductNotFoundException.java @@ -0,0 +1,7 @@ +package com.baeldung.opentelemetry.exception; + +public class ProductNotFoundException extends RuntimeException { + public ProductNotFoundException(String productNotFound) { + super(productNotFound); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Price.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Price.java new file mode 100644 index 0000000000..dccaf978fd --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Price.java @@ -0,0 +1,39 @@ +package com.baeldung.opentelemetry.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Price { + + @JsonProperty("productId") + private long productId; + + @JsonProperty("price_amount") + private double priceAmount; + + @JsonProperty("discount") + private double discount; + + public long getProductId() { + return productId; + } + + public void setProductId(long productId) { + this.productId = productId; + } + + public double getPriceAmount() { + return priceAmount; + } + + public void setPriceAmount(double priceAmount) { + this.priceAmount = priceAmount; + } + + public double getDiscount() { + return discount; + } + + public void setDiscount(double discount) { + this.discount = discount; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Product.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Product.java new file mode 100644 index 0000000000..2a3a279dd8 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/model/Product.java @@ -0,0 +1,27 @@ +package com.baeldung.opentelemetry.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Product { + + @JsonProperty("id") + private long id; + + @JsonProperty("name") + private String name; + + @JsonProperty("price") + private Price price; + + public void setId(long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setPrice(Price price) { + this.price = price; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/repository/ProductRepository.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/repository/ProductRepository.java new file mode 100644 index 0000000000..07f94f626e --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/java/com/baeldung/opentelemetry/repository/ProductRepository.java @@ -0,0 +1,55 @@ +package com.baeldung.opentelemetry.repository; + +import com.baeldung.opentelemetry.exception.ProductNotFoundException; +import com.baeldung.opentelemetry.model.Product; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; + +@Component +public class ProductRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductRepository.class); + + private final Map productMap = new HashMap<>(); + + public Product getProduct(Long productId){ + LOGGER.info("Getting Product from Product Repo With Product Id {}", productId); + + if(!productMap.containsKey(productId)){ + LOGGER.error("Product Not Found for Product Id {}", productId); + throw new ProductNotFoundException("Product Not Found"); + } + + return productMap.get(productId); + } + + @PostConstruct + private void setupRepo() { + Product product1 = getProduct(100001, "apple"); + productMap.put(100001L, product1); + + Product product2 = getProduct(100002, "pears"); + productMap.put(100002L, product2); + + Product product3 = getProduct(100003, "banana"); + productMap.put(100003L, product3); + + Product product4 = getProduct(100004, "mango"); + productMap.put(100004L, product4); + + Product product5 = getProduct(100005, "test"); + productMap.put(100005L, product5); + } + + private static Product getProduct(int id, String name) { + Product product = new Product(); + product.setId(id); + product.setName(name); + return product; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/resources/application.properties new file mode 100644 index 0000000000..1645b6144d --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/main/resources/application.properties @@ -0,0 +1,5 @@ +server.port= 8080 +spring.application.name=product-service +priceClient.baseUrl=http://price-service:8081 +spring.sleuth.otel.config.trace-id-ratio-based=1.0 +spring.sleuth.otel.exporter.otlp.endpoint=http://collector:4317 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java new file mode 100644 index 0000000000..4f4a918cb4 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java @@ -0,0 +1,16 @@ +package com.baeldung.opentelemetry; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = ProductApplication.class) +class SpringContextTest { + + @Test + void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/controller/ProductControllerUnitTest.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/controller/ProductControllerUnitTest.java new file mode 100644 index 0000000000..fcb3e23752 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry1/src/test/java/com/baeldung/opentelemetry/controller/ProductControllerUnitTest.java @@ -0,0 +1,92 @@ +package com.baeldung.opentelemetry.controller; + +import com.baeldung.opentelemetry.api.client.PriceClient; +import com.baeldung.opentelemetry.exception.ProductNotFoundException; +import com.baeldung.opentelemetry.model.Price; +import com.baeldung.opentelemetry.model.Product; +import com.baeldung.opentelemetry.repository.ProductRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; + +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.client.HttpServerErrorException; + + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@ExtendWith(SpringExtension.class) +@WebMvcTest(ProductController.class) +class ProductControllerUnitTest { + + @MockBean + private PriceClient priceCLient; + + @MockBean + private ProductRepository productRepository; + + @Autowired + private MockMvc mockMvc; + + + @Test + void givenProductandPriceDataAvailable_whenGetProductCalled_thenReturnProductDetails() throws Exception { + long productId = 100000L; + + Price price = createPrice(productId); + Product product = createProduct(productId); + product.setPrice(price); + + when(productRepository.getProduct(productId)).thenReturn(product); + when(priceCLient.getPrice(productId)).thenReturn(price); + + mockMvc.perform(get("/product/" + productId)) + .andExpect(status().is(HttpStatus.OK.value())); + } + + @Test + void givenProductNotFound_whenGetProductCalled_thenReturnInternalServerError() throws Exception { + long productId = 100000L; + Price price = createPrice(productId); + + when(productRepository.getProduct(productId)).thenThrow(ProductNotFoundException.class); + when(priceCLient.getPrice(productId)).thenReturn(price); + + mockMvc.perform(get("/product/" + productId)) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + } + + @Test + void givenPriceServiceNotAvailable_whenGetProductCalled_thenReturnInternalServerError() throws Exception { + long productId = 100000L; + Product product = createProduct(productId); + + when(productRepository.getProduct(productId)).thenReturn(product); + when(priceCLient.getPrice(productId)).thenThrow(HttpServerErrorException.ServiceUnavailable.class); + + mockMvc.perform(get("/product/" + productId)) + .andExpect(status().is(HttpStatus.INTERNAL_SERVER_ERROR.value())); + } + + private static Product createProduct(long productId) { + Product product = new Product(); + product.setId(productId); + product.setName("test"); + return product; + } + + private static Price createPrice(long productId) { + Price price = new Price(); + price.setProductId(productId); + price.setPriceAmount(12.00); + price.setDiscount(2.5); + return price; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/Dockerfile b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/Dockerfile new file mode 100644 index 0000000000..fb0e3b3263 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/Dockerfile @@ -0,0 +1,7 @@ +FROM adoptopenjdk/openjdk11:alpine + +COPY target/spring-cloud-open-telemetry2-1.0.0-SNAPSHOT.jar spring-cloud-open-telemetry.jar + +EXPOSE 8081 + +ENTRYPOINT ["java","-jar","/spring-cloud-open-telemetry.jar"] \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml new file mode 100644 index 0000000000..2d7ac8204e --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + spring-cloud-open-telemetry2 + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT + spring-cloud-open-telemetry2 + jar + + + com.baeldung.spring.cloud + spring-cloud-open-telemetry + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot-dependencies.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${release.train.version} + pom + import + + + org.springframework.cloud + spring-cloud-sleuth-otel-dependencies + ${spring-cloud-sleuth-otel.version} + import + pom + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-brave + + + + + org.springframework.cloud + spring-cloud-sleuth-otel-autoconfigure + + + io.opentelemetry + opentelemetry-exporter-otlp-trace + + + io.grpc + grpc-okhttp + ${grpc-okhttp.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + + spring-milestones + https://repo.spring.io/milestone + + + + + spring-milestones + https://repo.spring.io/milestone + + + + + 2.5.7 + 2020.0.4 + 1.0.0-M12 + 1.42.1 + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/PriceApplication.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/PriceApplication.java new file mode 100644 index 0000000000..75db68c624 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/PriceApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.opentelemetry; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PriceApplication { + + public static void main(String[] args) { + SpringApplication.run(PriceApplication.class, args); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/controller/PriceController.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/controller/PriceController.java new file mode 100644 index 0000000000..6142d4da10 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/controller/PriceController.java @@ -0,0 +1,29 @@ +package com.baeldung.opentelemetry.controller; + +import com.baeldung.opentelemetry.model.Price; +import com.baeldung.opentelemetry.repository.PriceRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PriceController { + + private static final Logger LOGGER = LoggerFactory.getLogger(PriceController.class); + + private final PriceRepository priceRepository; + + @Autowired + public PriceController(PriceRepository priceRepository) { + this.priceRepository = priceRepository; + } + + @GetMapping(path = "/price/{id}") + public Price getPrice(@PathVariable("id") long productId) { + LOGGER.info("Getting Price details for Product Id {}", productId); + return priceRepository.getPrice(productId); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceNotFoundException.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceNotFoundException.java new file mode 100644 index 0000000000..6e1c5e0b5e --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/PriceNotFoundException.java @@ -0,0 +1,7 @@ +package com.baeldung.opentelemetry.exception; + +public class PriceNotFoundException extends RuntimeException { + public PriceNotFoundException(String priceNotFound) { + super(priceNotFound); + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java new file mode 100644 index 0000000000..fe7789ecf5 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/exception/ProductControllerAdvice.java @@ -0,0 +1,16 @@ +package com.baeldung.opentelemetry.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class ProductControllerAdvice { + + @ExceptionHandler(PriceNotFoundException.class) + public ResponseEntity handlePriceNotFoundException(PriceNotFoundException exception) { + return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); + } + +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/model/Price.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/model/Price.java new file mode 100644 index 0000000000..0e30c4e25b --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/model/Price.java @@ -0,0 +1,27 @@ +package com.baeldung.opentelemetry.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Price { + + @JsonProperty("productId") + private long productId; + + @JsonProperty("price_amount") + private double priceAmount; + + @JsonProperty("discount") + private double discount; + + public void setDiscount(double discount) { + this.discount = discount; + } + + public void setProductId(long productId) { + this.productId = productId; + } + + public void setPriceAmount(double priceAmount) { + this.priceAmount = priceAmount; + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/repository/PriceRepository.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/repository/PriceRepository.java new file mode 100644 index 0000000000..63af7548d9 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/java/com/baeldung/opentelemetry/repository/PriceRepository.java @@ -0,0 +1,53 @@ +package com.baeldung.opentelemetry.repository; + +import com.baeldung.opentelemetry.model.Price; +import com.baeldung.opentelemetry.exception.PriceNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; + +@Component +public class PriceRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(PriceRepository.class); + + private final Map priceMap = new HashMap<>(); + + public Price getPrice(Long productId){ + LOGGER.info("Getting Price from Price Repo With Product Id {}", productId); + + if(!priceMap.containsKey(productId)){ + LOGGER.error("Price Not Found for Product Id {}", productId); + throw new PriceNotFoundException("Product Not Found"); + } + + return priceMap.get(productId); + } + + @PostConstruct + private void setupRepo(){ + Price price1 = getPrice(100001L, 12.5, 2.5); + priceMap.put(100001L, price1); + + Price price2 = getPrice(100002L, 10.5, 2.1); + priceMap.put(100002L, price2); + + Price price3 = getPrice(100003L, 18.5, 2.0); + priceMap.put(100003L, price3); + + Price price4 = getPrice(100004L, 18.5, 2.0); + priceMap.put(100004L, price4); + } + + private static Price getPrice(long productId, double priceAmount, double discount) { + Price price = new Price(); + price.setProductId(productId); + price.setPriceAmount(priceAmount); + price.setDiscount(discount); + return price; + } +} \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/resources/application.properties new file mode 100644 index 0000000000..03b80ae271 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port= 8081 +spring.application.name=price-service +spring.sleuth.otel.config.trace-id-ratio-based=1.0 +spring.sleuth.otel.exporter.otlp.endpoint=http://collector:4317 diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java new file mode 100644 index 0000000000..524cc30567 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/SpringContextTest.java @@ -0,0 +1,16 @@ +package com.baeldung.opentelemetry; + +import org.junit.jupiter.api.Test; + +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PriceApplication.class) +class SpringContextTest { + + @Test + void whenSpringContextIsBootstrapped_thenNoException() { + } +} diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/controller/PriceControllerUnitTest.java b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/controller/PriceControllerUnitTest.java new file mode 100644 index 0000000000..7fd87c99d1 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/src/test/java/com/baeldung/opentelemetry/controller/PriceControllerUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.opentelemetry.controller; + + +import com.baeldung.opentelemetry.exception.PriceNotFoundException; +import com.baeldung.opentelemetry.model.Price; +import com.baeldung.opentelemetry.repository.PriceRepository; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@ExtendWith(SpringExtension.class) +@WebMvcTest(PriceController.class) +class PriceControllerUnitTest { + + @MockBean + private PriceRepository priceRepository; + + @Autowired + private MockMvc mockMvc; + + @Test + void givenProductandPriceAvailable_whenGetProductCalled_thenReturnProductDetails() throws Exception { + long productId = 100000L; + Price price = new Price(); + price.setProductId(productId); + price.setPriceAmount(12.00); + price.setDiscount(2.5); + + when(priceRepository.getPrice(productId)).thenReturn(price); + + mockMvc.perform(get("/price/" + productId)) + .andExpect(status().is(HttpStatus.OK.value())); + } + + + @Test + void givenProductNotFound_whenGetProductCalled_thenReturnInternalServerError() throws Exception { + long productId = 100000L; + + when(priceRepository.getPrice(productId)).thenThrow(PriceNotFoundException.class); + + mockMvc.perform(get("/price/" + productId)) + .andExpect(status().is(HttpStatus.NOT_FOUND.value())); + } + +} diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/pom.xml b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/pom.xml index 397f06399f..9d0d91b2c0 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/pom.xml +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/pom.xml @@ -36,7 +36,7 @@ com.amazonaws amazon-kinesis-client - 1.11.2 + 1.14.9 org.springframework.cloud @@ -46,9 +46,9 @@ - 1.11.632 - 2.0.2.RELEASE - 2.2.1.RELEASE + 1.12.380 + 2.2.0 + 4.0.0 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ConsumerBinder.java b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ConsumerBinder.java index 38ad634086..1fedec83ad 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ConsumerBinder.java +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ConsumerBinder.java @@ -1,16 +1,16 @@ package com.baeldung.binder; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.annotation.StreamListener; -import org.springframework.cloud.stream.messaging.Sink; -import org.springframework.stereotype.Component; +import java.util.function.Consumer; -@Component -@EnableBinding(Sink.class) +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration public class ConsumerBinder { - - @StreamListener(Sink.INPUT) - public void consume(String ip) { - System.out.println(ip); - } + @Bean + Consumer input() { + return str -> { + System.out.println(str); + }; + } } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/KinesisBinderApplication.java b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/KinesisBinderApplication.java index e4f6916ed9..1cf31f9928 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/KinesisBinderApplication.java +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/KinesisBinderApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class KinesisBinderApplication { - public static void main(String[] args) { - SpringApplication.run(KinesisBinderApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(KinesisBinderApplication.class, args); + } } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ProducerBinder.java b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ProducerBinder.java index 468f2886de..1486459a1e 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ProducerBinder.java +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/binder/ProducerBinder.java @@ -1,24 +1,20 @@ package com.baeldung.binder; +import java.util.function.Supplier; import java.util.stream.IntStream; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.messaging.Source; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.messaging.support.MessageBuilder; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -@Component -@EnableBinding(Source.class) -public class ProducerBinder { +@Configuration +class ProducerBinder { - @Autowired - private Source source; - - @Scheduled(fixedDelay = 3000L) - private void produce() { - IntStream.range(1, 200).mapToObj(ipSuffix -> "192.168.0." + ipSuffix) - .forEach(entry -> source.output().send(MessageBuilder.withPayload(entry).build())); + @Bean + public Supplier output() { + return () -> IntStream.range(1, 200) + .mapToObj(ipSuffix -> "192.168.0." + ipSuffix) + .map(entry -> MessageBuilder.withPayload(entry) + .build()); } } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKCLApplication.java b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKCLApplication.java index 01c5af596d..1ab205d3aa 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKCLApplication.java +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKCLApplication.java @@ -1,11 +1,14 @@ package com.baeldung.kclkpl; +import static com.amazonaws.services.kinesis.clientlibrary.lib.worker.KinesisClientLibConfiguration.*; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; @@ -17,32 +20,30 @@ public class KinesisKCLApplication implements ApplicationRunner { @Value("${aws.access.key}") private String accessKey; - + @Value("${aws.secret.key}") private String secretKey; - + @Value("${ips.stream}") private String IPS_STREAM; - + public static void main(String[] args) { SpringApplication.run(KinesisKCLApplication.class, args); } - @Override - public void run(ApplicationArguments args) throws Exception { - BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); - KinesisClientLibConfiguration consumerConfig = new KinesisClientLibConfiguration( - "KinesisKCLConsumer", - IPS_STREAM, - new AWSStaticCredentialsProvider(awsCredentials), - "KinesisKCLConsumer") - .withRegionName(Regions.EU_CENTRAL_1.getName()); + @Override + public void run(ApplicationArguments args) throws Exception { + BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); - new Worker.Builder() - .recordProcessorFactory(new IpProcessorFactory()) - .config(consumerConfig) - .build() - .run(); - } - + KinesisClientLibConfiguration consumerConfig = new KinesisClientLibConfiguration("KinesisKCLConsumer", IPS_STREAM, "", "", DEFAULT_INITIAL_POSITION_IN_STREAM, new AWSStaticCredentialsProvider(awsCredentials), + new AWSStaticCredentialsProvider(awsCredentials), new AWSStaticCredentialsProvider(awsCredentials), DEFAULT_FAILOVER_TIME_MILLIS, "KinesisKCLConsumer", DEFAULT_MAX_RECORDS, DEFAULT_IDLETIME_BETWEEN_READS_MILLIS, + DEFAULT_DONT_CALL_PROCESS_RECORDS_FOR_EMPTY_RECORD_LIST, DEFAULT_PARENT_SHARD_POLL_INTERVAL_MILLIS, DEFAULT_SHARD_SYNC_INTERVAL_MILLIS, DEFAULT_CLEANUP_LEASES_UPON_SHARDS_COMPLETION, new ClientConfiguration(), new ClientConfiguration(), + new ClientConfiguration(), DEFAULT_TASK_BACKOFF_TIME_MILLIS, DEFAULT_METRICS_BUFFER_TIME_MILLIS, DEFAULT_METRICS_MAX_QUEUE_SIZE, DEFAULT_VALIDATE_SEQUENCE_NUMBER_BEFORE_CHECKPOINTING, Regions.EU_CENTRAL_1.getName(), DEFAULT_SHUTDOWN_GRACE_MILLIS, + DEFAULT_DDB_BILLING_MODE, null, 0, 0, 0); + + new Worker.Builder().recordProcessorFactory(new IpProcessorFactory()) + .config(consumerConfig) + .build() + .run(); + } } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKPLApplication.java b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKPLApplication.java index 4ff7cf8087..1b2d9bed3f 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKPLApplication.java +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/java/com/baeldung/kclkpl/KinesisKPLApplication.java @@ -16,23 +16,22 @@ public class KinesisKPLApplication { @Value("${aws.access.key}") private String accessKey; - + @Value("${aws.secret.key}") private String secretKey; - + public static void main(String[] args) { SpringApplication.run(KinesisKPLApplication.class, args); } @Bean public KinesisProducer kinesisProducer() { - BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); - KinesisProducerConfiguration producerConfig = new KinesisProducerConfiguration() - .setCredentialsProvider(new AWSStaticCredentialsProvider(awsCredentials)) - .setVerifyCertificate(false) - .setRegion(Regions.EU_CENTRAL_1.getName()); + BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); + KinesisProducerConfiguration producerConfig = new KinesisProducerConfiguration().setCredentialsProvider(new AWSStaticCredentialsProvider(awsCredentials)) + .setVerifyCertificate(false) + .setRegion(Regions.EU_CENTRAL_1.getName()); - return new KinesisProducer(producerConfig); + return new KinesisProducer(producerConfig); } - + } \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/resources/application.properties index 777abef1cc..fddea95d45 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/resources/application.properties +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/main/resources/application.properties @@ -12,9 +12,11 @@ cloud.aws.credentials.secret-key=my-aws-secret-key cloud.aws.region.static=eu-central-1 cloud.aws.stack.auto=false -spring.cloud.stream.bindings.input.destination=live-ips -spring.cloud.stream.bindings.input.group=live-ips-group -spring.cloud.stream.bindings.input.content-type=text/plain +spring.cloud.stream.bindings.input-in-0.destination=live-ips +spring.cloud.stream.bindings.input-in-0.group=live-ips-group +spring.cloud.stream.bindings.input-in-0.content-type=text/plain +spring.cloud.stream.function.definition = input -spring.cloud.stream.bindings.output.destination=myStream -spring.cloud.stream.bindings.output.content-type=text/plain \ No newline at end of file +spring.cloud.stream.bindings.output-out-0.destination=myStream +spring.cloud.stream.bindings.output-out-0.content-type=text/plain +spring.cloud.stream.poller.fixed-delay = 3000 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/test/resources/application.properties b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/test/resources/application.properties index 777abef1cc..fddea95d45 100644 --- a/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/test/resources/application.properties +++ b/spring-cloud-modules/spring-cloud-stream/spring-cloud-stream-kinesis/src/test/resources/application.properties @@ -12,9 +12,11 @@ cloud.aws.credentials.secret-key=my-aws-secret-key cloud.aws.region.static=eu-central-1 cloud.aws.stack.auto=false -spring.cloud.stream.bindings.input.destination=live-ips -spring.cloud.stream.bindings.input.group=live-ips-group -spring.cloud.stream.bindings.input.content-type=text/plain +spring.cloud.stream.bindings.input-in-0.destination=live-ips +spring.cloud.stream.bindings.input-in-0.group=live-ips-group +spring.cloud.stream.bindings.input-in-0.content-type=text/plain +spring.cloud.stream.function.definition = input -spring.cloud.stream.bindings.output.destination=myStream -spring.cloud.stream.bindings.output.content-type=text/plain \ No newline at end of file +spring.cloud.stream.bindings.output-out-0.destination=myStream +spring.cloud.stream.bindings.output-out-0.content-type=text/plain +spring.cloud.stream.poller.fixed-delay = 3000 \ No newline at end of file diff --git a/spring-core-6/README.md b/spring-core-6/README.md index 1cb5935cc5..90e2dfed01 100644 --- a/spring-core-6/README.md +++ b/spring-core-6/README.md @@ -3,3 +3,4 @@ - [Instantiating Multiple Beans of the Same Class with Spring Annotations](https://www.baeldung.com/spring-same-class-multiple-beans) - [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) - [Reinitialize Singleton Bean in Spring Context](https://www.baeldung.com/spring-reinitialize-singleton-bean) +- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) diff --git a/spring-di/pom.xml b/spring-di/pom.xml index af0601deb6..9d2a260a06 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -111,6 +111,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + org.apache.maven.plugins maven-war-plugin diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index 0621009bdd..6d573b6813 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -144,6 +144,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + org.apache.maven.plugins maven-war-plugin diff --git a/spring-kafka-2/pom.xml b/spring-kafka-2/pom.xml index d51c2e300f..76a82f6000 100644 --- a/spring-kafka-2/pom.xml +++ b/spring-kafka-2/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-kafka - spring-kafka + spring-kafka-2 + spring-kafka-2 Intro to Kafka with Spring diff --git a/spring-katharsis/pom.xml b/spring-katharsis/pom.xml index b836a42bca..2fcc87e2dd 100644 --- a/spring-katharsis/pom.xml +++ b/spring-katharsis/pom.xml @@ -55,6 +55,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + org.codehaus.cargo cargo-maven2-plugin diff --git a/spring-mobile/pom.xml b/spring-mobile/pom.xml index 7f715c8735..bac1d2cdc9 100644 --- a/spring-mobile/pom.xml +++ b/spring-mobile/pom.xml @@ -32,6 +32,15 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + 1.1.5.RELEASE diff --git a/spring-native/pom.xml b/spring-native/pom.xml index 6940ee462b..55f17c833f 100644 --- a/spring-native/pom.xml +++ b/spring-native/pom.xml @@ -72,9 +72,6 @@ paketobuildpacks/builder:tiny 2.7.1 0.12.1 - 1.8 - 1.8 - 1.8 2.17.1 diff --git a/spring-reactive-modules/README.md b/spring-reactive-modules/README.md index 3522efec17..57c3eebbff 100644 --- a/spring-reactive-modules/README.md +++ b/spring-reactive-modules/README.md @@ -1,4 +1,3 @@ ## Spring Reactive This module contains modules about Spring Reactive -- [How to Resolve Spring Webflux DataBufferLimitException](https://www.baeldung.com/spring-webflux-databufferlimitexception) diff --git a/testing-modules/instancio/README.md b/testing-modules/instancio/README.md index 881477f036..35166ee017 100644 --- a/testing-modules/instancio/README.md +++ b/testing-modules/instancio/README.md @@ -1 +1,2 @@ -### Relevant articles +## Relevant articles +- [Generate Unit Test Data in Java Using Instancio](https://www.baeldung.com/java-test-data-instancio) diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index f3e8d3f9a3..bfc490b03e 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 junit-5-advanced 1.0-SNAPSHOT @@ -27,6 +27,12 @@ ${jmockit.version} test + + org.assertj + assertj-core + ${assertj.version} + test + @@ -46,6 +52,7 @@ 1.49 + 3.24.2 \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/multiassertions/MultiAssertionsInOneUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/multiassertions/MultiAssertionsInOneUnitTest.java new file mode 100644 index 0000000000..6fec9015cf --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/multiassertions/MultiAssertionsInOneUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.multiassertions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.from; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +public class MultiAssertionsInOneUnitTest { + private static final Product EXPECTED = new Product(42L, "LG Monitor", "32 inches, 4K Resolution, Ideal for programmer", true, new BigDecimal("429.99"), 77); + private static final Product TO_BE_TESTED = new Product(-1L, "LG Monitor", "dummy value: whatever", true, new BigDecimal("429.99"), 77); + + @Test + void givenAProductObject_whenUsingAssertAll_thenAssertMultiPropertiesInOneCall() { + //@formatter:off + assertAll("Verify Product properties", + () -> assertEquals(EXPECTED.getName(), TO_BE_TESTED.getName()), + () -> assertEquals(EXPECTED.isOnSale(), TO_BE_TESTED.isOnSale()), + () -> assertEquals(EXPECTED.getStockQuantity(), TO_BE_TESTED.getStockQuantity()), + () -> assertEquals(EXPECTED.getPrice(), TO_BE_TESTED.getPrice())); + //@formatter:on + } + + @Test + void givenAProductObject_whenUsingAssertJExtracting_thenAssertMultiPropertiesInOneCall() { + //@formatter:off + assertThat(TO_BE_TESTED) + .extracting("name", "onSale", "stockQuantity", "price") + .containsExactly(EXPECTED.getName(), EXPECTED.isOnSale(), EXPECTED.getStockQuantity(), EXPECTED.getPrice()); + + assertThat(TO_BE_TESTED) + .extracting(Product::getName, Product::isOnSale, Product::getStockQuantity,Product::getPrice) + .containsExactly(EXPECTED.getName(), EXPECTED.isOnSale(), EXPECTED.getStockQuantity(), EXPECTED.getPrice()); + //@formatter:on + } + + @Test + void givenAProductObject_whenUsingAssertJReturns_thenAssertMultiPropertiesInOneCall() { + //@formatter:off + assertThat(TO_BE_TESTED) + .returns(EXPECTED.getName(),from(Product::getName)) + .returns(EXPECTED.isOnSale(), from(Product::isOnSale)) + .returns(EXPECTED.getStockQuantity(), from(Product::getStockQuantity)) + .returns(EXPECTED.getPrice(), from(Product::getPrice)) + + .doesNotReturn(EXPECTED.getId(), from(Product::getId)) + .doesNotReturn(EXPECTED.getDescription(), from(Product::getDescription)); + //@formatter:on + } +} + +class Product { + private Long id; + private String name; + private String description; + private boolean onSale; + private BigDecimal price; + private int stockQuantity; + + public Product(Long id, String name, String description, boolean onSale, BigDecimal price, int stockQuantity) { + this.id = id; + this.name = name; + this.description = description; + this.onSale = onSale; + this.price = price; + this.stockQuantity = stockQuantity; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public boolean isOnSale() { + return onSale; + } + + public BigDecimal getPrice() { + return price; + } + + public int getStockQuantity() { + return stockQuantity; + } +} \ No newline at end of file diff --git a/testing-modules/testing-libraries/pom.xml b/testing-modules/testing-libraries/pom.xml index f9443fa792..b7c9b8c0bd 100644 --- a/testing-modules/testing-libraries/pom.xml +++ b/testing-modules/testing-libraries/pom.xml @@ -90,6 +90,11 @@ + + org.codehaus.mojo + findbugs-maven-plugin + ${findbugs-plugin.version} + @@ -111,8 +116,9 @@ 4.8.0 3.0.0 1.19.0 - 1.0.0 + 1.2.1 2.4.3 + 3.0.5 \ No newline at end of file diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml index bcd51bea85..15ef45be63 100644 --- a/testing-modules/zerocode/pom.xml +++ b/testing-modules/zerocode/pom.xml @@ -37,6 +37,7 @@ org.springframework.boot spring-boot-maven-plugin + ${spring.boot.version} it diff --git a/vaadin/pom.xml b/vaadin/pom.xml index 6976ff2a6a..82963f9e7f 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -76,6 +76,10 @@ + + org.apache.maven.plugins + maven-compiler-plugin + org.apache.maven.plugins maven-war-plugin @@ -184,8 +188,6 @@ 8.8.5 8.8.5 9.3.9.v20160517 - 1.8 - 1.8 local mytheme 3.0.0