From 2e41874a5c9aca865e0cb7cf00fb84b748527833 Mon Sep 17 00:00:00 2001 From: 3hsan <56245694+ehsansasanian@users.noreply.github.com> Date: Fri, 5 May 2023 10:47:57 +0200 Subject: [PATCH 01/20] JAVA-16946: comment spring-jooq module from persistence-modules. (#13951) --- persistence-modules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 46ac9b50f1..ad757d9073 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -107,7 +107,7 @@ spring-jdbc - spring-jooq + spring-mybatis spring-persistence-simple From 7e404b3dfbe48f7246037b7230247485d264444b Mon Sep 17 00:00:00 2001 From: Kasra Madadipouya Date: Fri, 5 May 2023 11:58:11 +0200 Subject: [PATCH 02/20] JAVA-20555 use Java Base64 instead of deprecated Spring Base64Utils (#13941) --- .../security/oauth2/UaaTokenEndpointClient.java | 4 ++-- .../web/ManualOauthRequestController.java | 6 ++++-- .../authresolver/AuthResolverIntegrationTest.java | 11 ++++++----- .../authresolver/AuthResolverIntegrationTest.java | 11 ++++++----- .../petstore/client/invoker/auth/HttpBasicAuth.java | 5 +++-- .../petstore/client/invoker/auth/HttpBasicAuth.java | 6 +++--- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java b/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java index 01c8febdb2..296e8cf67a 100644 --- a/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java +++ b/jhipster-modules/jhipster-uaa/gateway/src/main/java/com/baeldung/jhipster/gateway/security/oauth2/UaaTokenEndpointClient.java @@ -5,11 +5,11 @@ import io.github.jhipster.config.JHipsterProperties; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.nio.charset.StandardCharsets; +import java.util.Base64; /** * Client talking to UAA's token endpoint to do different OAuth2 grants. @@ -34,7 +34,7 @@ public class UaaTokenEndpointClient extends OAuth2TokenEndpointClientAdapter imp String clientId = getClientId(); String clientSecret = getClientSecret(); String authorization = clientId + ":" + clientSecret; - return "Basic " + Base64Utils.encodeToString(authorization.getBytes(StandardCharsets.UTF_8)); + return "Basic " + Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8)); } } diff --git a/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java b/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java index d54d811032..c449a5991e 100644 --- a/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java +++ b/spring-reactive-modules/spring-5-reactive-oauth/src/main/java/com/baeldung/webclient/manualrequest/web/ManualOauthRequestController.java @@ -1,12 +1,13 @@ package com.baeldung.webclient.manualrequest.web; +import java.util.Base64; + 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.HttpHeaders; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.BodyInserters; @@ -41,7 +42,8 @@ public class ManualOauthRequestController { logger.info("Creating web client..."); Mono resource = client.post() .uri(tokenUri) - .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((clientId + ":" + clientSecret).getBytes())) + .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString((clientId + ":" + clientSecret).getBytes())) .body(BodyInserters.fromFormData(OAuth2ParameterNames.GRANT_TYPE, GrantType.CLIENT_CREDENTIALS.getValue())) .retrieve() .bodyToMono(JsonNode.class) diff --git a/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java b/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java index 691243b3ea..9e0855d086 100644 --- a/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java +++ b/spring-reactive-modules/spring-5-reactive-security/src/test/java/com/baeldung/reactive/authresolver/AuthResolverIntegrationTest.java @@ -1,5 +1,7 @@ package com.baeldung.reactive.authresolver; +import java.util.Base64; + import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.util.Base64Utils; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class) @@ -22,7 +23,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/customer/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) .exchange() .expectStatus() .isOk(); @@ -33,7 +34,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/customer/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) .exchange() .expectStatus() .isUnauthorized(); @@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/employee/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) .exchange() .expectStatus() .isOk(); @@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest { testClient .get() .uri("/employee/welcome") - .header("Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + .header("Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) .exchange() .expectStatus() .isUnauthorized(); diff --git a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java index c87f8c1a3a..a0bc793a11 100644 --- a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java +++ b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/authresolver/AuthResolverIntegrationTest.java @@ -11,13 +11,14 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.util.Base64Utils; import org.springframework.web.context.WebApplicationContext; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.Base64; + @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = AuthResolverApplication.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -44,7 +45,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/customer/welcome") .header( - "Authorization", String.format("Basic %s", Base64Utils.encodeToString("customer1:pass1".getBytes())) + "Authorization", String.format("Basic %s", Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) ) ) .andExpect(status().is2xxSuccessful()); @@ -55,7 +56,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/customer/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) ) .andExpect(status().isUnauthorized()); } @@ -65,7 +66,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/employee/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("employee1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("employee1:pass1".getBytes())) ) .andExpect(status().is2xxSuccessful()); } @@ -75,7 +76,7 @@ public class AuthResolverIntegrationTest { this.mockMvc .perform(get("/employee/welcome") .header( - "Authorization", "Basic " + Base64Utils.encodeToString("customer1:pass1".getBytes())) + "Authorization", "Basic " + Base64.getEncoder().encodeToString("customer1:pass1".getBytes())) ) .andExpect(status().isUnauthorized()); } diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java b/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java index 4c1dad6e7c..fea7b0532b 100644 --- a/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java +++ b/spring-swagger-codegen/spring-openapi-generator-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java @@ -1,9 +1,9 @@ package com.baeldung.petstore.client.invoker.auth; import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.springframework.http.HttpHeaders; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2020-03-15T06:14:01.568992-05:00[America/Chicago]") @@ -33,6 +33,7 @@ public class HttpBasicAuth implements Authentication { return; } String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); - headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8))); + headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString(str.getBytes(StandardCharsets.UTF_8))); } } diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java index 16c88a4bc6..23c1dbc4c2 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/java/com/baeldung/petstore/client/invoker/auth/HttpBasicAuth.java @@ -1,10 +1,9 @@ package com.baeldung.petstore.client.invoker.auth; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import java.util.Base64; import org.springframework.http.HttpHeaders; -import org.springframework.util.Base64Utils; import org.springframework.util.MultiValueMap; @javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaClientCodegen", date = "2017-08-29T12:04:37.072+02:00") @@ -34,6 +33,7 @@ public class HttpBasicAuth implements Authentication { return; } String str = (username == null ? "" : username) + ":" + (password == null ? "" : password); - headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString(str.getBytes(StandardCharsets.UTF_8))); + headerParams.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder() + .encodeToString(str.getBytes(StandardCharsets.UTF_8))); } } From f37f777d9373e3f81ded165bbf5d8767282d22da Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 21:41:29 +0800 Subject: [PATCH 03/20] Update README.md [skip ci] --- core-java-modules/core-java-perf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-perf/README.md b/core-java-modules/core-java-perf/README.md index 2f0331f281..c400f1d196 100644 --- a/core-java-modules/core-java-perf/README.md +++ b/core-java-modules/core-java-perf/README.md @@ -14,3 +14,4 @@ This module contains articles about performance of Java applications - [JMX Ports](https://www.baeldung.com/jmx-ports) - [Calling JMX MBean Method From a Shell Script](https://www.baeldung.com/jmx-mbean-shell-access) - [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging) +- [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks) From ab1964f166b176025a1898c2c7aee4988fdcb05e Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 21:48:48 +0800 Subject: [PATCH 04/20] Update README.md [skip ci] --- spring-boot-modules/spring-boot-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-3/README.md b/spring-boot-modules/spring-boot-3/README.md index be95ce2830..e99eb79127 100644 --- a/spring-boot-modules/spring-boot-3/README.md +++ b/spring-boot-modules/spring-boot-3/README.md @@ -6,3 +6,4 @@ - [Migrate Application From Spring Boot 2 to Spring Boot 3](https://www.baeldung.com/spring-boot-3-migration) - [Using Java Records with JPA](https://www.baeldung.com/spring-jpa-java-records) - [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) +- [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads) From 69e5f59d4b6f60a6ab26ca784728545612988834 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:24:09 +0800 Subject: [PATCH 05/20] Update README.md [skip ci] --- core-java-modules/core-java-string-operations-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-5/README.md b/core-java-modules/core-java-string-operations-5/README.md index 94fb7e855e..bbd63d1138 100644 --- a/core-java-modules/core-java-string-operations-5/README.md +++ b/core-java-modules/core-java-string-operations-5/README.md @@ -8,3 +8,4 @@ - [Convert String to String Array](https://www.baeldung.com/java-convert-string-to-string-array) - [String Interpolation in Java](https://www.baeldung.com/java-string-interpolation) - [Guide to Splitting a String by Whitespace in Java](https://www.baeldung.com/java-splitting-a-string-by-whitespace) +- [Check if the First Letter of a String Is a Number](https://www.baeldung.com/java-check-if-string-starts-with-number) From cc061011c75b130132e268307c114aa2836866a4 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:28:38 +0800 Subject: [PATCH 06/20] Update README.md [skip ci] --- core-java-modules/core-java-char/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-char/README.md b/core-java-modules/core-java-char/README.md index 5f33aa6914..e4af3121c5 100644 --- a/core-java-modules/core-java-char/README.md +++ b/core-java-modules/core-java-char/README.md @@ -4,3 +4,4 @@ This module contains articles about Java Character Class ### Relevant Articles: - [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic) +- [Difference Between Java’s “char” and “String”](https://www.baeldung.com/java-char-vs-string) From 7720c03dbf9c5ead745a2ec7ca044993c7a5ed10 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:37:21 +0800 Subject: [PATCH 07/20] Update README.md [skip ci] --- spring-boot-modules/spring-boot-libraries-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-libraries-2/README.md b/spring-boot-modules/spring-boot-libraries-2/README.md index fbba6ad62c..5c6b93469d 100644 --- a/spring-boot-modules/spring-boot-libraries-2/README.md +++ b/spring-boot-modules/spring-boot-libraries-2/README.md @@ -10,4 +10,5 @@ This module contains articles about various Spring Boot libraries - [Scanning Java Annotations At Runtime](https://www.baeldung.com/java-scan-annotations-runtime) - [Guide to Resilience4j With Spring Boot](https://www.baeldung.com/spring-boot-resilience4j) - [Using OpenAI ChatGPT APIs in Spring Boot](https://www.baeldung.com/spring-boot-chatgpt-api-openai) +- [Introduction to Spring Modulith](https://www.baeldung.com/spring-modulith) - More articles: [[prev -->]](/spring-boot-modules/spring-boot-libraries) From 93348fff6060a4d25fc1db6e417eb7163fd25089 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:42:22 +0800 Subject: [PATCH 08/20] Update README.md [skip ci] --- persistence-modules/hibernate-mapping-2/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/persistence-modules/hibernate-mapping-2/README.md b/persistence-modules/hibernate-mapping-2/README.md index 7a811e17cf..4fba6691cf 100644 --- a/persistence-modules/hibernate-mapping-2/README.md +++ b/persistence-modules/hibernate-mapping-2/README.md @@ -4,4 +4,5 @@ This module contains articles about Hibernate Mappings. ### Relevant articles -- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) \ No newline at end of file +- [Hibernate Many to Many Annotation Tutorial](https://www.baeldung.com/hibernate-many-to-many) +- [Boolean Converters in Hibernate 6](https://www.baeldung.com/java-hibernate-6-boolean-converters) From e47d956d5e641087a8e87abd66e32edfd1f28427 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:48:25 +0800 Subject: [PATCH 09/20] Update README.md [skip ci] --- testing-modules/selenium-junit-testng/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/testing-modules/selenium-junit-testng/README.md b/testing-modules/selenium-junit-testng/README.md index 4d9834c6f5..e262fb326f 100644 --- a/testing-modules/selenium-junit-testng/README.md +++ b/testing-modules/selenium-junit-testng/README.md @@ -10,6 +10,7 @@ - [Handle Browser Tabs With Selenium](https://www.baeldung.com/java-handle-browser-tabs-selenium) - [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait) - [StaleElementReferenceException in Selenium](https://www.baeldung.com/selenium-staleelementreferenceexception) +- [Retrieve the Value of an HTML Input in Selenium WebDriver](https://www.baeldung.com/java-selenium-html-input-value) #### Notes: - to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described From 2a750529ff6fbfbdb2f395ad839b7dca87f75b0a Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:51:11 +0800 Subject: [PATCH 10/20] Update README.md [skip ci] --- algorithms-modules/algorithms-miscellaneous-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index 53c218a40c..ab07d655f9 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -2,4 +2,5 @@ - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) - [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array) +- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) From 73ab237379e701a4ccc5be90d9518d21fa7204e6 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 5 May 2023 23:58:06 +0800 Subject: [PATCH 11/20] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-repo-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-repo-3/README.md b/persistence-modules/spring-data-jpa-repo-3/README.md index dc33900736..d3782eb1e6 100644 --- a/persistence-modules/spring-data-jpa-repo-3/README.md +++ b/persistence-modules/spring-data-jpa-repo-3/README.md @@ -4,4 +4,5 @@ This module contains articles about Spring Data JPA. ### Relevant Articles: - [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces) +- [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list) - More articles: [[<-- prev]](../spring-data-jpa-repo-2) From bb7a389e0140162b7fb1048a3f1016d50ebead28 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 6 May 2023 00:09:33 +0800 Subject: [PATCH 12/20] Update README.md [skip ci] --- core-java-modules/core-java-arrays-operations-basic/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-arrays-operations-basic/README.md b/core-java-modules/core-java-arrays-operations-basic/README.md index 2e1268e00c..eed64c0cae 100644 --- a/core-java-modules/core-java-arrays-operations-basic/README.md +++ b/core-java-modules/core-java-arrays-operations-basic/README.md @@ -11,3 +11,4 @@ This module contains articles about Java array fundamentals. They assume no prev - [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element) - [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end) - [Initializing a Boolean Array in Java](https://www.baeldung.com/java-initializing-boolean-array) +- [Find the Index of an Element in a Java Array](https://www.baeldung.com/java-array-find-index) From 35d5f583ac8f41316a274eafd4d932ad3e9b173a Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 6 May 2023 00:15:22 +0800 Subject: [PATCH 13/20] Update README.md [skip ci] --- core-java-modules/core-java-string-operations-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-5/README.md b/core-java-modules/core-java-string-operations-5/README.md index bbd63d1138..70a4f5607e 100644 --- a/core-java-modules/core-java-string-operations-5/README.md +++ b/core-java-modules/core-java-string-operations-5/README.md @@ -9,3 +9,4 @@ - [String Interpolation in Java](https://www.baeldung.com/java-string-interpolation) - [Guide to Splitting a String by Whitespace in Java](https://www.baeldung.com/java-splitting-a-string-by-whitespace) - [Check if the First Letter of a String Is a Number](https://www.baeldung.com/java-check-if-string-starts-with-number) +- [Print “” Quotes Around a String in Java](https://www.baeldung.com/java-string-print-quotes) From 7d26ae4a5ed1f6e10d095df606f99de422effd24 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 6 May 2023 00:19:31 +0800 Subject: [PATCH 14/20] Update README.md [skip ci] --- core-java-modules/core-java-20/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-20/README.md b/core-java-modules/core-java-20/README.md index 7e20469e44..aba4e9e240 100644 --- a/core-java-modules/core-java-20/README.md +++ b/core-java-modules/core-java-20/README.md @@ -1,2 +1,2 @@ ## Relevant Articles -- TBD \ No newline at end of file +- [Scoped Values in Java 20](https://www.baeldung.com/java-20-scoped-values) From 3ab60dc3070a173a0827c2d8cf174bf9e3e4491f Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Fri, 5 May 2023 22:25:50 +0200 Subject: [PATCH 15/20] BAEL-6332: Calling Non-Static Method In Static Method In Java (#13940) --- .../java/com/baeldung/staticmodifier/Car.java | 4 ++++ .../CallNonStaticMethodUnitTest.java | 21 +++++++++++++++++++ .../baeldung/staticmodifier/CarUnitTest.java | 7 +++++++ 3 files changed, 32 insertions(+) create mode 100644 core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java b/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java index 950f008dcd..1158851fbd 100644 --- a/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java +++ b/core-java-modules/core-java-lang-oop-modifiers/src/main/java/com/baeldung/staticmodifier/Car.java @@ -42,6 +42,10 @@ public class Car { this.engine = engine; } + public static String getCarsInformation(Car car) { + return car.getName() + "-" + car.getEngine(); + } + public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; } diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java new file mode 100644 index 0000000000..1171cb2e7a --- /dev/null +++ b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmethod/CallNonStaticMethodUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.staticmethod; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.Test; + +import com.baeldung.staticmodifier.Car; + +public class CallNonStaticMethodUnitTest { + @AfterClass + public static void setUpCarInstance() { + Car.setNumberOfCars(0); + } + @Test + public void whenCallingNonStaticMethodInStaticMethodWithInstanceClass_thenSuccess() { + Car car = new Car("Jaguar", "V8"); + assertEquals("Jaguar-V8", Car.getCarsInformation(car)); + } + +} diff --git a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java index f55955caa8..68bbe8f0a2 100644 --- a/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java +++ b/core-java-modules/core-java-lang-oop-modifiers/src/test/java/com/baeldung/staticmodifier/CarUnitTest.java @@ -2,9 +2,16 @@ package com.baeldung.staticmodifier; import static org.junit.Assert.*; +import org.junit.AfterClass; import org.junit.Test; public class CarUnitTest { + + @AfterClass + public static void setUpCarInstance() { + Car.setNumberOfCars(0); + } + @Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); From dea82bf189c8a34b0f5614f05d34ec789ee490f3 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sat, 6 May 2023 03:11:54 +0200 Subject: [PATCH 16/20] [BAEL-6485_RM-Punctuation] Remove Punctuation (#13946) --- .../RemovePunctuationUnitTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java new file mode 100644 index 0000000000..751ae0f4bc --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/delpunctuation/RemovePunctuationUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.delpunctuation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class RemovePunctuationUnitTest { + private static final String INPUT = "Its 1 W o r d (!@#$%^&*{}[];':\")<>,."; + private static final String EXPECTED = "Its 1 W o r d "; + + private static final String UNICODE_INPUT = "3 March März 三月 březen маршировать (!@#$%^&*{}[];':\")<>,."; + private static final String UNICODE_EXPECTED = "3 March März 三月 březen маршировать "; + + @Test + void whenUsingCharClassRange_thenGetExceptedResult() { + String result = INPUT.replaceAll("[^\\sa-zA-Z0-9]", ""); + assertEquals(EXPECTED, result); + } + + @Test + void whenUsingPunctuationCharClass_thenGetExceptedResult() { + String result = INPUT.replaceAll("\\p{Punct}", ""); + assertEquals(EXPECTED, result); + } + + @Test + void whenInputContainsUnicodeChars_thenGetExceptedResult() { + String result1 = UNICODE_INPUT.replaceAll("[^\\sa-zA-Z0-9]", ""); + assertNotEquals(UNICODE_EXPECTED, result1); + + String actualResult1 = "3 March Mrz bezen "; + assertEquals(actualResult1, result1); + + + String result2 = UNICODE_INPUT.replaceAll("\\p{Punct}", ""); + assertEquals(UNICODE_EXPECTED, result2); + + String result3 = UNICODE_INPUT.replaceAll("[^\\s\\p{L}0-9]", ""); + assertEquals(UNICODE_EXPECTED, result3); + } + +} \ No newline at end of file From 4a9e72664c9a8d94f7eb944b887ee62c36f57b4a Mon Sep 17 00:00:00 2001 From: Avin Buricha Date: Sat, 6 May 2023 08:53:31 +0530 Subject: [PATCH 17/20] BAEL-6410 (#13919) * BAEL-6410 | Article code * Adding consumer code for article --- .../kafka/headers/KafkaMessageHeaders.java | 88 +++++++++++++++ .../headers/KafkaMessageHeadersLiveTest.java | 104 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java create mode 100644 apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java new file mode 100644 index 0000000000..2c8c14bfc5 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/headers/KafkaMessageHeaders.java @@ -0,0 +1,88 @@ +package com.baeldung.kafka.headers; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.Headers; +import org.apache.kafka.common.header.internals.RecordHeader; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KafkaMessageHeaders { + + private static Logger logger = LoggerFactory.getLogger(KafkaMessageHeaders.class); + + private static String TOPIC = "baeldung"; + private static String MESSAGE_KEY = "message"; + private static String MESSAGE_VALUE = "Hello World"; + private static String HEADER_KEY = "website"; + private static String HEADER_VALUE = "baeldung.com"; + + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + public static void main(String[] args) { + setup(); + + publishMessageWithCustomHeaders(); + + consumeMessageWithCustomHeaders(); + } + + private static void consumeMessageWithCustomHeaders() { + consumer.subscribe(Arrays.asList(TOPIC)); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + for (ConsumerRecord record : records) { + logger.info(record.key()); + logger.info(record.value()); + + Headers headers = record.headers(); + for (Header header : headers) { + logger.info(header.key()); + logger.info(new String(header.value())); + } + } + } + + private static void publishMessageWithCustomHeaders() { + List
headers = new ArrayList<>(); + headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes())); + + ProducerRecord record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers); + producer.send(record1); + + ProducerRecord record2 = new ProducerRecord<>(TOPIC, null, System.currentTimeMillis(), MESSAGE_KEY, MESSAGE_VALUE, headers); + producer.send(record2); + } + + private static void setup() { + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1"); + + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + } + +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java new file mode 100644 index 0000000000..42cc572e07 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/headers/KafkaMessageHeadersLiveTest.java @@ -0,0 +1,104 @@ +package com.baeldung.kafka.headers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.Headers; +import org.apache.kafka.common.header.internals.RecordHeader; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +// This live test needs a Docker Daemon running so that a kafka container can be created + +@Testcontainers +public class KafkaMessageHeadersLiveTest { + + private static String TOPIC = "baeldung"; + private static String MESSAGE_KEY = "message"; + private static String MESSAGE_VALUE = "Hello World"; + private static String HEADER_KEY = "website"; + private static String HEADER_VALUE = "baeldung.com"; + + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "ConsumerGroup1"); + + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenAMessageWithCustomHeaders_whenPublishedToKafkaAndConsumed_thenCheckForCustomHeaders() throws ExecutionException, InterruptedException { + List
headers = new ArrayList<>(); + headers.add(new RecordHeader(HEADER_KEY, HEADER_VALUE.getBytes())); + + ProducerRecord record1 = new ProducerRecord<>(TOPIC, null, MESSAGE_KEY, MESSAGE_VALUE, headers); + Future future = producer.send(record1); + + RecordMetadata metadata = future.get(); + + assertNotNull(metadata); + + consumer.subscribe(Arrays.asList(TOPIC)); + + ConsumerRecords records = consumer.poll(Duration.ofMinutes(1)); + for (ConsumerRecord record : records) { + assertEquals(MESSAGE_KEY, record.key()); + assertEquals(MESSAGE_VALUE, record.value()); + + Headers consumedHeaders = record.headers(); + assertNotNull(consumedHeaders); + + for (Header header : consumedHeaders) { + assertEquals(HEADER_KEY, header.key()); + assertEquals(HEADER_VALUE, new String(header.value())); + } + } + } +} From 7123ae8ad7f348ed47c750defbd7c1bd2de1e98d Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Sat, 6 May 2023 04:59:46 -0300 Subject: [PATCH 18/20] BAEL-6046 MongoDB - Field Level Encryption (#13859) --- .../spring-boot-persistence-mongodb-3/pom.xml | 28 +++++- .../boot/csfle/config/EncryptionConfig.java | 28 +++++- .../boot/csfle/config/MongoClientConfig.java | 88 ++++++++++++++----- .../boot/csfle/service/CitizenService.java | 33 ++++--- .../boot/csfle/web/CitizenController.java | 3 +- .../boot/csfle/CitizenServiceLiveTest.java | 10 ++- .../src/test/resources/embedded.properties | 6 +- 7 files changed, 150 insertions(+), 46 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml b/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml index b9a47aa703..484e0c0f7e 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml +++ b/persistence-modules/spring-boot-persistence-mongodb-3/pom.xml @@ -16,6 +16,21 @@ + + org.mongodb + mongodb-driver-sync + ${mongodb-driver.version} + + + org.mongodb + mongodb-driver-core + ${mongodb-driver.version} + + + org.mongodb + bson + ${mongodb-driver.version} + org.springframework.boot spring-boot-starter-web @@ -23,6 +38,16 @@ org.springframework.boot spring-boot-starter-data-mongodb + + + org.mongodb + mongodb-driver-sync + + + org.mongodb + mongodb-driver-core + + org.mongodb @@ -37,7 +62,8 @@ - 1.6.1 + 1.7.3 + 4.9.1 diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java index 0ff97eb6c1..1a74340057 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/EncryptionConfig.java @@ -1,5 +1,7 @@ package com.baeldung.boot.csfle.config; +import java.io.File; + import org.bson.BsonBinary; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -17,7 +19,13 @@ public class EncryptionConfig { private String keyVaultAlias; @Value("${com.baeldung.csfle.auto-decryption:false}") - private Boolean autoDecryption; + private boolean autoDecryption; + + @Value("${com.baeldung.csfle.auto-encryption:false}") + private boolean autoEncryption; + + @Value("${com.baeldung.csfle.auto-encryption-lib:#{null}}") + private File autoEncryptionLib; private BsonBinary dataKeyId; @@ -41,7 +49,23 @@ public class EncryptionConfig { return masterKeyPath; } - public Boolean getAutoDecryption() { + public boolean isAutoDecryption() { return autoDecryption; } + + public boolean isAutoEncryption() { + return autoEncryption; + } + + public File getAutoEncryptionLib() { + return autoEncryptionLib; + } + + public String dataKeyIdUuid() { + if (dataKeyId == null) + throw new IllegalStateException("data key not initialized"); + + return dataKeyId.asUuid() + .toString(); + } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java index 0dff1ec86d..19d0af08b2 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/config/MongoClientConfig.java @@ -1,14 +1,15 @@ package com.baeldung.boot.csfle.config; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import org.bson.BsonBinary; import org.bson.BsonDocument; import org.bson.Document; -import org.bson.conversions.Bson; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -51,14 +52,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { @Bean @Override public MongoClient mongoClient() { - MongoClient client; try { - client = MongoClients.create(clientSettings()); - ClientEncryption encryption = clientEncryption(); - encryptionConfig.setDataKeyId(createOrRetrieveDataKey(client, encryption)); - - return client; + encryptionConfig.setDataKeyId(createOrRetrieveDataKey(encryption)); + return MongoClients.create(clientSettings()); } catch (IOException e) { throw new IllegalStateException("unable to create client", e); } @@ -77,19 +74,10 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { return ClientEncryptions.create(encryptionSettings); } - private BsonBinary createOrRetrieveDataKey(MongoClient client, ClientEncryption encryption) { - MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace()); - MongoCollection keyVault = client.getDatabase(namespace.getDatabaseName()) - .getCollection(namespace.getCollectionName()); - - Bson query = Filters.in("keyAltNames", encryptionConfig.getKeyVaultAlias()); - BsonDocument key = keyVault.withDocumentClass(BsonDocument.class) - .find(query) - .first(); - + private BsonBinary createOrRetrieveDataKey(ClientEncryption encryption) { + BsonDocument key = encryption.getKeyByAltName(encryptionConfig.getKeyVaultAlias()); if (key == null) { - keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true) - .partialFilterExpression(Filters.exists("keyAltNames"))); + createKeyUniqueIndex(); DataKeyOptions options = new DataKeyOptions(); options.keyAltNames(Arrays.asList(encryptionConfig.getKeyVaultAlias())); @@ -99,16 +87,68 @@ public class MongoClientConfig extends AbstractMongoClientConfiguration { } } + private void createKeyUniqueIndex() { + try (MongoClient client = MongoClients.create(MongoClientSettings.builder() + .applyConnectionString(new ConnectionString(uri)) + .build())) { + MongoNamespace namespace = new MongoNamespace(encryptionConfig.getKeyVaultNamespace()); + MongoCollection keyVault = client.getDatabase(namespace.getDatabaseName()) + .getCollection(namespace.getCollectionName()); + + keyVault.createIndex(Indexes.ascending("keyAltNames"), new IndexOptions().unique(true) + .partialFilterExpression(Filters.exists("keyAltNames"))); + } + } + private MongoClientSettings clientSettings() throws FileNotFoundException, IOException { Builder settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(uri)); - if (encryptionConfig.getAutoDecryption()) { - settings.autoEncryptionSettings(AutoEncryptionSettings.builder() + if (encryptionConfig.isAutoDecryption()) { + AutoEncryptionSettings.Builder builder = AutoEncryptionSettings.builder() .keyVaultNamespace(encryptionConfig.getKeyVaultNamespace()) - .kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath())) - .bypassAutoEncryption(true) - .build()); + .kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath())); + + if (encryptionConfig.isAutoEncryption() && encryptionConfig.getDataKeyId() != null) { + File autoEncryptionLib = encryptionConfig.getAutoEncryptionLib(); + if (!autoEncryptionLib.isFile()) { + throw new IllegalArgumentException("encryption lib must be an existing file"); + } + + Map map = new HashMap<>(); + map.put("cryptSharedLibRequired", true); + map.put("cryptSharedLibPath", autoEncryptionLib.toString()); + builder.extraOptions(map); + + String keyUuid = encryptionConfig.dataKeyIdUuid(); + HashMap schemaMap = new HashMap<>(); + schemaMap.put(getDatabaseName() + ".citizens", + BsonDocument.parse("{" + + " bsonType: \"object\"," + + " encryptMetadata: {" + + " keyId: [UUID(\"" + keyUuid + "\")]" + + " }," + + " properties: {" + + " email: {" + + " encrypt: {" + + " bsonType: \"string\"," + + " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\"" + + " }" + + " }," + + " birthYear: {" + + " encrypt: {" + + " bsonType: \"int\"," + + " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Random\"" + + " }" + + " }" + + " }" + + "}")); + builder.schemaMap(schemaMap); + } else { + builder.bypassAutoEncryption(true); + } + + settings.autoEncryptionSettings(builder.build()); } return settings.build(); diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java index 6b3c463d0d..c93b00f3f8 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java @@ -35,16 +35,20 @@ public class CitizenService { @Autowired private ClientEncryption clientEncryption; - public EncryptedCitizen save(Citizen citizen) { - EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen); - encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); - encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); + public Object save(Citizen citizen) { + if (encryptionConfig.isAutoEncryption()) { + return mongo.save(citizen); + } else { + EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen); + encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); + encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); - return mongo.save(encryptedCitizen); + return mongo.save(encryptedCitizen); + } } public List findAll() { - if (!encryptionConfig.getAutoDecryption()) { + if (!encryptionConfig.isAutoDecryption()) { List allEncrypted = mongo.findAll(EncryptedCitizen.class); return allEncrypted.stream() @@ -56,13 +60,20 @@ public class CitizenService { } public Citizen findByEmail(String email) { - Query byEmail = new Query(Criteria.where("email") - .is(encrypt(email, DETERMINISTIC_ALGORITHM))); - if (!encryptionConfig.getAutoDecryption()) { + Criteria emailCriteria = Criteria.where("email"); + if (encryptionConfig.isAutoEncryption()) { + emailCriteria.is(email); + } else { + emailCriteria + .is(encrypt(email, DETERMINISTIC_ALGORITHM)); + } + + Query byEmail = new Query(emailCriteria); + if (encryptionConfig.isAutoDecryption()) { + return mongo.findOne(byEmail, Citizen.class); + } else { EncryptedCitizen encryptedCitizen = mongo.findOne(byEmail, EncryptedCitizen.class); return decrypt(encryptedCitizen); - } else { - return mongo.findOne(byEmail, Citizen.class); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java index d17435fb5e..7a2b2605cd 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.baeldung.boot.csfle.data.Citizen; -import com.baeldung.boot.csfle.data.EncryptedCitizen; import com.baeldung.boot.csfle.service.CitizenService; @RestController @@ -32,7 +31,7 @@ public class CitizenController { } @PostMapping - public EncryptedCitizen post(@RequestBody Citizen citizen) { + public Object post(@RequestBody Citizen citizen) { return service.save(citizen); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java index 471cb2883a..d57da43751 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/csfle/CitizenServiceLiveTest.java @@ -38,10 +38,14 @@ public class CitizenServiceLiveTest { citizen.setName("Foo"); citizen.setEmail("foo@citizen.com"); - Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM); + Object saved = service.save(citizen); + if (saved instanceof EncryptedCitizen) { + Binary encryptedEmail = service.encrypt(citizen.getEmail(), CitizenService.DETERMINISTIC_ALGORITHM); - EncryptedCitizen saved = service.save(citizen); - assertEquals(encryptedEmail, saved.getEmail()); + assertEquals(encryptedEmail, ((EncryptedCitizen) saved).getEmail()); + } else { + assertEquals(citizen.getEmail(), ((Citizen) saved).getEmail()); + } } @Test diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties index 5325354e55..cd1c1d43c7 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/resources/embedded.properties @@ -1,10 +1,10 @@ spring.mongodb.embedded.version=4.4.9 -spring.data.mongodb.uri=changeit -spring.data.mongodb.database=changeit +#spring.data.mongodb.uri=changeit +#spring.data.mongodb.database=changeit com.baeldung.csfle.kms-provider=local com.baeldung.csfle.key-vault.namespace=encryption._keyVault com.baeldung.csfle.key-vault.alias=master.key -com.baeldung.csfle.master-key-path=/tmp/master.key +#com.baeldung.csfle.master-key-path=/tmp/master.key com.baeldung.csfle.auto-decryption=false From ce79066afc6b20c1d2d9dbd09dc8cc34e096f300 Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Sat, 6 May 2023 21:58:20 +0530 Subject: [PATCH 19/20] [BAEL-6253] record equals hashcode (#13958) * [BAEL-6253] records equals and hashcode * [BAEL-6253] records equals and hashcode * [BAEL-6253] records equals and hashcode test case --------- Co-authored-by: Bhaskar --- core-java-modules/core-java-records/pom.xml | 32 +++++++++++++++++++ .../baeldung/equalshashcoderecords/Movie.java | 26 +++++++++++++++ .../equalshashcoderecords/Person.java | 5 +++ .../CustomRecordEqualsHashCode.java | 30 +++++++++++++++++ core-java-modules/pom.xml | 1 + 5 files changed, 94 insertions(+) create mode 100644 core-java-modules/core-java-records/pom.xml create mode 100644 core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java create mode 100644 core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java create mode 100644 core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java diff --git a/core-java-modules/core-java-records/pom.xml b/core-java-modules/core-java-records/pom.xml new file mode 100644 index 0000000000..ed9a36fc14 --- /dev/null +++ b/core-java-modules/core-java-records/pom.xml @@ -0,0 +1,32 @@ + + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + 4.0.0 + + core-java-records + + + + org.apache.maven.plugins + maven-compiler-plugin + + 16 + 16 + + + + + + + 19 + 19 + UTF-8 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java new file mode 100644 index 0000000000..e94638e8b5 --- /dev/null +++ b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Movie.java @@ -0,0 +1,26 @@ +package com.baeldung.equalshashcoderecords; + +import java.util.Objects; + +record Movie(String name, Integer yearOfRelease, String distributor) { + +@Override +public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null) { + return false; + } + Movie movie = (Movie) other; + if (movie.name.equals(this.name) && movie.yearOfRelease.equals(this.yearOfRelease)) { + return true; + } + return false; +} + + @Override + public int hashCode() { + return Objects.hash(name, yearOfRelease); + } +} diff --git a/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java new file mode 100644 index 0000000000..7bfd8ae741 --- /dev/null +++ b/core-java-modules/core-java-records/src/main/java/com/baeldung/equalshashcoderecords/Person.java @@ -0,0 +1,5 @@ +package com.baeldung.equalshashcoderecords; + +public record Person(String firstName, String lastName, String SSN, String dateOfBirth) { +}; + diff --git a/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java b/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java new file mode 100644 index 0000000000..074886304f --- /dev/null +++ b/core-java-modules/core-java-records/src/test/java/com/baeldung/equalshashcoderecords/CustomRecordEqualsHashCode.java @@ -0,0 +1,30 @@ +package com.baeldung.equalshashcoderecords; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.Test; + +public class CustomRecordEqualsHashCode { + @Test + public void givenTwoRecords_whenDefaultEquals_thenCompareEquality() { + Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + Person mike = new Person("Mike", "Adams", "ABJDJ2883", "2001-01-02"); + assertNotEquals(robert, mike); + } + + @Test + public void givenTwoRecords_hashCodesShouldBeSame() { + Person robert = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + Person robertCopy = new Person("Robert", "Frost", "HDHDB223", "2000-01-02"); + assertEquals(robert.hashCode(), robertCopy.hashCode()); + } + + @Test + public void givenTwoRecords_whenCustomImplementation_thenCompareEquality() { + Movie movie1 = new Movie("The Batman", 2022, "WB"); + Movie movie2 = new Movie("The Batman", 2022, "Dreamworks"); + assertEquals(movie1, movie2); + assertEquals(movie1.hashCode(), movie2.hashCode()); + } +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 6f3aec8c3a..91f0dbfc28 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -141,6 +141,7 @@ core-java-uuid pre-jpms core-java-collections-maps-6 + core-java-records From 65cf74f42f5cbc2cb44c3865ec0ff251394f8436 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sun, 7 May 2023 17:05:37 +0200 Subject: [PATCH 20/20] [compByteArrays] Comparing Two Byte Arrays in Java (#13935) --- .../compare/CompareByteArraysUnitTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java diff --git a/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java new file mode 100644 index 0000000000..4274acf83d --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-basic/src/test/java/com/baeldung/array/compare/CompareByteArraysUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.array.compare; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +public class CompareByteArraysUnitTest { + private final static String INPUT = "I am a magic string."; + private final static byte[] ARRAY1 = INPUT.getBytes(); + private final static byte[] ARRAY2 = INPUT.getBytes(); + + @Test + void whenUsingEqualsSign_thenTwoArraysAreNotEqual() { + assertFalse(ARRAY1 == ARRAY2); + } + + @Test + void whenUsingEquals_thenTwoArraysAreNotEqual() { + assertFalse(ARRAY1.equals(ARRAY2)); + } + + @Test + void whenUsingArrayEquals_thenTwoArraysAreEqual() { + assertTrue(Arrays.equals(ARRAY1, ARRAY2)); + } + + @Test + void whenComparingStringArrays_thenGetExpectedResult() { + String[] strArray1 = new String[] { "Java", "is", "great" }; + String[] strArray2 = new String[] { "Java", "is", "great" }; + + assertFalse(strArray1 == strArray2); + assertFalse(strArray1.equals(strArray2)); + assertTrue(Arrays.equals(strArray1, strArray2)); + } +} \ No newline at end of file