From fa06d77df8272afb13814aa500366a6ea45e0e8a Mon Sep 17 00:00:00 2001 From: Vladyslav Chernov Date: Mon, 24 Jul 2023 13:17:40 -0700 Subject: [PATCH 001/283] BAEL-5852: What does the Holder do in Java? --- .../main/java/com/baeldung/holder/Holder.java | 9 ++++++ .../com/baeldung/holder/SupplierService.java | 13 ++++++++ .../holder/SupplierServiceUnitTest.java | 31 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java create mode 100644 core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java create mode 100644 core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java new file mode 100644 index 0000000000..da066ee5c6 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java @@ -0,0 +1,9 @@ +package com.baeldung.holder; + +public class Holder { + public T value; + + public Holder(T value) { + this.value = value; + } +} diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java new file mode 100644 index 0000000000..473a4de423 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java @@ -0,0 +1,13 @@ +package com.baeldung.holder; + +public class SupplierService { + public void getSupplierByZipCode(String zip, Holder resultHolder) { + // Let's pretend we did some work here to get the supplier + // And let's say all zip codes starting with "9" are valid, just for this example + if (zip.startsWith("9")) { + resultHolder.value = true; + } else { + resultHolder.value = false; + } + } +} diff --git a/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java new file mode 100644 index 0000000000..e1446fc229 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.holder; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class SupplierServiceUnitTest { + + @Test + public void givenValidZipCode_whenGetSupplierByZipCode_thenTrue() { + SupplierService service = new SupplierService(); + Holder resultHolder = new Holder<>(false); + String zipCode = "98682"; + + service.getSupplierByZipCode(zipCode, resultHolder); + + assertTrue(resultHolder.value); + } + + @Test + public void givenInvalidZipCode_whenGetSupplierByZipCode_thenFalse() { + SupplierService service = new SupplierService(); + Holder resultHolder = new Holder<>(true); + String zipCode = "12345"; + + service.getSupplierByZipCode(zipCode, resultHolder); + + assertFalse(resultHolder.value); + } +} From 0bb7a8db27e93e108459f1c9baa340a898a23176 Mon Sep 17 00:00:00 2001 From: Vladyslav Chernov Date: Sun, 17 Sep 2023 21:57:35 -0700 Subject: [PATCH 002/283] BAEL-5755: Convert an XML file to CSV file --- .../baeldung/xml/xml2csv/Xml2CsvExample.java | 113 +++++++++++++ xml/src/main/resources/xml2csv/data.xml | 26 +++ xml/src/main/resources/xml2csv/style.xsl | 21 +++ .../xml/xml2csv/Xml2CsvExampleUnitTest.java | 155 ++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java create mode 100644 xml/src/main/resources/xml2csv/data.xml create mode 100644 xml/src/main/resources/xml2csv/style.xsl create mode 100644 xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java diff --git a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java new file mode 100644 index 0000000000..d2acafc881 --- /dev/null +++ b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java @@ -0,0 +1,113 @@ +package com.baeldung.xml.xml2csv; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +public class Xml2CsvExample { + + private static final String BASE_PATH = "xml/src/main/resources/xml2csv/"; + + private static final String STYLE_XSL = BASE_PATH + "style.xsl"; + private static final String DATA_XML = BASE_PATH + "data.xml"; + private static final String OUTPUT_CSV_XSTL = BASE_PATH + "output_xstl.csv"; + private static final String OUTPUT_CSV_STAX = BASE_PATH + "output_stax.csv"; + + public static void main(String[] args) { + try { + convertXml2CsvXslt(STYLE_XSL, DATA_XML, OUTPUT_CSV_XSTL); + convertXml2CsvStax(DATA_XML, OUTPUT_CSV_STAX); + } catch (IOException | TransformerException e) { + e.printStackTrace(); + } + } + + protected static void convertXml2CsvXslt(String xslPath, String xmlPath, String csvPath) throws IOException, TransformerException { + StreamSource styleSource = new StreamSource(new File(xslPath)); + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(styleSource); + Source source = new StreamSource(new File(xmlPath)); + Result outputTarget = new StreamResult(new File(csvPath)); + transformer.transform(source, outputTarget); + } + + protected static void convertXml2CsvStax(String xmlFilePath, String csvFilePath) throws IOException, TransformerException { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + + try (InputStream in = Files.newInputStream(Paths.get(xmlFilePath)); BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) { + + // Write header to CSV + writer.write("bookstore_id,book_id,category,title,author_id,author_name,price\n"); + + XMLStreamReader reader = inputFactory.createXMLStreamReader(in); + + String currentElement; + StringBuilder csvRow = new StringBuilder(); + StringBuilder bookstoreInfo = new StringBuilder(); + + while (reader.hasNext()) { + int eventType = reader.next(); + + switch (eventType) { + case XMLStreamConstants.START_ELEMENT: + currentElement = reader.getLocalName(); + if ("Bookstore".equals(currentElement)) { + bookstoreInfo.setLength(0); // clear previous bookstore info + bookstoreInfo.append(reader.getAttributeValue(null, "id")) + .append(","); + } + if ("Book".equals(currentElement)) { + csvRow.append(bookstoreInfo) + .append(reader.getAttributeValue(null, "id")) + .append(",") + .append(reader.getAttributeValue(null, "category")) + .append(","); + } + if ("Author".equals(currentElement)) { + csvRow.append(reader.getAttributeValue(null, "id")) + .append(","); + } + break; + + case XMLStreamConstants.CHARACTERS: + if (!reader.isWhiteSpace()) { + csvRow.append(reader.getText() + .trim()) + .append(","); + } + break; + + case XMLStreamConstants.END_ELEMENT: + if ("Book".equals(reader.getLocalName())) { + // remove the last comma and add a newline + csvRow.setLength(csvRow.length() - 1); + csvRow.append("\n"); + writer.write(csvRow.toString()); + + // Reset the StringBuilder for the next row + csvRow.setLength(0); + } + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/xml/src/main/resources/xml2csv/data.xml b/xml/src/main/resources/xml2csv/data.xml new file mode 100644 index 0000000000..385fcf661c --- /dev/null +++ b/xml/src/main/resources/xml2csv/data.xml @@ -0,0 +1,26 @@ + + + + + + Death and the Penguin + Andrey Kurkov + 10.99 + + + Kobzar + Taras Shevchenko + 8.50 + + + + + + + Voroshilovgrad + Serhiy Zhadan + 12.99 + + + + diff --git a/xml/src/main/resources/xml2csv/style.xsl b/xml/src/main/resources/xml2csv/style.xsl new file mode 100644 index 0000000000..ea23880092 --- /dev/null +++ b/xml/src/main/resources/xml2csv/style.xsl @@ -0,0 +1,21 @@ + + + + + bookstore_id,book_id,category,title,author_id,author_name,price + + + + + + + + + + + + + + + + diff --git a/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java new file mode 100644 index 0000000000..3fa44b427c --- /dev/null +++ b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java @@ -0,0 +1,155 @@ +package com.baeldung.xml.xml2csv; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.xml.transform.TransformerException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +public class Xml2CsvExampleUnitTest { + + private static final String BASE_PATH = "src/main/resources/xml2csv/"; + + private static final String STYLE_XSL = BASE_PATH + "style.xsl"; + private static final String DATA_XML = BASE_PATH + "data.xml"; + private static final String TEMP_OUTPUT_CSV = BASE_PATH + "tempOutput.xml"; + + @AfterEach + public void teardown() { + new File(TEMP_OUTPUT_CSV).delete(); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvFileIsCreated() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + assertTrue(csvFile.exists()); + } + + @Test + public void whenConvertXml2CsvStax_thenCsvFileIsCreated() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + assertTrue(csvFile.exists()); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvFileIsNotEmpty() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + BufferedReader reader = new BufferedReader(new FileReader(csvFile)); + String firstLine = reader.readLine(); + assertNotNull(firstLine); + assertFalse(firstLine.isEmpty()); + + reader.close(); + } + + @Test + public void whenConvertXml2CsvStax_thenCsvFileIsNotEmpty() throws IOException, TransformerException { + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + BufferedReader reader = new BufferedReader(new FileReader(csvFile)); + String firstLine = reader.readLine(); + assertNotNull(firstLine); + assertFalse(firstLine.isEmpty()); + + reader.close(); + } + + @Test + public void whenConvertXml2CsvXsltWithWrongXSL_thenThrowsException() { + String xslWrongPath = BASE_PATH + "wrongFile.xsl"; + + assertThrows(TransformerException.class, () -> Xml2CsvExample.convertXml2CsvXslt(xslWrongPath, DATA_XML, TEMP_OUTPUT_CSV)); + } + + @Test + public void whenConvertXml2CsvXslt_thenCsvMatchesPattern() throws IOException, TransformerException { + String headerPattern = "^bookstore_id,book_id,category,title,author_id,author_name,price$"; + String dataPattern = "^[A-Z0-9]+,[A-Z0-9]+,[a-zA-Z]+,[a-zA-Z0-9\\s]+,[A-Z0-9]+,[a-zA-Z\\s]+,\\d+(\\.\\d{2})?$"; + + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + String line; + boolean isFirstLine = true; + while ((line = reader.readLine()) != null) { + if (isFirstLine) { + assertTrue(line.matches(headerPattern), "Header does not match pattern"); + isFirstLine = false; + } else { + assertTrue(line.matches(dataPattern), "Data line does not match pattern"); + } + } + } + } + + @Test + public void whenConvertXml2Stax_thenCsvMatchesPattern() throws IOException, TransformerException { + String headerPattern = "^bookstore_id,book_id,category,title,author_id,author_name,price$"; + String dataPattern = "^[A-Z0-9]+,[A-Z0-9]+,[a-zA-Z]+,[a-zA-Z0-9\\s]+,[A-Z0-9]+,[a-zA-Z\\s]+,\\d+(\\.\\d{2})?$"; + + Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); + + File csvFile = new File(TEMP_OUTPUT_CSV); + try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + String line; + boolean isFirstLine = true; + while ((line = reader.readLine()) != null) { + if (isFirstLine) { + assertTrue(line.matches(headerPattern), "Header does not match pattern"); + isFirstLine = false; + } else { + assertTrue(line.matches(dataPattern), "Data line does not match pattern"); + } + } + } + } + + @Test + public void whenConcurrentConversion_thenNoErrors() throws InterruptedException { + int numThreads = 10; + ExecutorService service = Executors.newFixedThreadPool(numThreads); + CountDownLatch latch = new CountDownLatch(numThreads); + + for (int i = 0; i < numThreads; i++) { + final int threadId = i; + service.execute(() -> { + String threadSpecificOutputCsv = BASE_PATH + "tempOutput" + threadId + ".csv"; + try { + Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, threadSpecificOutputCsv); + assertTrue(Files.exists(Paths.get(threadSpecificOutputCsv)), "File should exist"); + } catch (IOException | TransformerException e) { + fail("Exception should not be thrown: " + e.getMessage()); + } finally { + new File(threadSpecificOutputCsv).delete(); + latch.countDown(); + } + }); + } + + latch.await(); + } + +} From 5c8a1373498a1eed20a14085863c63327fa8a3c9 Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Fri, 6 Oct 2023 17:48:47 +0530 Subject: [PATCH 003/283] JAVA-18764: Chnages made for applcation.yml file --- .../src/main/resources/application.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/security-modules/cas/cas-server/src/main/resources/application.yml b/security-modules/cas/cas-server/src/main/resources/application.yml index 0c4e4ffde2..0fd72c539d 100644 --- a/security-modules/cas/cas-server/src/main/resources/application.yml +++ b/security-modules/cas/cas-server/src/main/resources/application.yml @@ -8,3 +8,19 @@ server: spring: main: allow-bean-definition-overriding: true +cas: + authn: + accept: + users: + jdbc: + query[0]: + sql: SELECT * FROM users WHERE email = ? + url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC + dialect: org.hibernate.dialect.MySQLDialect + user: root + password: root1234 + ddlAuto: none + driverClass: com.mysql.cj.jdbc.Driver + fieldPassword: password + passwordEncoder: + type: NONE From c8bc9634d5ca7f92fe65193ff6ddec6b8682ebfd Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Mon, 9 Oct 2023 21:00:52 +0530 Subject: [PATCH 004/283] JAVA-18764: Update article "CAS SSO with Spring Security" --- security-modules/cas/cas-secured-app/pom.xml | 9 ++++ .../cassecuredapp/CasSecuredApplication.java | 11 ++++- .../cassecuredapp/MyUserDetailsService.java | 34 +++++++++++++++ .../cassecuredapp/UserRepository.java | 15 +++++++ .../com/baeldung/cassecuredapp/Users.java | 41 +++++++++++++++++++ .../src/main/resources/application.properties | 8 +++- 6 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java create mode 100644 security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java create mode 100644 security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java diff --git a/security-modules/cas/cas-secured-app/pom.xml b/security-modules/cas/cas-secured-app/pom.xml index 6f1ec22cb5..6e1b878354 100644 --- a/security-modules/cas/cas-secured-app/pom.xml +++ b/security-modules/cas/cas-secured-app/pom.xml @@ -36,6 +36,15 @@ spring-boot-devtools runtime + + org.springframework.boot + spring-boot-starter-data-jpa + + + mysql + mysql-connector-java + runtime + org.springframework.boot spring-boot-starter-test diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java index 62da9cf725..9293a3e00f 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java @@ -6,6 +6,7 @@ import org.jasig.cas.client.validation.Cas30ServiceTicketValidator; import org.jasig.cas.client.validation.TicketValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -34,6 +35,7 @@ public class CasSecuredApplication { SpringApplication.run(CasSecuredApplication.class, args); } + @Bean public CasAuthenticationFilter casAuthenticationFilter( AuthenticationManager authenticationManager, @@ -58,6 +60,10 @@ public class CasSecuredApplication { return new Cas30ServiceTicketValidator("https://localhost:8443/cas"); } + @Bean + public MyUserDetailsService getUser(){ + return new MyUserDetailsService(); + } @Bean public CasAuthenticationProvider casAuthenticationProvider( TicketValidator ticketValidator, @@ -65,9 +71,10 @@ public class CasSecuredApplication { CasAuthenticationProvider provider = new CasAuthenticationProvider(); provider.setServiceProperties(serviceProperties); provider.setTicketValidator(ticketValidator); - provider.setUserDetailsService( + /* provider.setUserDetailsService( s -> new User("casuser", "Mellon", true, true, true, true, - AuthorityUtils.createAuthorityList("ROLE_ADMIN"))); + AuthorityUtils.createAuthorityList("ROLE_ADMIN")));*/ + provider.setUserDetailsService(getUser()); provider.setKey("CAS_PROVIDER_LOCALHOST_8900"); return provider; } diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java new file mode 100644 index 0000000000..35c83bfd75 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java @@ -0,0 +1,34 @@ +package com.baeldung.cassecuredapp; + +import java.util.Collections; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +public class MyUserDetailsService implements UserDetailsService { + + @Autowired + private UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + // Get the user from the database. + Users users = getUserFromDatabase(username); + + // Create a UserDetails object. + UserDetails userDetails = new User( + users.getEmail(), + users.getPassword(), + Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN"))); + + return userDetails; + } + + private Users getUserFromDatabase(String username) { + return userRepository.findByEmail(username); + } +} diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java new file mode 100644 index 0000000000..366329a3fb --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.cassecuredapp; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends CrudRepository { + + Users findByEmail(@Param("email") String email); + +} diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java new file mode 100644 index 0000000000..4e775e80e3 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java @@ -0,0 +1,41 @@ +package com.baeldung.cassecuredapp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Users { + @Id + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + private String password; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/security-modules/cas/cas-secured-app/src/main/resources/application.properties b/security-modules/cas/cas-secured-app/src/main/resources/application.properties index f8789997d5..fa13527982 100644 --- a/security-modules/cas/cas-secured-app/src/main/resources/application.properties +++ b/security-modules/cas/cas-secured-app/src/main/resources/application.properties @@ -1,2 +1,8 @@ server.port=8900 -spring.freemarker.suffix=.ftl \ No newline at end of file +spring.freemarker.suffix=.ftl + +spring.jpa.generate-ddl=false +spring.datasource.url= jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +spring.datasource.username=root +spring.datasource.password=root1234 +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver \ No newline at end of file From 307d0f5e409b29c6bced2310206ba093b34769e7 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Tue, 10 Oct 2023 22:39:14 -0400 Subject: [PATCH 005/283] Message Ordering - First Draft. --- apache-kafka-2/pom.xml | 5 ++ .../ordering/ConsumerConfigurations.java | 32 ++++++++++++ .../ExtSeqWithTimeWindowConsumer.java | 49 +++++++++++++++++++ .../ExtSeqWithTimeWindowProducer.java | 29 +++++++++++ .../ordering/MultiPartitionConsumer.java | 34 +++++++++++++ .../ordering/MultiPartitionProducer.java | 27 ++++++++++ .../ordering/ProducerConfigurations.java | 27 ++++++++++ .../ordering/SinglePartitionConsumer.java | 35 +++++++++++++ .../ordering/SinglePartitionProducer.java | 29 +++++++++++ .../message/ordering/payload/Message.java | 36 ++++++++++++++ .../serialization/JacksonDeserializer.java | 36 ++++++++++++++ .../serialization/JacksonSerializer.java | 20 ++++++++ 12 files changed, 359 insertions(+) create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java diff --git a/apache-kafka-2/pom.xml b/apache-kafka-2/pom.xml index 067dedef8a..45b31004b7 100644 --- a/apache-kafka-2/pom.xml +++ b/apache-kafka-2/pom.xml @@ -57,6 +57,11 @@ ${lombok.version} provided + + com.fasterxml.jackson.core + jackson-databind + 2.15.2 + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java new file mode 100644 index 0000000000..b18db3ef24 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -0,0 +1,32 @@ +package com.baeldung.kafka.message.ordering; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; + +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; + +public class ConsumerConfigurations { + public static void main(String[] args) { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put("max.poll.records", "500"); + props.put("fetch.min.bytes", "1"); + props.put("fetch.max.wait.ms", "500"); + Consumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(Collections.singletonList("multi_partition_topic")); + + while (true) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + records.forEach(record -> { + System.out.println("Partition: " + record.partition() + ", Message: " + record.value()); + }); + } + } +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java new file mode 100644 index 0000000000..5b01a86e39 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -0,0 +1,49 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; + +import java.time.Duration; +import java.util.*; + +public class ExtSeqWithTimeWindowConsumer { + private static final long BUFFER_PERIOD_MS = 5000; + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); + + public static void main(String[] args) { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put("value.deserializer.serializedClass", Message.class); + Consumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(Collections.singletonList("multi_partition_topic")); + List buffer = new ArrayList<>(); + long lastProcessedTime = System.nanoTime(); + while (true) { + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + if (record != null && record.value() != null) { + buffer.add(record.value()); + } + }); + if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_MS) { + processBuffer(buffer); + lastProcessedTime = System.nanoTime(); + } + } + } + + private static void processBuffer(List buffer) { + Collections.sort(buffer); + buffer.forEach(message -> { + System.out.println("Processing message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + }); + buffer.clear(); + } +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java new file mode 100644 index 0000000000..91c5af716f --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -0,0 +1,29 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; + +import java.util.Properties; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; + +public class ExtSeqWithTimeWindowProducer { + public static void main(String[] args) { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + + KafkaProducer producer = new KafkaProducer<>(props); + for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { + long messageId = Message.getRandomMessageId(); + String key = "Key-" + insertPosition; + Message message = new Message(insertPosition, messageId); + producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); + System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + } + producer.close(); + System.out.println("ExternalSequencingProducer Completed."); + } +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java new file mode 100644 index 0000000000..f9b0b3b040 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -0,0 +1,34 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; + +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; + +public class MultiPartitionConsumer { + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); + public static void main(String[] args) { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put("value.deserializer.serializedClass", Message.class); + Consumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(Collections.singletonList("multi_partition_topic")); + while (true) { + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + Message message = record.value(); + System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + }); + } + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java new file mode 100644 index 0000000000..8b2a49b2b5 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -0,0 +1,27 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; + +import java.util.Properties; + +public class MultiPartitionProducer { + public static void main(String[] args) { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + + KafkaProducer producer = new KafkaProducer<>(props); + for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { + long messageId = Message.getRandomMessageId(); + String key = "Key-" + insertPosition; + Message message = new Message(insertPosition, messageId); + producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); + System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + } + producer.close(); + System.out.println("SinglePartitionProducer Completed."); + } +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java new file mode 100644 index 0000000000..bcdf6ceb32 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -0,0 +1,27 @@ +package com.baeldung.kafka.message.ordering; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; + +import java.util.Properties; + +public class ProducerConfigurations { + public static void main(String[] args) { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("max.in.flight.requests.per.connection", "1"); + props.put("batch.size", "16384"); + props.put("linger.ms", "5"); + KafkaProducer producer = new KafkaProducer<>(props); + + for (int i = 0; i < 10; i++) { + String key = "Key-" + (i % 3); // Assuming 3 partitions + producer.send(new ProducerRecord<>("multi_partition_topic", key, "Message-" + i)); + } + + producer.close(); + System.out.println("MultiPartitionProducer Completed."); + } +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java new file mode 100644 index 0000000000..932a29c394 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -0,0 +1,35 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; + +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; + +public class SinglePartitionConsumer { + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); + + public static void main(String[] args) { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put("value.deserializer.serializedClass", Message.class); + Consumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(Collections.singletonList("single_partition_topic")); + while (true) { + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + Message message = record.value(); + System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + }); + } + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java new file mode 100644 index 0000000000..b5366819c5 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -0,0 +1,29 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; + +import java.util.Properties; +import java.util.Random; + +public class SinglePartitionProducer { + public static void main(String[] args) { + Properties props = new Properties(); + props.put("bootstrap.servers", "localhost:9092"); + props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + + KafkaProducer producer = new KafkaProducer<>(props); + for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { + long messageId = Message.getRandomMessageId(); + String key = "Key-" + insertPosition; + Message message = new Message(insertPosition, messageId); + producer.send(new ProducerRecord<>("single_partition_topic", key, message)); + System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + } + producer.close(); + System.out.println("SinglePartitionProducer Completed."); + } + +} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java new file mode 100644 index 0000000000..b185d663d4 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -0,0 +1,36 @@ +package com.baeldung.kafka.message.ordering.payload; + +import java.util.Random; + +public class Message implements Comparable { + private long insertPosition; + private long messageId; + + public Message(){ + + } + + public Message(long insertPosition, long messageId) { + this.insertPosition = insertPosition; + this.messageId = messageId; + } + + public long getInsertPosition() { + return insertPosition; + } + + public long getMessageId() { + return messageId; + } + + @Override + public int compareTo(Message other) { + return Long.compare(this.messageId, other.messageId); + } + + public static long getRandomMessageId() { + Random rand = new Random(); + return rand.nextInt(1000); + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java new file mode 100644 index 0000000000..34aa181fcb --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -0,0 +1,36 @@ +package com.baeldung.kafka.message.ordering.serialization; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.common.serialization.Deserializer; + +import java.util.Map; + +public class JacksonDeserializer implements Deserializer { + private final ObjectMapper objectMapper = new ObjectMapper(); + private Class tClass; + + public JacksonDeserializer(Class tClass) { + this.tClass = tClass; + } + + public JacksonDeserializer() { + + } + + @Override + public void configure(Map configs, boolean isKey) { + this.tClass = (Class) configs.get("value.deserializer.serializedClass"); + } + + @Override + public T deserialize(String topic, byte[] bytes) { + if (bytes == null) { + return null; + } + try { + return objectMapper.readValue(bytes, tClass); + } catch (Exception e) { + throw new RuntimeException("Error deserializing value", e); + } + } +} + diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java new file mode 100644 index 0000000000..fa9d25dd85 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java @@ -0,0 +1,20 @@ +package com.baeldung.kafka.message.ordering.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.common.serialization.Serializer; + +public class JacksonSerializer implements Serializer { + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public byte[] serialize(String topic, T data) { + if (data == null) { + return null; + } + try { + return objectMapper.writeValueAsBytes(data); + } catch (Exception e) { + throw new RuntimeException("Error serializing value", e); + } + } +} From 23124ab6f81536cb1a7e242d9caad1aead3fdf14 Mon Sep 17 00:00:00 2001 From: Vinay Mhatre <90505086+SamsterZero@users.noreply.github.com> Date: Wed, 11 Oct 2023 18:26:22 +0530 Subject: [PATCH 006/283] To change default redirect Previously after logging in we used to get the desired index page, but the address bar still had the "/login" in the address bar, this code fixes that --- .../com/baeldung/customuserdetails/SecurityConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java index cfec910ce9..d438aefcdc 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java +++ b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/SecurityConfiguration.java @@ -28,7 +28,7 @@ public class SecurityConfiguration { .formLogin() .loginPage("/login") .permitAll() - .successForwardUrl("/index") + .defaultSuccessUrl("/index") .and() .logout() .permitAll() From 8772eaa67351c29e44db9c391225bb9602af2469 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:28:15 -0400 Subject: [PATCH 007/283] Single and Multiple Partition test. --- apache-kafka-2/pom.xml | 3 +- .../message/ordering/payload/Message.java | 14 +++ .../ordering/MultiplePartitionTest.java | 114 +++++++++++++++++ .../message/ordering/SinglePartitionTest.java | 115 ++++++++++++++++++ 4 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java create mode 100644 apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java diff --git a/apache-kafka-2/pom.xml b/apache-kafka-2/pom.xml index 45b31004b7..d0838a386e 100644 --- a/apache-kafka-2/pom.xml +++ b/apache-kafka-2/pom.xml @@ -60,7 +60,7 @@ com.fasterxml.jackson.core jackson-databind - 2.15.2 + ${jackson.databind.version} @@ -69,6 +69,7 @@ 2.8.0 1.15.3 1.15.3 + 2.15.2 \ No newline at end of file diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java index b185d663d4..317aec699e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -1,5 +1,6 @@ package com.baeldung.kafka.message.ordering.payload; +import javax.swing.*; import java.util.Random; public class Message implements Comparable { @@ -10,6 +11,7 @@ public class Message implements Comparable { } + //Required for Kafka Serialization and Deserialization public Message(long insertPosition, long messageId) { this.insertPosition = insertPosition; this.messageId = messageId; @@ -28,6 +30,18 @@ public class Message implements Comparable { return Long.compare(this.messageId, other.messageId); } + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Message)) { + return false; + } + Message message = (Message) obj; + return this.messageId == message.getMessageId() && this.insertPosition == message.getInsertPosition(); + } + public static long getRandomMessageId() { Random rand = new Random(); return rand.nextInt(1000); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java new file mode 100644 index 0000000000..586c328f79 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java @@ -0,0 +1,114 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import lombok.var; +import org.apache.kafka.clients.admin.*; +import org.apache.kafka.clients.consumer.ConsumerConfig; +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.KafkaFuture; +import org.apache.kafka.common.PartitionInfo; +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; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import static org.junit.jupiter.api.Assertions.*; + +@Testcontainers +public class MultiplePartitionTest { + private static String TOPIC = "multi_partition_topic"; + private static int PARTITIONS = 5; + private static short REPLICATION_FACTOR = 1; + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producerProperties.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put("value.deserializer.serializedClass", Message.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + List topicList = new ArrayList<>(); + NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + topicList.add(newTopic); + CreateTopicsResult result = admin.createTopics(topicList); + KafkaFuture future = result.values().get(TOPIC); + future.whenComplete((voidResult, exception) -> { + if (exception != null) { + System.err.println("Error creating the topic: " + exception.getMessage()); + } else { + System.out.println("Topic created successfully!"); + } + }).get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentMessageList = new ArrayList<>(); + List receivedMessageList = new ArrayList<>(); + for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { + long messageId = Message.getRandomMessageId(); + String key = "Key-" + insertPosition; + Message message = new Message(insertPosition, messageId); + Future future = producer.send(new ProducerRecord<>(TOPIC, key, message)); + sentMessageList.add(message); + RecordMetadata metadata = future.get(); + System.out.println("Partition : " + metadata.partition()); + } + + boolean isOrderMaintained = true; + consumer.subscribe(Collections.singletonList(TOPIC)); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + Message message = record.value(); + receivedMessageList.add(message); + }); + for (int insertPosition = 0; insertPosition <= receivedMessageList.size() - 1; insertPosition++) { + if (isOrderMaintained){ + Message sentMessage = sentMessageList.get(insertPosition); + Message receivedMessage = receivedMessageList.get(insertPosition); + if (!sentMessage.equals(receivedMessage)) { + isOrderMaintained = false; + } + } + } + assertFalse(isOrderMaintained); + } +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java new file mode 100644 index 0000000000..afffbcc28e --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java @@ -0,0 +1,115 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.CreateTopicsResult; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.ConsumerConfig; +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.KafkaFuture; +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; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Testcontainers +public class SinglePartitionTest { + private static String TOPIC = "single_partition_topic"; + private static int PARTITIONS = 1; + private static short REPLICATION_FACTOR = 1; + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + producerProperties.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put("value.deserializer.serializedClass", Message.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + List topicList = new ArrayList<>(); + NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + topicList.add(newTopic); + CreateTopicsResult result = admin.createTopics(topicList); + KafkaFuture future = result.values().get(TOPIC); + future.whenComplete((voidResult, exception) -> { + if (exception != null) { + System.err.println("Error creating the topic: " + exception.getMessage()); + } else { + System.out.println("Topic created successfully!"); + } + }).get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentMessageList = new ArrayList<>(); + List receivedMessageList = new ArrayList<>(); + for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { + long messageId = Message.getRandomMessageId(); + String key = "Key-" + insertPosition; + Message message = new Message(insertPosition, messageId); + ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, key, message); + Future future = producer.send(producerRecord); + sentMessageList.add(message); + RecordMetadata metadata = future.get(); + System.out.println("Partition : " + metadata.partition()); + } + + consumer.subscribe(Collections.singletonList(TOPIC)); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + Message message = record.value(); + receivedMessageList.add(message); + }); + boolean result = true; + for (int count = 0; count <= 9 ; count++) { + Message sentMessage = sentMessageList.get(count); + Message receivedMessage = receivedMessageList.get(count); + if (!sentMessage.equals(receivedMessage) && result){ + result = false; + } + } + assertTrue(result); + } +} From c4aac70277435d53363e2e99f8a26de8d2729585 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:46:35 -0400 Subject: [PATCH 008/283] User Constants instead od repeatative strings --- .../baeldung/kafka/message/ordering/Config.java | 5 +++++ .../message/ordering/MultiplePartitionTest.java | 14 +++++++++----- .../message/ordering/SinglePartitionTest.java | 14 +++++++++----- 3 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java new file mode 100644 index 0000000000..2635e72431 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java @@ -0,0 +1,5 @@ +package com.baeldung.kafka.message.ordering; + +public class Config { + public static final String CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS = "value.deserializer.serializedClass"; +} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java index 586c328f79..5b68544f95 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java @@ -1,6 +1,8 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import lombok.var; import org.apache.kafka.clients.admin.*; import org.apache.kafka.clients.consumer.ConsumerConfig; @@ -12,6 +14,8 @@ import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.RecordMetadata; import org.apache.kafka.common.KafkaFuture; import org.apache.kafka.common.PartitionInfo; +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; @@ -47,15 +51,15 @@ public class MultiplePartitionTest { Properties producerProperties = new Properties(); producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); - producerProperties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - producerProperties.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); Properties consumerProperties = new Properties(); consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); - consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - consumerProperties.put("value.deserializer.serializedClass", Message.class); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java index afffbcc28e..807e21bfa8 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java @@ -1,6 +1,8 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.clients.admin.AdminClientConfig; import org.apache.kafka.clients.admin.CreateTopicsResult; @@ -13,6 +15,8 @@ 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.KafkaFuture; +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; @@ -49,15 +53,15 @@ public class SinglePartitionTest { Properties producerProperties = new Properties(); producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); - producerProperties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - producerProperties.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); Properties consumerProperties = new Properties(); consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); - consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - consumerProperties.put("value.deserializer.serializedClass", Message.class); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); From 1d1aaeedb6eea4201a8a92eade16f2ec62ef588c Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:57:42 -0400 Subject: [PATCH 009/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index bcdf6ceb32..60ae5fc2f8 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -13,7 +13,7 @@ public class ProducerConfigurations { props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("max.in.flight.requests.per.connection", "1"); props.put("batch.size", "16384"); - props.put("linger.ms", "5"); + props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); KafkaProducer producer = new KafkaProducer<>(props); for (int i = 0; i < 10; i++) { From f8ea1db5ccd727c2e06912a04eac3b9de4088341 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:58:27 -0400 Subject: [PATCH 010/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 60ae5fc2f8..566605973c 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -12,7 +12,7 @@ public class ProducerConfigurations { props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("max.in.flight.requests.per.connection", "1"); - props.put("batch.size", "16384"); + props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); KafkaProducer producer = new KafkaProducer<>(props); From 463e45d025682fbd4eecbb73165c460ef9f7ea03 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:58:33 -0400 Subject: [PATCH 011/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 566605973c..c9cef04bbc 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -11,7 +11,7 @@ public class ProducerConfigurations { props.put("bootstrap.servers", "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("max.in.flight.requests.per.connection", "1"); + props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); KafkaProducer producer = new KafkaProducer<>(props); From 836c977fdea79eda47f2e5989709d73f40e5f593 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:58:43 -0400 Subject: [PATCH 012/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index c9cef04bbc..81d91693fe 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -8,7 +8,7 @@ import java.util.Properties; public class ProducerConfigurations { public static void main(String[] args) { Properties props = new Properties(); - props.put("bootstrap.servers", "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); From 540da8c7795ac450793347b927e6c6a800c06c25 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:58:57 -0400 Subject: [PATCH 013/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java Co-authored-by: Liam Williams --- .../message/ordering/serialization/JacksonSerializer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java index fa9d25dd85..2d7432cc7b 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java @@ -3,6 +3,10 @@ package com.baeldung.kafka.message.ordering.serialization; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.kafka.common.serialization.Serializer; +/** + * Configured via {@link org.apache.kafka.clients.producer.ProducerConfig#VALUE_SERIALIZER_CLASS_CONFIG} + */ +@SuppressWarnings("unused") public class JacksonSerializer implements Serializer { private final ObjectMapper objectMapper = new ObjectMapper(); From c3af2facae6cdc5b3a27607eec2d079f1a670d9f Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:59:07 -0400 Subject: [PATCH 014/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java Co-authored-by: Liam Williams --- .../message/ordering/serialization/JacksonDeserializer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 34aa181fcb..f3c8aaf60f 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -4,6 +4,10 @@ import org.apache.kafka.common.serialization.Deserializer; import java.util.Map; +/** + * Configured via {@link org.apache.kafka.clients.consumer.ConsumerConfig#VALUE_DESERIALIZER_CLASS_CONFIG} + */ +@SuppressWarnings("unused") public class JacksonDeserializer implements Deserializer { private final ObjectMapper objectMapper = new ObjectMapper(); private Class tClass; From d31cf69b4d5d2ca8d88cbebf6aee72b84dba96b3 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 15:59:38 -0400 Subject: [PATCH 015/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/MultiPartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index 8b2a49b2b5..0fd20c2ab1 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -11,7 +11,7 @@ public class MultiPartitionProducer { Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { From 857da48e742306babf0579436aa2baf0c3ea5a0c Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:00:04 -0400 Subject: [PATCH 016/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 81d91693fe..ae3f2839c8 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -10,7 +10,7 @@ public class ProducerConfigurations { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); From e35327cade00d1be3bedc513e416dc9de28f177a Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:00:49 -0400 Subject: [PATCH 017/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/MultiPartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index 0fd20c2ab1..04ffdd3336 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -10,7 +10,7 @@ public class MultiPartitionProducer { public static void main(String[] args) { Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); - props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); From 2dd76f7e78bad11206916195f15a81c0f79f9aad Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:01:50 -0400 Subject: [PATCH 018/283] Review comment incorporation --- .../kafka/message/ordering/ProducerConfigurations.java | 1 + .../kafka/message/ordering/payload/Message.java | 3 ++- .../ordering/serialization/JacksonDeserializer.java | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 60ae5fc2f8..2c885b7caa 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -1,6 +1,7 @@ package com.baeldung.kafka.message.ordering; import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerRecord; import java.util.Properties; diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java index 317aec699e..095aeef89a 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -2,6 +2,7 @@ package com.baeldung.kafka.message.ordering.payload; import javax.swing.*; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; public class Message implements Comparable { private long insertPosition; @@ -44,7 +45,7 @@ public class Message implements Comparable { public static long getRandomMessageId() { Random rand = new Random(); - return rand.nextInt(1000); + return ThreadLocalRandom.current().nextInt(1000); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 34aa181fcb..cb0b77e4c0 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -6,10 +6,10 @@ import java.util.Map; public class JacksonDeserializer implements Deserializer { private final ObjectMapper objectMapper = new ObjectMapper(); - private Class tClass; + private Class type; - public JacksonDeserializer(Class tClass) { - this.tClass = tClass; + public JacksonDeserializer(Class type) { + this.type = type; } public JacksonDeserializer() { @@ -18,7 +18,7 @@ public class JacksonDeserializer implements Deserializer { @Override public void configure(Map configs, boolean isKey) { - this.tClass = (Class) configs.get("value.deserializer.serializedClass"); + this.type = (Class) configs.get("value.deserializer.serializedClass"); } @Override @@ -27,7 +27,7 @@ public class JacksonDeserializer implements Deserializer { return null; } try { - return objectMapper.readValue(bytes, tClass); + return objectMapper.readValue(bytes, type); } catch (Exception e) { throw new RuntimeException("Error deserializing value", e); } From 51cf5cee5fe1ec871163291a4e97071c024dcb1d Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:02:15 -0400 Subject: [PATCH 019/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/MultiPartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index 04ffdd3336..b565941fa5 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -9,7 +9,7 @@ import java.util.Properties; public class MultiPartitionProducer { public static void main(String[] args) { Properties props = new Properties(); - props.put("bootstrap.servers", "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); From 9eed20e483f00dde53393c3d0ae541a107a7696c Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:03:11 -0400 Subject: [PATCH 020/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/ExtSeqWithTimeWindowProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index 91c5af716f..59bfb397ec 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -13,7 +13,7 @@ public class ExtSeqWithTimeWindowProducer { Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { From 6da6a92a797d02ac0086c6591d949a58fc148f3b Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:03:28 -0400 Subject: [PATCH 021/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/ExtSeqWithTimeWindowProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index 59bfb397ec..b4b890ffe7 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -12,7 +12,7 @@ public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); - props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); From 576b08076f59695d7286afcdf25145630de2ab1a Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:03:53 -0400 Subject: [PATCH 022/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/ExtSeqWithTimeWindowProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index b4b890ffe7..69f50352ad 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -11,7 +11,7 @@ import java.util.concurrent.atomic.AtomicLong; public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { Properties props = new Properties(); - props.put("bootstrap.servers", "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); From 3c716605b90ddf32311a5459aacab1cf41a55566 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:04:07 -0400 Subject: [PATCH 023/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/SinglePartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index b5366819c5..1610df746c 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -10,7 +10,7 @@ import java.util.Random; public class SinglePartitionProducer { public static void main(String[] args) { Properties props = new Properties(); - props.put("bootstrap.servers", "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); From d408db30f209eda244bb505055b09935822e4ad9 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:05:27 -0400 Subject: [PATCH 024/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/SinglePartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index 1610df746c..03f89b9a55 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -12,7 +12,7 @@ public class SinglePartitionProducer { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); - props.put("value.serializer", "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { From f2a69a8bb11a482237230c7261bcebdb1c87af97 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:07:42 -0400 Subject: [PATCH 025/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ConsumerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java index b18db3ef24..8af4e576ce 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -18,7 +18,7 @@ public class ConsumerConfigurations { props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put("max.poll.records", "500"); props.put("fetch.min.bytes", "1"); - props.put("fetch.max.wait.ms", "500"); + props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); From 89eed31dbd38d7bcc784dfbe99ea13bf1e136788 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:08:05 -0400 Subject: [PATCH 026/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ConsumerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java index 8af4e576ce..9f3d8b9d5c 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -17,7 +17,7 @@ public class ConsumerConfigurations { props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put("max.poll.records", "500"); - props.put("fetch.min.bytes", "1"); + props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, "1"); props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); From d850d6c30cbad40b5245b58f06ac0173ecfb3546 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:08:27 -0400 Subject: [PATCH 027/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ProducerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 5dc917e308..af06fa04de 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -10,7 +10,7 @@ public class ProducerConfigurations { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); From d85a01e524432d27f146d89609d6935d81aef091 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:08:54 -0400 Subject: [PATCH 028/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/SinglePartitionProducer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index 03f89b9a55..869a260da6 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -11,7 +11,7 @@ public class SinglePartitionProducer { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") - props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); KafkaProducer producer = new KafkaProducer<>(props); From 29096686cc7de507162dc4c468a574ce5932a538 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:09:36 -0400 Subject: [PATCH 029/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/ConsumerConfigurations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java index 9f3d8b9d5c..b3faceaa44 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -16,7 +16,7 @@ public class ConsumerConfigurations { props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - props.put("max.poll.records", "500"); + props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "500"); props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, "1"); props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); Consumer consumer = new KafkaConsumer<>(props); From b94d5a1f8a8e2ce146b1d60d96f3ad3319c2976e Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 16:36:33 -0400 Subject: [PATCH 030/283] Incorporated Review Comments --- .../message/ordering/ConsumerConfigurations.java | 8 ++++++-- .../ordering/ExtSeqWithTimeWindowConsumer.java | 12 ++++++------ .../ordering/ExtSeqWithTimeWindowProducer.java | 9 ++++++--- .../message/ordering/MultiPartitionConsumer.java | 12 ++++++++---- .../message/ordering/MultiPartitionProducer.java | 7 +++++-- .../message/ordering/ProducerConfigurations.java | 5 +++-- .../message/ordering/SinglePartitionConsumer.java | 9 ++++++--- .../message/ordering/SinglePartitionProducer.java | 9 ++++++--- .../ordering/serialization/JacksonDeserializer.java | 6 ++++-- 9 files changed, 50 insertions(+), 27 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java index b3faceaa44..15562cfcef 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -1,9 +1,13 @@ package com.baeldung.kafka.message.ordering; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; import java.time.Duration; import java.util.Collections; @@ -14,8 +18,8 @@ public class ConsumerConfigurations { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "500"); props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, "1"); props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index 5b01a86e39..f5a0dbd640 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -1,10 +1,12 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.*; @@ -17,10 +19,10 @@ public class ExtSeqWithTimeWindowConsumer { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put("value.deserializer.serializedClass", Message.class); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); List buffer = new ArrayList<>(); @@ -28,9 +30,7 @@ public class ExtSeqWithTimeWindowConsumer { while (true) { ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { - if (record != null && record.value() != null) { - buffer.add(record.value()); - } + buffer.add(record.value()); }); if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_MS) { processBuffer(buffer); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index 69f50352ad..110015de25 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -1,8 +1,11 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; import java.util.Properties; import java.util.Random; @@ -11,9 +14,9 @@ import java.util.concurrent.atomic.AtomicLong; public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java index f9b0b3b040..542a664745 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -1,10 +1,12 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.Collections; @@ -16,17 +18,19 @@ public class MultiPartitionConsumer { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put("value.deserializer.serializedClass", Message.class); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); while (true) { ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { Message message = record.value(); - System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + if (message != null) { + System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + } }); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index b565941fa5..bf9db58392 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -1,8 +1,11 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; import java.util.Properties; @@ -10,8 +13,8 @@ public class MultiPartitionProducer { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index af06fa04de..0eb563910e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -3,6 +3,7 @@ package com.baeldung.kafka.message.ordering; 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.serialization.StringSerializer; import java.util.Properties; @@ -10,8 +11,8 @@ public class ProducerConfigurations { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java index 932a29c394..e1a449055e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -1,10 +1,13 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; import java.time.Duration; import java.util.Collections; @@ -17,10 +20,10 @@ public class SinglePartitionConsumer { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put("value.deserializer.serializedClass", Message.class); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("single_partition_topic")); while (true) { diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index 869a260da6..c986089841 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -1,8 +1,11 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; import java.util.Properties; import java.util.Random; @@ -10,9 +13,9 @@ import java.util.Random; public class SinglePartitionProducer { public static void main(String[] args) { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092") - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "com.baeldung.kafka.message.ordering.serialization.JacksonSerializer"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 2def07f987..be2b104761 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -1,4 +1,5 @@ package com.baeldung.kafka.message.ordering.serialization; +import com.baeldung.kafka.message.ordering.Config; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.kafka.common.serialization.Deserializer; @@ -22,7 +23,7 @@ public class JacksonDeserializer implements Deserializer { @Override public void configure(Map configs, boolean isKey) { - this.type = (Class) configs.get("value.deserializer.serializedClass"); + this.type = (Class) configs.get(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS); } @Override @@ -33,8 +34,9 @@ public class JacksonDeserializer implements Deserializer { try { return objectMapper.readValue(bytes, type); } catch (Exception e) { - throw new RuntimeException("Error deserializing value", e); + //throw new RuntimeException("Error deserializing value", e); } + return null; } } From 6d4e6886b311ffe28794033bc555e80b274fe40b Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 18:42:20 -0400 Subject: [PATCH 031/283] Renamed Inser position to patition key --- .../ordering/ExtSeqWithTimeWindowConsumer.java | 2 +- .../ordering/ExtSeqWithTimeWindowProducer.java | 6 ++---- .../message/ordering/MultiPartitionConsumer.java | 2 +- .../message/ordering/MultiPartitionProducer.java | 4 ++-- .../message/ordering/SinglePartitionConsumer.java | 3 +-- .../message/ordering/SinglePartitionProducer.java | 5 ++--- .../kafka/message/ordering/payload/Message.java | 14 +++++++------- .../message/ordering/MultiplePartitionTest.java | 2 +- .../message/ordering/SinglePartitionTest.java | 2 +- 9 files changed, 18 insertions(+), 22 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index f5a0dbd640..d342c1a950 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -42,7 +42,7 @@ public class ExtSeqWithTimeWindowConsumer { private static void processBuffer(List buffer) { Collections.sort(buffer); buffer.forEach(message -> { - System.out.println("Processing message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Processing message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index 110015de25..d1480522e5 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -8,8 +8,6 @@ import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.StringSerializer; import java.util.Properties; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { @@ -22,9 +20,9 @@ public class ExtSeqWithTimeWindowProducer { for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { long messageId = Message.getRandomMessageId(); String key = "Key-" + insertPosition; - Message message = new Message(insertPosition, messageId); + Message message = new Message(key, messageId); producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); } producer.close(); System.out.println("ExternalSequencingProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java index 542a664745..4471070f0f 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -29,7 +29,7 @@ public class MultiPartitionConsumer { records.forEach(record -> { Message message = record.value(); if (message != null) { - System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Process message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); } }); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index bf9db58392..04e3dcce0a 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -20,9 +20,9 @@ public class MultiPartitionProducer { for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { long messageId = Message.getRandomMessageId(); String key = "Key-" + insertPosition; - Message message = new Message(insertPosition, messageId); + Message message = new Message(key, messageId); producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java index e1a449055e..b47e4ca3b0 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -7,7 +7,6 @@ import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; import java.time.Duration; import java.util.Collections; @@ -30,7 +29,7 @@ public class SinglePartitionConsumer { ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { Message message = record.value(); - System.out.println("Process message with Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Process message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); }); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index c986089841..d669a0fd69 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -8,7 +8,6 @@ import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.StringSerializer; import java.util.Properties; -import java.util.Random; public class SinglePartitionProducer { public static void main(String[] args) { @@ -21,9 +20,9 @@ public class SinglePartitionProducer { for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { long messageId = Message.getRandomMessageId(); String key = "Key-" + insertPosition; - Message message = new Message(insertPosition, messageId); + Message message = new Message(key, messageId); producer.send(new ProducerRecord<>("single_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getInsertPosition() + ", Message Id: " + message.getMessageId()); + System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java index 095aeef89a..de1e5135da 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -1,11 +1,11 @@ package com.baeldung.kafka.message.ordering.payload; -import javax.swing.*; +import java.util.Objects; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; public class Message implements Comparable { - private long insertPosition; + private String partitionKey; private long messageId; public Message(){ @@ -13,13 +13,13 @@ public class Message implements Comparable { } //Required for Kafka Serialization and Deserialization - public Message(long insertPosition, long messageId) { - this.insertPosition = insertPosition; + public Message(String partitionKey, long messageId) { + this.partitionKey = partitionKey; this.messageId = messageId; } - public long getInsertPosition() { - return insertPosition; + public String getPartitionKey() { + return partitionKey; } public long getMessageId() { @@ -40,7 +40,7 @@ public class Message implements Comparable { return false; } Message message = (Message) obj; - return this.messageId == message.getMessageId() && this.insertPosition == message.getInsertPosition(); + return this.messageId == message.getMessageId() && Objects.equals(this.partitionKey, message.getPartitionKey()); } public static long getRandomMessageId() { diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java index 5b68544f95..aed5f30e9d 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java @@ -90,7 +90,7 @@ public class MultiplePartitionTest { for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { long messageId = Message.getRandomMessageId(); String key = "Key-" + insertPosition; - Message message = new Message(insertPosition, messageId); + Message message = new Message(key, messageId); Future future = producer.send(new ProducerRecord<>(TOPIC, key, message)); sentMessageList.add(message); RecordMetadata metadata = future.get(); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java index 807e21bfa8..5751c8d0e0 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java @@ -92,7 +92,7 @@ public class SinglePartitionTest { for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { long messageId = Message.getRandomMessageId(); String key = "Key-" + insertPosition; - Message message = new Message(insertPosition, messageId); + Message message = new Message(key, messageId); ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, key, message); Future future = producer.send(producerRecord); sentMessageList.add(message); From d1d456e59a6ba378c84021b26e09f05a134be131 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 19:19:01 -0400 Subject: [PATCH 032/283] Removed insertPosition, renamed messageId to applicationIdentifier --- .../ExtSeqWithTimeWindowConsumer.java | 9 ++++--- .../ExtSeqWithTimeWindowProducer.java | 18 ++++++------- .../ordering/MultiPartitionConsumer.java | 5 ++-- .../ordering/MultiPartitionProducer.java | 18 ++++++------- .../ordering/SinglePartitionConsumer.java | 9 ++++--- .../ordering/SinglePartitionProducer.java | 18 ++++++------- .../message/ordering/payload/Message.java | 20 +++++++-------- .../ordering/MultiplePartitionTest.java | 25 ++++++++----------- .../message/ordering/SinglePartitionTest.java | 23 ++++++++--------- 9 files changed, 69 insertions(+), 76 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index d342c1a950..19595d9e95 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -6,20 +6,21 @@ import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.*; public class ExtSeqWithTimeWindowConsumer { - private static final long BUFFER_PERIOD_MS = 5000; + private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); public static void main(String[] args) { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); @@ -32,7 +33,7 @@ public class ExtSeqWithTimeWindowConsumer { records.forEach(record -> { buffer.add(record.value()); }); - if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_MS) { + if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { processBuffer(buffer); lastProcessedTime = System.nanoTime(); } @@ -42,7 +43,7 @@ public class ExtSeqWithTimeWindowConsumer { private static void processBuffer(List buffer) { Collections.sort(buffer); buffer.forEach(message -> { - System.out.println("Processing message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + System.out.println("Processing message with Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index d1480522e5..a20c569159 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -5,7 +5,7 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; +import org.apache.kafka.common.serialization.LongSerializer; import java.util.Properties; @@ -13,16 +13,14 @@ public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - - KafkaProducer producer = new KafkaProducer<>(props); - for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { - long messageId = Message.getRandomMessageId(); - String key = "Key-" + insertPosition; - Message message = new Message(key, messageId); - producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + producer.send(new ProducerRecord<>("multi_partition_topic", partitionKey, message)); + System.out.println("Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); } producer.close(); System.out.println("ExternalSequencingProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java index 4471070f0f..c37c645d31 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -6,6 +6,7 @@ import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; @@ -18,7 +19,7 @@ public class MultiPartitionConsumer { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); @@ -29,7 +30,7 @@ public class MultiPartitionConsumer { records.forEach(record -> { Message message = record.value(); if (message != null) { - System.out.println("Process message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + System.out.println("Process message with Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); } }); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index 04e3dcce0a..81cc5c6af0 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -5,7 +5,7 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; +import org.apache.kafka.common.serialization.LongSerializer; import java.util.Properties; @@ -13,16 +13,14 @@ public class MultiPartitionProducer { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - - KafkaProducer producer = new KafkaProducer<>(props); - for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { - long messageId = Message.getRandomMessageId(); - String key = "Key-" + insertPosition; - Message message = new Message(key, messageId); - producer.send(new ProducerRecord<>("multi_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + producer.send(new ProducerRecord<>("multi_partition_topic", partitionKey, message)); + System.out.println("Partition Key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java index b47e4ca3b0..9f44cd78c6 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -6,6 +6,7 @@ import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; @@ -19,17 +20,17 @@ public class SinglePartitionConsumer { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); - Consumer consumer = new KafkaConsumer<>(props); + Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("single_partition_topic")); while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { Message message = record.value(); - System.out.println("Process message with Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + System.out.println("Process message with Partition Key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); }); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index d669a0fd69..efa6e5b93d 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -5,7 +5,7 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.StringSerializer; +import org.apache.kafka.common.serialization.LongSerializer; import java.util.Properties; @@ -13,16 +13,14 @@ public class SinglePartitionProducer { public static void main(String[] args) { Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - - KafkaProducer producer = new KafkaProducer<>(props); - for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { - long messageId = Message.getRandomMessageId(); - String key = "Key-" + insertPosition; - Message message = new Message(key, messageId); - producer.send(new ProducerRecord<>("single_partition_topic", key, message)); - System.out.println("Insert Position: " + message.getPartitionKey() + ", Message Id: " + message.getMessageId()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + producer.send(new ProducerRecord<>("single_partition_topic", partitionKey, message)); + System.out.println("Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java index de1e5135da..734ecba53d 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -5,30 +5,30 @@ import java.util.Random; import java.util.concurrent.ThreadLocalRandom; public class Message implements Comparable { - private String partitionKey; - private long messageId; + private long partitionKey; + private long applicationIdentifier; public Message(){ } //Required for Kafka Serialization and Deserialization - public Message(String partitionKey, long messageId) { + public Message(long partitionKey, long applicationIdentifier) { this.partitionKey = partitionKey; - this.messageId = messageId; + this.applicationIdentifier = applicationIdentifier; } - public String getPartitionKey() { + public long getPartitionKey() { return partitionKey; } - public long getMessageId() { - return messageId; + public long getApplicationIdentifier() { + return applicationIdentifier; } @Override public int compareTo(Message other) { - return Long.compare(this.messageId, other.messageId); + return Long.compare(this.partitionKey, other.partitionKey); } @Override @@ -40,10 +40,10 @@ public class Message implements Comparable { return false; } Message message = (Message) obj; - return this.messageId == message.getMessageId() && Objects.equals(this.partitionKey, message.getPartitionKey()); + return this.applicationIdentifier == message.getApplicationIdentifier() && Objects.equals(this.partitionKey, message.getPartitionKey()); } - public static long getRandomMessageId() { + public static long getRandomApplicationIdentifier() { Random rand = new Random(); return ThreadLocalRandom.current().nextInt(1000); } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java index aed5f30e9d..ef0a881999 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java @@ -3,7 +3,6 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.Message; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; -import lombok.var; import org.apache.kafka.clients.admin.*; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -13,9 +12,8 @@ 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.KafkaFuture; -import org.apache.kafka.common.PartitionInfo; -import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -36,8 +34,8 @@ public class MultiplePartitionTest { private static int PARTITIONS = 5; private static short REPLICATION_FACTOR = 1; private static Admin admin; - private static KafkaProducer producer; - private static KafkaConsumer consumer; + private static KafkaProducer producer; + private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); @@ -51,12 +49,12 @@ public class MultiplePartitionTest { 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.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.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.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); @@ -87,11 +85,10 @@ public class MultiplePartitionTest { void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentMessageList = new ArrayList<>(); List receivedMessageList = new ArrayList<>(); - for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { - long messageId = Message.getRandomMessageId(); - String key = "Key-" + insertPosition; - Message message = new Message(key, messageId); - Future future = producer.send(new ProducerRecord<>(TOPIC, key, message)); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + Future future = producer.send(new ProducerRecord<>(TOPIC, partitionKey, message)); sentMessageList.add(message); RecordMetadata metadata = future.get(); System.out.println("Partition : " + metadata.partition()); @@ -99,7 +96,7 @@ public class MultiplePartitionTest { boolean isOrderMaintained = true; consumer.subscribe(Collections.singletonList(TOPIC)); - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { Message message = record.value(); receivedMessageList.add(message); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java index 5751c8d0e0..350a28e7c1 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java @@ -15,8 +15,8 @@ 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.KafkaFuture; -import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -36,8 +36,8 @@ public class SinglePartitionTest { private static int PARTITIONS = 1; private static short REPLICATION_FACTOR = 1; private static Admin admin; - private static KafkaProducer producer; - private static KafkaConsumer consumer; + private static KafkaProducer producer; + private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); @@ -53,12 +53,12 @@ public class SinglePartitionTest { 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.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.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.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); @@ -89,11 +89,10 @@ public class SinglePartitionTest { void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentMessageList = new ArrayList<>(); List receivedMessageList = new ArrayList<>(); - for (long insertPosition = 1; insertPosition <= 10 ; insertPosition++) { - long messageId = Message.getRandomMessageId(); - String key = "Key-" + insertPosition; - Message message = new Message(key, messageId); - ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, key, message); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, partitionKey, message); Future future = producer.send(producerRecord); sentMessageList.add(message); RecordMetadata metadata = future.get(); @@ -101,7 +100,7 @@ public class SinglePartitionTest { } consumer.subscribe(Collections.singletonList(TOPIC)); - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { Message message = record.value(); receivedMessageList.add(message); From 7c40b82bf9fb27130ff0c8b97a0092616054fe7d Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 15 Oct 2023 19:30:29 -0400 Subject: [PATCH 033/283] Build Failure - Priority:3 Unit test class names need to end in UnitTest, integration tests with IntegrationTest, etc. --- ...PartitionTest.java => MultiplePartitionIntegrationTest.java} | 2 +- ...lePartitionTest.java => SinglePartitionIntegrationTest.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{MultiplePartitionTest.java => MultiplePartitionIntegrationTest.java} (99%) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{SinglePartitionTest.java => SinglePartitionIntegrationTest.java} (99%) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java similarity index 99% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index ef0a881999..c948effd70 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -29,7 +29,7 @@ import java.util.concurrent.Future; import static org.junit.jupiter.api.Assertions.*; @Testcontainers -public class MultiplePartitionTest { +public class MultiplePartitionIntegrationTest { private static String TOPIC = "multi_partition_topic"; private static int PARTITIONS = 5; private static short REPLICATION_FACTOR = 1; diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java similarity index 99% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 350a28e7c1..87b7d07431 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -31,7 +31,7 @@ import java.util.concurrent.Future; import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers -public class SinglePartitionTest { +public class SinglePartitionIntegrationTest { private static String TOPIC = "single_partition_topic"; private static int PARTITIONS = 1; private static short REPLICATION_FACTOR = 1; From baaef6bcf3599c79d90cf8e6fc9f96df59c47e4d Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Mon, 16 Oct 2023 19:50:02 -0400 Subject: [PATCH 034/283] Added tests for External Sequence number with Time Window --- .../ExtSeqWithTimeWindowConsumer.java | 6 +- .../ExtSeqWithTimeWindowProducer.java | 1 + .../message/ordering/payload/Message.java | 12 +- .../ExtSeqWithTimeWindowIntegrationTest.java | 138 ++++++++++++++++++ 4 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index 19595d9e95..cd424178ae 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -24,12 +24,12 @@ public class ExtSeqWithTimeWindowConsumer { props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); - Consumer consumer = new KafkaConsumer<>(props); + Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { buffer.add(record.value()); }); @@ -43,7 +43,7 @@ public class ExtSeqWithTimeWindowConsumer { private static void processBuffer(List buffer) { Collections.sort(buffer); buffer.forEach(message -> { - System.out.println("Processing message with Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + System.out.println("Processing message with Global Sequence number: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index a20c569159..99e05990cb 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -19,6 +19,7 @@ public class ExtSeqWithTimeWindowProducer { for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { long applicationIdentifier = Message.getRandomApplicationIdentifier(); Message message = new Message(partitionKey, applicationIdentifier); + message.setGlobalSequenceNumber(partitionKey); producer.send(new ProducerRecord<>("multi_partition_topic", partitionKey, message)); System.out.println("Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java index 734ecba53d..694d84f9d8 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java @@ -8,6 +8,8 @@ public class Message implements Comparable { private long partitionKey; private long applicationIdentifier; + private long globalSequenceNumber; + public Message(){ } @@ -26,9 +28,17 @@ public class Message implements Comparable { return applicationIdentifier; } + public long getGlobalSequenceNumber() { + return globalSequenceNumber; + } + + public void setGlobalSequenceNumber(long globalSequenceNumber) { + this.globalSequenceNumber = globalSequenceNumber; + } + @Override public int compareTo(Message other) { - return Long.compare(this.partitionKey, other.partitionKey); + return Long.compare(this.globalSequenceNumber, other.globalSequenceNumber); } @Override diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java new file mode 100644 index 0000000000..a01c230026 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -0,0 +1,138 @@ +package com.baeldung.kafka.message.ordering; + +import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; +import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; +import org.apache.kafka.clients.admin.*; +import org.apache.kafka.clients.consumer.ConsumerConfig; +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.KafkaFuture; +import org.apache.kafka.common.serialization.LongDeserializer; +import org.apache.kafka.common.serialization.LongSerializer; +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; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import static org.junit.jupiter.api.Assertions.*; + +@Testcontainers +public class ExtSeqWithTimeWindowIntegrationTest { + private static String TOPIC = "multi_partition_topic"; + private static int PARTITIONS = 5; + private static short REPLICATION_FACTOR = 1; + private static Admin admin; + private static KafkaProducer producer; + private static KafkaConsumer consumer; + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + + private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + + @BeforeAll + static void setup() throws ExecutionException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); + + Properties consumerProperties = new Properties(); + consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); + consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); + consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + admin = Admin.create(adminProperties); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + List topicList = new ArrayList<>(); + NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + topicList.add(newTopic); + CreateTopicsResult result = admin.createTopics(topicList); + KafkaFuture future = result.values().get(TOPIC); + future.whenComplete((voidResult, exception) -> { + if (exception != null) { + System.err.println("Error creating the topic: " + exception.getMessage()); + } else { + System.out.println("Topic created successfully!"); + } + }).get(); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void givenMultiplePartitions_whenPublishedToKafkaAndConsumedWithExtSeqNumberAndTimeWindow_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { + List sentMessageList = new ArrayList<>(); + List receivedMessageList = new ArrayList<>(); + for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { + long applicationIdentifier = Message.getRandomApplicationIdentifier(); + Message message = new Message(partitionKey, applicationIdentifier); + message.setGlobalSequenceNumber(partitionKey); + Future future = producer.send(new ProducerRecord<>(TOPIC, partitionKey, message)); + sentMessageList.add(message); + RecordMetadata metadata = future.get(); + System.out.println("Partition : " + metadata.partition()); + } + + boolean isOrderMaintained = true; + consumer.subscribe(Collections.singletonList(TOPIC)); + List buffer = new ArrayList<>(); + long lastProcessedTime = System.nanoTime(); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + buffer.add(record.value()); + }); + while (buffer.size() > 0) { + if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { + processBuffer(buffer, receivedMessageList); + lastProcessedTime = System.nanoTime(); + } + records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + records.forEach(record -> { + buffer.add(record.value()); + }); + } + for (int insertPosition = 0; insertPosition <= receivedMessageList.size() - 1; insertPosition++) { + if (isOrderMaintained){ + Message sentMessage = sentMessageList.get(insertPosition); + Message receivedMessage = receivedMessageList.get(insertPosition); + if (!sentMessage.equals(receivedMessage)) { + isOrderMaintained = false; + } + } + } + assertTrue(isOrderMaintained); + } + + private static void processBuffer(List buffer, List receivedMessageList) { + Collections.sort(buffer); + buffer.forEach(message -> { + receivedMessageList.add(message); + System.out.println("Processing message with Global Sequence number: " + message.getGlobalSequenceNumber() + ", Application Identifier: " + message.getApplicationIdentifier()); + }); + buffer.clear(); + } +} From 5b936c47a0c9a4cbf1ad4f8b695d47d7b76ca5be Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Tue, 17 Oct 2023 19:39:27 -0400 Subject: [PATCH 035/283] Message to User Event Rename --- .../ExtSeqWithTimeWindowConsumer.java | 17 +++--- .../ExtSeqWithTimeWindowProducer.java | 17 +++--- .../ordering/MultiPartitionConsumer.java | 15 +++-- .../ordering/MultiPartitionProducer.java | 15 ++--- .../ordering/SinglePartitionConsumer.java | 13 ++-- .../ordering/SinglePartitionProducer.java | 16 ++--- .../message/ordering/payload/Message.java | 61 ------------------- .../message/ordering/payload/UserEvent.java | 58 ++++++++++++++++++ .../ExtSeqWithTimeWindowIntegrationTest.java | 46 +++++++------- .../MultiplePartitionIntegrationTest.java | 36 +++++------ .../SinglePartitionIntegrationTest.java | 34 +++++------ 11 files changed, 163 insertions(+), 165 deletions(-) delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java create mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index cd424178ae..639a980462 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -1,13 +1,12 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.LongDeserializer; -import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.*; @@ -23,13 +22,13 @@ public class ExtSeqWithTimeWindowConsumer { props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); - Consumer consumer = new KafkaConsumer<>(props); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); - List buffer = new ArrayList<>(); + List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { buffer.add(record.value()); }); @@ -40,10 +39,10 @@ public class ExtSeqWithTimeWindowConsumer { } } - private static void processBuffer(List buffer) { + private static void processBuffer(List buffer) { Collections.sort(buffer); - buffer.forEach(message -> { - System.out.println("Processing message with Global Sequence number: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + buffer.forEach(userEvent -> { + System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", event nano time : " + userEvent.getEventNanoTime()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index 99e05990cb..c18e35b351 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -1,6 +1,6 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerConfig; @@ -8,6 +8,7 @@ import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.LongSerializer; import java.util.Properties; +import java.util.UUID; public class ExtSeqWithTimeWindowProducer { public static void main(String[] args) { @@ -15,13 +16,13 @@ public class ExtSeqWithTimeWindowProducer { props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - message.setGlobalSequenceNumber(partitionKey); - producer.send(new ProducerRecord<>("multi_partition_topic", partitionKey, message)); - System.out.println("Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long sequenceNumber = 1; sequenceNumber <= 10 ; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + userEvent.setGlobalSequenceNumber(sequenceNumber); + producer.send(new ProducerRecord<>("multi_partition_topic", sequenceNumber, userEvent)); + System.out.println("User Event Nano time : " + userEvent.getEventNanoTime() + ", User Event Id: " + userEvent.getUserEventId()); } producer.close(); System.out.println("ExternalSequencingProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java index c37c645d31..e738832425 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -1,13 +1,12 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.LongDeserializer; -import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.Collections; @@ -22,15 +21,15 @@ public class MultiPartitionConsumer { props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); - Consumer consumer = new KafkaConsumer<>(props); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("multi_partition_topic")); while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { - Message message = record.value(); - if (message != null) { - System.out.println("Process message with Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + UserEvent userEvent = record.value(); + if (userEvent != null) { + System.out.println("Process message with event nano time : " + userEvent.getEventNanoTime() + ", Event ID: " + userEvent.getUserEventId()); } }); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index 81cc5c6af0..db02c87bbe 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -1,6 +1,6 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerConfig; @@ -8,6 +8,7 @@ import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.LongSerializer; import java.util.Properties; +import java.util.UUID; public class MultiPartitionProducer { public static void main(String[] args) { @@ -15,12 +16,12 @@ public class MultiPartitionProducer { props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - producer.send(new ProducerRecord<>("multi_partition_topic", partitionKey, message)); - System.out.println("Partition Key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long count = 1; count <= 10 ; count++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + producer.send(new ProducerRecord<>("multi_partition_topic", count, userEvent)); + System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java index 9f44cd78c6..5f5ce86924 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -1,13 +1,12 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.common.serialization.LongDeserializer; -import org.apache.kafka.common.serialization.StringDeserializer; import java.time.Duration; import java.util.Collections; @@ -23,14 +22,14 @@ public class SinglePartitionConsumer { props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); - Consumer consumer = new KafkaConsumer<>(props); + props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + Consumer consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList("single_partition_topic")); while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { - Message message = record.value(); - System.out.println("Process message with Partition Key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + UserEvent userEvent = record.value(); + System.out.println("Process message with event nano time : " + userEvent.getEventNanoTime() + ", Event ID: " + userEvent.getUserEventId()); }); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index efa6e5b93d..2a7719e34f 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -1,13 +1,15 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.LongSerializer; +import java.time.Instant; import java.util.Properties; +import java.util.UUID; public class SinglePartitionProducer { public static void main(String[] args) { @@ -15,12 +17,12 @@ public class SinglePartitionProducer { props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - producer.send(new ProducerRecord<>("single_partition_topic", partitionKey, message)); - System.out.println("Partition key: " + message.getPartitionKey() + ", Application Identifier: " + message.getApplicationIdentifier()); + KafkaProducer producer = new KafkaProducer<>(props); + for (long count = 1; count <= 10 ; count++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + producer.send(new ProducerRecord<>("single_partition_topic", count, userEvent)); + System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java deleted file mode 100644 index 694d84f9d8..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/Message.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.baeldung.kafka.message.ordering.payload; - -import java.util.Objects; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -public class Message implements Comparable { - private long partitionKey; - private long applicationIdentifier; - - private long globalSequenceNumber; - - public Message(){ - - } - - //Required for Kafka Serialization and Deserialization - public Message(long partitionKey, long applicationIdentifier) { - this.partitionKey = partitionKey; - this.applicationIdentifier = applicationIdentifier; - } - - public long getPartitionKey() { - return partitionKey; - } - - public long getApplicationIdentifier() { - return applicationIdentifier; - } - - public long getGlobalSequenceNumber() { - return globalSequenceNumber; - } - - public void setGlobalSequenceNumber(long globalSequenceNumber) { - this.globalSequenceNumber = globalSequenceNumber; - } - - @Override - public int compareTo(Message other) { - return Long.compare(this.globalSequenceNumber, other.globalSequenceNumber); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Message)) { - return false; - } - Message message = (Message) obj; - return this.applicationIdentifier == message.getApplicationIdentifier() && Objects.equals(this.partitionKey, message.getPartitionKey()); - } - - public static long getRandomApplicationIdentifier() { - Random rand = new Random(); - return ThreadLocalRandom.current().nextInt(1000); - } -} - diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java new file mode 100644 index 0000000000..0c4018e624 --- /dev/null +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -0,0 +1,58 @@ +package com.baeldung.kafka.message.ordering.payload; + +import java.util.Objects; +public class UserEvent implements Comparable { + private String userEventId; + + private long eventNanoTime; + + private long globalSequenceNumber; + + public UserEvent(){ + + } + + //Required for Kafka Serialization and Deserialization + public UserEvent(String userEventId) { + this.userEventId = userEventId; + } + + public String getUserEventId() { + return userEventId; + } + + public long getEventNanoTime() { + return eventNanoTime; + } + + public void setEventNanoTime(long eventNanoTime) { + this.eventNanoTime = eventNanoTime; + } + + public long getGlobalSequenceNumber() { + return globalSequenceNumber; + } + + public void setGlobalSequenceNumber(long globalSequenceNumber) { + this.globalSequenceNumber = globalSequenceNumber; + } + + @Override + public int compareTo(UserEvent other) { + return Long.compare(this.globalSequenceNumber, other.globalSequenceNumber); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UserEvent)) { + return false; + } + UserEvent userEvent = (UserEvent) obj; + return Objects.equals(this.userEventId, userEvent.getUserEventId()) + && userEvent.getEventNanoTime() == this.eventNanoTime; + } +} + diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index a01c230026..5f540d5b50 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.admin.*; @@ -34,8 +34,8 @@ public class ExtSeqWithTimeWindowIntegrationTest { private static int PARTITIONS = 5; private static short REPLICATION_FACTOR = 1; private static Admin admin; - private static KafkaProducer producer; - private static KafkaConsumer consumer; + private static KafkaProducer producer; + private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds @@ -59,7 +59,7 @@ public class ExtSeqWithTimeWindowIntegrationTest { consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); @@ -85,29 +85,29 @@ public class ExtSeqWithTimeWindowIntegrationTest { @Test void givenMultiplePartitions_whenPublishedToKafkaAndConsumedWithExtSeqNumberAndTimeWindow_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { - List sentMessageList = new ArrayList<>(); - List receivedMessageList = new ArrayList<>(); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - message.setGlobalSequenceNumber(partitionKey); - Future future = producer.send(new ProducerRecord<>(TOPIC, partitionKey, message)); - sentMessageList.add(message); + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long sequenceNumber = 1; sequenceNumber <= 10 ; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + userEvent.setGlobalSequenceNumber(sequenceNumber); + Future future = producer.send(new ProducerRecord<>(TOPIC, sequenceNumber, userEvent)); + sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); System.out.println("Partition : " + metadata.partition()); } boolean isOrderMaintained = true; consumer.subscribe(Collections.singletonList(TOPIC)); - List buffer = new ArrayList<>(); + List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { buffer.add(record.value()); }); while (buffer.size() > 0) { if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { - processBuffer(buffer, receivedMessageList); + processBuffer(buffer, receivedUserEventList); lastProcessedTime = System.nanoTime(); } records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); @@ -115,11 +115,11 @@ public class ExtSeqWithTimeWindowIntegrationTest { buffer.add(record.value()); }); } - for (int insertPosition = 0; insertPosition <= receivedMessageList.size() - 1; insertPosition++) { + for (int insertPosition = 0; insertPosition <= receivedUserEventList.size() - 1; insertPosition++) { if (isOrderMaintained){ - Message sentMessage = sentMessageList.get(insertPosition); - Message receivedMessage = receivedMessageList.get(insertPosition); - if (!sentMessage.equals(receivedMessage)) { + UserEvent sentUserEvent = sentUserEventList.get(insertPosition); + UserEvent receivedUserEvent = receivedUserEventList.get(insertPosition); + if (!sentUserEvent.equals(receivedUserEvent)) { isOrderMaintained = false; } } @@ -127,11 +127,11 @@ public class ExtSeqWithTimeWindowIntegrationTest { assertTrue(isOrderMaintained); } - private static void processBuffer(List buffer, List receivedMessageList) { + private static void processBuffer(List buffer, List receivedUserEventList) { Collections.sort(buffer); - buffer.forEach(message -> { - receivedMessageList.add(message); - System.out.println("Processing message with Global Sequence number: " + message.getGlobalSequenceNumber() + ", Application Identifier: " + message.getApplicationIdentifier()); + buffer.forEach(userEvent -> { + receivedUserEventList.add(userEvent); + System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index c948effd70..d4b88ad06f 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.admin.*; @@ -34,8 +34,8 @@ public class MultiplePartitionIntegrationTest { private static int PARTITIONS = 5; private static short REPLICATION_FACTOR = 1; private static Admin admin; - private static KafkaProducer producer; - private static KafkaConsumer consumer; + private static KafkaProducer producer; + private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); @@ -57,7 +57,7 @@ public class MultiplePartitionIntegrationTest { consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); @@ -83,29 +83,29 @@ public class MultiplePartitionIntegrationTest { @Test void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { - List sentMessageList = new ArrayList<>(); - List receivedMessageList = new ArrayList<>(); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - Future future = producer.send(new ProducerRecord<>(TOPIC, partitionKey, message)); - sentMessageList.add(message); + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long count = 1; count <= 10 ; count++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + Future future = producer.send(new ProducerRecord<>(TOPIC, count, userEvent)); + sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); System.out.println("Partition : " + metadata.partition()); } boolean isOrderMaintained = true; consumer.subscribe(Collections.singletonList(TOPIC)); - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { - Message message = record.value(); - receivedMessageList.add(message); + UserEvent userEvent = record.value(); + receivedUserEventList.add(userEvent); }); - for (int insertPosition = 0; insertPosition <= receivedMessageList.size() - 1; insertPosition++) { + for (int insertPosition = 0; insertPosition <= receivedUserEventList.size() - 1; insertPosition++) { if (isOrderMaintained){ - Message sentMessage = sentMessageList.get(insertPosition); - Message receivedMessage = receivedMessageList.get(insertPosition); - if (!sentMessage.equals(receivedMessage)) { + UserEvent sentUserEvent = sentUserEventList.get(insertPosition); + UserEvent receivedUserEvent = receivedUserEventList.get(insertPosition); + if (!sentUserEvent.equals(receivedUserEvent)) { isOrderMaintained = false; } } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 87b7d07431..b41dc67686 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.message.ordering.payload.Message; +import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.admin.Admin; @@ -36,8 +36,8 @@ public class SinglePartitionIntegrationTest { private static int PARTITIONS = 1; private static short REPLICATION_FACTOR = 1; private static Admin admin; - private static KafkaProducer producer; - private static KafkaConsumer consumer; + private static KafkaProducer producer; + private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); @@ -61,7 +61,7 @@ public class SinglePartitionIntegrationTest { consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, Message.class); + consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); @@ -87,29 +87,29 @@ public class SinglePartitionIntegrationTest { @Test void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { - List sentMessageList = new ArrayList<>(); - List receivedMessageList = new ArrayList<>(); - for (long partitionKey = 1; partitionKey <= 10 ; partitionKey++) { - long applicationIdentifier = Message.getRandomApplicationIdentifier(); - Message message = new Message(partitionKey, applicationIdentifier); - ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, partitionKey, message); + List sentUserEventList = new ArrayList<>(); + List receivedUserEventList = new ArrayList<>(); + for (long count = 1; count <= 10 ; count++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setEventNanoTime(System.nanoTime()); + ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, userEvent); Future future = producer.send(producerRecord); - sentMessageList.add(message); + sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); System.out.println("Partition : " + metadata.partition()); } consumer.subscribe(Collections.singletonList(TOPIC)); - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); + ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { - Message message = record.value(); - receivedMessageList.add(message); + UserEvent userEvent = record.value(); + receivedUserEventList.add(userEvent); }); boolean result = true; for (int count = 0; count <= 9 ; count++) { - Message sentMessage = sentMessageList.get(count); - Message receivedMessage = receivedMessageList.get(count); - if (!sentMessage.equals(receivedMessage) && result){ + UserEvent sentUserEvent = sentUserEventList.get(count); + UserEvent receivedUserEvent = receivedUserEventList.get(count); + if (!sentUserEvent.equals(receivedUserEvent) && result){ result = false; } } From 1071a071706b8ed306153628d9610a91cf4de82a Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Thu, 19 Oct 2023 19:33:27 +0530 Subject: [PATCH 036/283] JAVA-18764: Changes made for updating the pkg --- .../cassecuredapp/CasSecuredApplication.java | 15 +++------------ .../baeldung/cassecuredapp/UserRepository.java | 15 --------------- .../CasUserDetailsService.java} | 18 ++++++++++-------- .../{Users.java => user/User.java} | 4 ++-- .../cassecuredapp/user/UserRepository.java | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 37 deletions(-) delete mode 100644 security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java rename security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/{MyUserDetailsService.java => service/CasUserDetailsService.java} (63%) rename security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/{Users.java => user/User.java} (91%) create mode 100644 security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java index 9293a3e00f..84bbd2ace4 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java @@ -1,30 +1,21 @@ package com.baeldung.cassecuredapp; import org.jasig.cas.client.session.SingleSignOutFilter; -import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; import org.jasig.cas.client.validation.Cas30ServiceTicketValidator; import org.jasig.cas.client.validation.TicketValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.context.event.EventListener; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.cas.ServiceProperties; import org.springframework.security.cas.authentication.CasAuthenticationProvider; -import org.springframework.security.cas.web.CasAuthenticationEntryPoint; import org.springframework.security.cas.web.CasAuthenticationFilter; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import javax.servlet.http.HttpSessionEvent; +import com.baeldung.cassecuredapp.service.CasUserDetailsService; @SpringBootApplication public class CasSecuredApplication { @@ -61,8 +52,8 @@ public class CasSecuredApplication { } @Bean - public MyUserDetailsService getUser(){ - return new MyUserDetailsService(); + public CasUserDetailsService getUser(){ + return new CasUserDetailsService(); } @Bean public CasAuthenticationProvider casAuthenticationProvider( diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java deleted file mode 100644 index 366329a3fb..0000000000 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/UserRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.cassecuredapp; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -@Repository -public interface UserRepository extends CrudRepository { - - Users findByEmail(@Param("email") String email); - -} diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java similarity index 63% rename from security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java rename to security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java index 35c83bfd75..ac4fef1ff0 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/MyUserDetailsService.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java @@ -1,15 +1,17 @@ -package com.baeldung.cassecuredapp; +package com.baeldung.cassecuredapp.service; import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; -public class MyUserDetailsService implements UserDetailsService { +import com.baeldung.cassecuredapp.user.User; +import com.baeldung.cassecuredapp.user.UserRepository; + +public class CasUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @@ -17,18 +19,18 @@ public class MyUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // Get the user from the database. - Users users = getUserFromDatabase(username); + User user = getUserFromDatabase(username); // Create a UserDetails object. - UserDetails userDetails = new User( - users.getEmail(), - users.getPassword(), + UserDetails userDetails = new org.springframework.security.core.userdetails.User( + user.getEmail(), + user.getPassword(), Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN"))); return userDetails; } - private Users getUserFromDatabase(String username) { + private User getUserFromDatabase(String username) { return userRepository.findByEmail(username); } } diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java similarity index 91% rename from security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java rename to security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java index 4e775e80e3..1dddc11458 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/Users.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java @@ -1,11 +1,11 @@ -package com.baeldung.cassecuredapp; +package com.baeldung.cassecuredapp.user; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity -public class Users { +public class User { @Id private Long id; diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java new file mode 100644 index 0000000000..0481fabb06 --- /dev/null +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.cassecuredapp.user; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.baeldung.cassecuredapp.user.User; + +@Repository +public interface UserRepository extends CrudRepository { + + User findByEmail(@Param("email") String email); + +} From a16aa0ee61b10cfce6f78ff0146bbedbabd43a90 Mon Sep 17 00:00:00 2001 From: Vladyslav Chernov Date: Fri, 20 Oct 2023 15:17:36 -0700 Subject: [PATCH 037/283] BAEL-5755: remove comments --- .../main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java index d2acafc881..99e5c7c0cb 100644 --- a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java +++ b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java @@ -51,7 +51,6 @@ public class Xml2CsvExample { try (InputStream in = Files.newInputStream(Paths.get(xmlFilePath)); BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) { - // Write header to CSV writer.write("bookstore_id,book_id,category,title,author_id,author_name,price\n"); XMLStreamReader reader = inputFactory.createXMLStreamReader(in); @@ -67,7 +66,7 @@ public class Xml2CsvExample { case XMLStreamConstants.START_ELEMENT: currentElement = reader.getLocalName(); if ("Bookstore".equals(currentElement)) { - bookstoreInfo.setLength(0); // clear previous bookstore info + bookstoreInfo.setLength(0); bookstoreInfo.append(reader.getAttributeValue(null, "id")) .append(","); } @@ -94,12 +93,10 @@ public class Xml2CsvExample { case XMLStreamConstants.END_ELEMENT: if ("Book".equals(reader.getLocalName())) { - // remove the last comma and add a newline csvRow.setLength(csvRow.length() - 1); csvRow.append("\n"); writer.write(csvRow.toString()); - // Reset the StringBuilder for the next row csvRow.setLength(0); } break; From 199df44c7f2978ed766273dd2bb17fce66ad0531 Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Mon, 23 Oct 2023 16:11:03 +0530 Subject: [PATCH 038/283] JAVA-18764: Changes made for updating the code --- .../cassecuredapp/CasSecuredApplication.java | 9 ++++++--- .../service/CasUserDetailsService.java | 13 +++++++------ .../cassecuredapp/user/{User.java => CasUser.java} | 2 +- .../baeldung/cassecuredapp/user/UserRepository.java | 6 ++---- .../src/main/resources/application.properties | 10 +++++----- 5 files changed, 21 insertions(+), 19 deletions(-) rename security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/{User.java => CasUser.java} (96%) diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java index 84bbd2ace4..f78d7a45d5 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredApplication.java @@ -12,6 +12,8 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.cas.ServiceProperties; import org.springframework.security.cas.authentication.CasAuthenticationProvider; import org.springframework.security.cas.web.CasAuthenticationFilter; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; @@ -62,10 +64,11 @@ public class CasSecuredApplication { CasAuthenticationProvider provider = new CasAuthenticationProvider(); provider.setServiceProperties(serviceProperties); provider.setTicketValidator(ticketValidator); - /* provider.setUserDetailsService( + provider.setUserDetailsService( s -> new User("casuser", "Mellon", true, true, true, true, - AuthorityUtils.createAuthorityList("ROLE_ADMIN")));*/ - provider.setUserDetailsService(getUser()); + AuthorityUtils.createAuthorityList("ROLE_ADMIN"))); + //For Authentication with a Database-backed UserDetailsService + //provider.setUserDetailsService(getUser()); provider.setKey("CAS_PROVIDER_LOCALHOST_8900"); return provider; } diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java index ac4fef1ff0..801f5726b7 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/service/CasUserDetailsService.java @@ -4,11 +4,12 @@ import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; -import com.baeldung.cassecuredapp.user.User; +import com.baeldung.cassecuredapp.user.CasUser; import com.baeldung.cassecuredapp.user.UserRepository; public class CasUserDetailsService implements UserDetailsService { @@ -19,18 +20,18 @@ public class CasUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // Get the user from the database. - User user = getUserFromDatabase(username); + CasUser casUser = getUserFromDatabase(username); // Create a UserDetails object. - UserDetails userDetails = new org.springframework.security.core.userdetails.User( - user.getEmail(), - user.getPassword(), + UserDetails userDetails = new User( + casUser.getEmail(), + casUser.getPassword(), Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN"))); return userDetails; } - private User getUserFromDatabase(String username) { + private CasUser getUserFromDatabase(String username) { return userRepository.findByEmail(username); } } diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java similarity index 96% rename from security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java rename to security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java index 1dddc11458..2bf96d0994 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/User.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/CasUser.java @@ -5,7 +5,7 @@ import javax.persistence.Entity; import javax.persistence.Id; @Entity -public class User { +public class CasUser { @Id private Long id; diff --git a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java index 0481fabb06..623ccf2e38 100644 --- a/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java +++ b/security-modules/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/user/UserRepository.java @@ -4,11 +4,9 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import com.baeldung.cassecuredapp.user.User; - @Repository -public interface UserRepository extends CrudRepository { +public interface UserRepository extends CrudRepository { - User findByEmail(@Param("email") String email); + CasUser findByEmail(@Param("email") String email); } diff --git a/security-modules/cas/cas-secured-app/src/main/resources/application.properties b/security-modules/cas/cas-secured-app/src/main/resources/application.properties index fa13527982..5c93c67ff1 100644 --- a/security-modules/cas/cas-secured-app/src/main/resources/application.properties +++ b/security-modules/cas/cas-secured-app/src/main/resources/application.properties @@ -1,8 +1,8 @@ server.port=8900 spring.freemarker.suffix=.ftl -spring.jpa.generate-ddl=false -spring.datasource.url= jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC -spring.datasource.username=root -spring.datasource.password=root1234 -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver \ No newline at end of file +#spring.jpa.generate-ddl=false +#spring.datasource.url= jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +#spring.datasource.username=root +#spring.datasource.password=root +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver \ No newline at end of file From d2cd902965cc8968628185b57f5f31e0de94724c Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Mon, 23 Oct 2023 16:12:35 +0530 Subject: [PATCH 039/283] JAVA-18764: Update article "CAS SSO with Spring Security" --- .../src/main/resources/application.yml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/security-modules/cas/cas-server/src/main/resources/application.yml b/security-modules/cas/cas-server/src/main/resources/application.yml index 0fd72c539d..a49e86dd09 100644 --- a/security-modules/cas/cas-server/src/main/resources/application.yml +++ b/security-modules/cas/cas-server/src/main/resources/application.yml @@ -8,19 +8,19 @@ server: spring: main: allow-bean-definition-overriding: true -cas: - authn: - accept: - users: - jdbc: - query[0]: - sql: SELECT * FROM users WHERE email = ? - url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC - dialect: org.hibernate.dialect.MySQLDialect - user: root - password: root1234 - ddlAuto: none - driverClass: com.mysql.cj.jdbc.Driver - fieldPassword: password - passwordEncoder: - type: NONE +#cas: +# authn: +# accept: +# users: +# jdbc: +# query[0]: +# sql: SELECT * FROM users WHERE email = ? +# url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +# dialect: org.hibernate.dialect.MySQLDialect +# user: root +# password: root +# ddlAuto: none +# driverClass: com.mysql.cj.jdbc.Driver +# fieldPassword: password +# passwordEncoder: +# type: NONE From bb9a96d9b36c5806a0ace5042d3f9df50e6c6673 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Fri, 27 Oct 2023 22:48:52 +0530 Subject: [PATCH 040/283] JAVA-26380 Change parent of spring-security-modules- Check build failures --- spring-security-modules/pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index ed8279c5f7..1b3db18b84 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -10,8 +10,9 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 From dc6b248d9d31785226c255dc6f96495b2eb34e61 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 28 Oct 2023 12:26:06 +0530 Subject: [PATCH 041/283] JAVA-26280 Improve libraries-testing module build time --- libraries-testing/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries-testing/pom.xml b/libraries-testing/pom.xml index 2c7f231fdc..8db9e4e5c5 100644 --- a/libraries-testing/pom.xml +++ b/libraries-testing/pom.xml @@ -213,7 +213,7 @@ 1.9.9 1.46.0 1.9.0 - 3.6.12 + 4.0.18 1.5.0 3.0.0 0.8.1 From 246d83d49d6790be372681ef3233ff567b02334b Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 28 Oct 2023 13:19:47 +0530 Subject: [PATCH 042/283] JAVA-26380 Update parent of child modules to use immediate parent --- spring-security-modules/spring-security-acl/pom.xml | 3 +-- spring-security-modules/spring-security-auth0/pom.xml | 3 +-- spring-security-modules/spring-security-azuread/pom.xml | 3 +-- spring-security-modules/spring-security-cognito/pom.xml | 3 +-- spring-security-modules/spring-security-core-2/pom.xml | 3 +-- spring-security-modules/spring-security-core/pom.xml | 3 +-- spring-security-modules/spring-security-ldap/pom.xml | 3 +-- spring-security-modules/spring-security-legacy-oidc/pom.xml | 3 +-- spring-security-modules/spring-security-oauth2-sso/pom.xml | 3 +-- spring-security-modules/spring-security-oauth2/pom.xml | 3 +-- spring-security-modules/spring-security-oidc/pom.xml | 3 +-- spring-security-modules/spring-security-okta/pom.xml | 3 +-- spring-security-modules/spring-security-opa/pom.xml | 3 +-- spring-security-modules/spring-security-pkce/pom.xml | 3 +-- spring-security-modules/spring-security-saml/pom.xml | 3 +-- spring-security-modules/spring-security-social-login/pom.xml | 3 +-- spring-security-modules/spring-security-web-angular/pom.xml | 3 +-- spring-security-modules/spring-security-web-boot-1/pom.xml | 3 +-- spring-security-modules/spring-security-web-boot-2/pom.xml | 3 +-- spring-security-modules/spring-security-web-boot-3/pom.xml | 3 +-- spring-security-modules/spring-security-web-boot-4/pom.xml | 3 +-- spring-security-modules/spring-security-web-boot-5/pom.xml | 3 +-- spring-security-modules/spring-security-web-login-2/pom.xml | 3 +-- spring-security-modules/spring-security-web-mvc/pom.xml | 3 +-- .../spring-security-web-rest-basic-auth/pom.xml | 3 +-- .../spring-security-web-rest-custom/pom.xml | 3 +-- spring-security-modules/spring-security-web-springdoc/pom.xml | 3 +-- spring-security-modules/spring-security-web-thymeleaf/pom.xml | 3 +-- spring-security-modules/spring-security-web-x509/pom.xml | 3 +-- 29 files changed, 29 insertions(+), 58 deletions(-) diff --git a/spring-security-modules/spring-security-acl/pom.xml b/spring-security-modules/spring-security-acl/pom.xml index 7facc1b14b..734b85800a 100644 --- a/spring-security-modules/spring-security-acl/pom.xml +++ b/spring-security-modules/spring-security-acl/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-auth0/pom.xml b/spring-security-modules/spring-security-auth0/pom.xml index 106a0db29f..8ee59eeac1 100644 --- a/spring-security-modules/spring-security-auth0/pom.xml +++ b/spring-security-modules/spring-security-auth0/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-azuread/pom.xml b/spring-security-modules/spring-security-azuread/pom.xml index c1fe08b47a..7e67a7e635 100644 --- a/spring-security-modules/spring-security-azuread/pom.xml +++ b/spring-security-modules/spring-security-azuread/pom.xml @@ -6,9 +6,8 @@ 4.0.0 com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 spring-security-azuread diff --git a/spring-security-modules/spring-security-cognito/pom.xml b/spring-security-modules/spring-security-cognito/pom.xml index 56754ddf99..2e359382a7 100644 --- a/spring-security-modules/spring-security-cognito/pom.xml +++ b/spring-security-modules/spring-security-cognito/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-core-2/pom.xml b/spring-security-modules/spring-security-core-2/pom.xml index 5d77098869..54aac0d9a7 100644 --- a/spring-security-modules/spring-security-core-2/pom.xml +++ b/spring-security-modules/spring-security-core-2/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-core/pom.xml b/spring-security-modules/spring-security-core/pom.xml index 03d7030057..2a18145ac0 100644 --- a/spring-security-modules/spring-security-core/pom.xml +++ b/spring-security-modules/spring-security-core/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-ldap/pom.xml b/spring-security-modules/spring-security-ldap/pom.xml index 471ffff4a1..9f4f3b4106 100644 --- a/spring-security-modules/spring-security-ldap/pom.xml +++ b/spring-security-modules/spring-security-ldap/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index e98486b0ff..55b6e780b2 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oauth2-sso/pom.xml b/spring-security-modules/spring-security-oauth2-sso/pom.xml index a87e4d7814..d8101d2313 100644 --- a/spring-security-modules/spring-security-oauth2-sso/pom.xml +++ b/spring-security-modules/spring-security-oauth2-sso/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oauth2/pom.xml b/spring-security-modules/spring-security-oauth2/pom.xml index 1b30f6685d..977e2c16fd 100644 --- a/spring-security-modules/spring-security-oauth2/pom.xml +++ b/spring-security-modules/spring-security-oauth2/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-oidc/pom.xml b/spring-security-modules/spring-security-oidc/pom.xml index 70031b7396..c27c084ad7 100644 --- a/spring-security-modules/spring-security-oidc/pom.xml +++ b/spring-security-modules/spring-security-oidc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-okta/pom.xml b/spring-security-modules/spring-security-okta/pom.xml index 98b8abedb4..5ae1241b18 100644 --- a/spring-security-modules/spring-security-okta/pom.xml +++ b/spring-security-modules/spring-security-okta/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-opa/pom.xml b/spring-security-modules/spring-security-opa/pom.xml index 72b0574253..a6240f6e69 100644 --- a/spring-security-modules/spring-security-opa/pom.xml +++ b/spring-security-modules/spring-security-opa/pom.xml @@ -7,9 +7,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-pkce/pom.xml b/spring-security-modules/spring-security-pkce/pom.xml index 5899b297b4..e0bd8eb90e 100644 --- a/spring-security-modules/spring-security-pkce/pom.xml +++ b/spring-security-modules/spring-security-pkce/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-saml/pom.xml b/spring-security-modules/spring-security-saml/pom.xml index 8a9b418374..8d7cce939f 100644 --- a/spring-security-modules/spring-security-saml/pom.xml +++ b/spring-security-modules/spring-security-saml/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-social-login/pom.xml b/spring-security-modules/spring-security-social-login/pom.xml index ddda4235be..5efa5b703c 100644 --- a/spring-security-modules/spring-security-social-login/pom.xml +++ b/spring-security-modules/spring-security-social-login/pom.xml @@ -9,9 +9,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-angular/pom.xml b/spring-security-modules/spring-security-web-angular/pom.xml index 2a745bc6cc..15dc4d007c 100644 --- a/spring-security-modules/spring-security-web-angular/pom.xml +++ b/spring-security-modules/spring-security-web-angular/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-1/pom.xml b/spring-security-modules/spring-security-web-boot-1/pom.xml index fa0fd567fe..08adb700ec 100644 --- a/spring-security-modules/spring-security-web-boot-1/pom.xml +++ b/spring-security-modules/spring-security-web-boot-1/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-2/pom.xml b/spring-security-modules/spring-security-web-boot-2/pom.xml index 3ba8726f51..2255f8b035 100644 --- a/spring-security-modules/spring-security-web-boot-2/pom.xml +++ b/spring-security-modules/spring-security-web-boot-2/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-3/pom.xml b/spring-security-modules/spring-security-web-boot-3/pom.xml index 5229068dfa..0b71e89527 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-4/pom.xml b/spring-security-modules/spring-security-web-boot-4/pom.xml index ffbed0f8ab..b5bfc55a9f 100644 --- a/spring-security-modules/spring-security-web-boot-4/pom.xml +++ b/spring-security-modules/spring-security-web-boot-4/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-boot-5/pom.xml b/spring-security-modules/spring-security-web-boot-5/pom.xml index f4e2e3ad92..14b8d87f25 100644 --- a/spring-security-modules/spring-security-web-boot-5/pom.xml +++ b/spring-security-modules/spring-security-web-boot-5/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-login-2/pom.xml b/spring-security-modules/spring-security-web-login-2/pom.xml index 2d92a8567f..a44543a6ba 100644 --- a/spring-security-modules/spring-security-web-login-2/pom.xml +++ b/spring-security-modules/spring-security-web-login-2/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-mvc/pom.xml b/spring-security-modules/spring-security-web-mvc/pom.xml index 505826d1a2..10dd89f618 100644 --- a/spring-security-modules/spring-security-web-mvc/pom.xml +++ b/spring-security-modules/spring-security-web-mvc/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml index 3c842a8a54..9a3b21af92 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml +++ b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-rest-custom/pom.xml b/spring-security-modules/spring-security-web-rest-custom/pom.xml index dfd2f59aaf..2e55fe8b89 100644 --- a/spring-security-modules/spring-security-web-rest-custom/pom.xml +++ b/spring-security-modules/spring-security-web-rest-custom/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-springdoc/pom.xml b/spring-security-modules/spring-security-web-springdoc/pom.xml index 03e938f1c8..30102fd83d 100644 --- a/spring-security-modules/spring-security-web-springdoc/pom.xml +++ b/spring-security-modules/spring-security-web-springdoc/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-thymeleaf/pom.xml b/spring-security-modules/spring-security-web-thymeleaf/pom.xml index c13aa6a471..dd5f2d7c97 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/pom.xml +++ b/spring-security-modules/spring-security-web-thymeleaf/pom.xml @@ -11,9 +11,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 diff --git a/spring-security-modules/spring-security-web-x509/pom.xml b/spring-security-modules/spring-security-web-x509/pom.xml index 5282ab7d83..ec0331fd53 100644 --- a/spring-security-modules/spring-security-web-x509/pom.xml +++ b/spring-security-modules/spring-security-web-x509/pom.xml @@ -10,9 +10,8 @@ com.baeldung - parent-boot-2 + spring-security-modules 0.0.1-SNAPSHOT - ../../parent-boot-2 From 462ddc7f0260f44d0dbd56789f55c09ea9c5cd88 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Sat, 28 Oct 2023 21:11:08 +0530 Subject: [PATCH 043/283] BAEL-7145 Bill Pugh Singleton implementation --- .../baledung/billpugh/BillPughSingleton.java | 15 ++++++ .../billpugh/EagerLoadedSingleton.java | 11 +++++ .../billpugh/LazyLoadedSingleton.java | 15 ++++++ .../SynchronizedLazyLoadedSingleton.java | 15 ++++++ .../billpugh/BillPughSingletonUnitTest.java | 43 +++++++++++++++++ .../EagerLoadedSingletonUnitTest.java | 46 +++++++++++++++++++ .../billpugh/LazyLoadedSingletonUnitTest.java | 17 +++++++ ...nchronizedLazyLoadedSingletonUnitTest.java | 44 ++++++++++++++++++ 8 files changed, 206 insertions(+) create mode 100644 patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java create mode 100644 patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java create mode 100644 patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java create mode 100644 patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java create mode 100644 patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java create mode 100644 patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java create mode 100644 patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java create mode 100644 patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java new file mode 100644 index 0000000000..f558706a07 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/BillPughSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class BillPughSingleton { + private BillPughSingleton() { + + } + + private static class SingletonHelper { + private static final BillPughSingleton BILL_PUGH_SINGLETON_INSTANCE = new BillPughSingleton(); + } + + public static BillPughSingleton getInstance() { + return SingletonHelper.BILL_PUGH_SINGLETON_INSTANCE; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java new file mode 100644 index 0000000000..c0a535f2d5 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/EagerLoadedSingleton.java @@ -0,0 +1,11 @@ +package com.baledung.billpugh; + +public class EagerLoadedSingleton { + private static final EagerLoadedSingleton EAGER_LOADED_SINGLETON = new EagerLoadedSingleton(); + private EagerLoadedSingleton() { + + } + public static EagerLoadedSingleton getInstance() { + return EAGER_LOADED_SINGLETON; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java new file mode 100644 index 0000000000..b4967a58cd --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/LazyLoadedSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class LazyLoadedSingleton { + private static LazyLoadedSingleton lazyLoadedSingletonObj; + + private LazyLoadedSingleton() { + } + + public static LazyLoadedSingleton getInstance() { + if (null == lazyLoadedSingletonObj) { + lazyLoadedSingletonObj = new LazyLoadedSingleton(); + } + return lazyLoadedSingletonObj; + } +} diff --git a/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java new file mode 100644 index 0000000000..fe3457e054 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/main/java/com/baledung/billpugh/SynchronizedLazyLoadedSingleton.java @@ -0,0 +1,15 @@ +package com.baledung.billpugh; + +public class SynchronizedLazyLoadedSingleton { + private static SynchronizedLazyLoadedSingleton synchronizedLazyLoadedSingleton; + + private SynchronizedLazyLoadedSingleton() { + } + + public static synchronized SynchronizedLazyLoadedSingleton getInstance() { + if (null == synchronizedLazyLoadedSingleton) { + synchronizedLazyLoadedSingleton = new SynchronizedLazyLoadedSingleton(); + } + return synchronizedLazyLoadedSingleton; + } +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java new file mode 100644 index 0000000000..b42d36229f --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java @@ -0,0 +1,43 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class BillPughSingletonUnitTest { + Logger logger = LoggerFactory.getLogger(BillPughSingletonUnitTest.class); + @Test + void giveSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set setHoldingSingletonObj = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return BillPughSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + setHoldingSingletonObj.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, setHoldingSingletonObj.size()); + } +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..fd65ff6c5b --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/EagerLoadedSingletonUnitTest.java @@ -0,0 +1,46 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EagerLoadedSingletonUnitTest { + + Logger logger = LoggerFactory.getLogger(EagerLoadedSingletonUnitTest.class); + + @Test + void giveEagerLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set set = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return EagerLoadedSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + set.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, set.size()); + } + +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..0e0ea25779 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/LazyLoadedSingletonUnitTest.java @@ -0,0 +1,17 @@ +package com.baledung.billpugh; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +public class LazyLoadedSingletonUnitTest { + + @Test + void givenLazyLoadedImpl_whenCallGetInstance_thenReturnSingleInstance() throws ClassNotFoundException { + Class bs = Class.forName("com.baledung.billpugh.LazyLoadedSingleton"); + assertThrows(IllegalAccessException.class, () -> bs.getDeclaredConstructor().newInstance()); + + LazyLoadedSingleton lazyLoadedSingletonObj1 = LazyLoadedSingleton.getInstance(); + LazyLoadedSingleton lazyLoadedSingletonObj2 = LazyLoadedSingleton.getInstance(); + assertEquals(lazyLoadedSingletonObj1.hashCode(), lazyLoadedSingletonObj2.hashCode()); + } +} diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java new file mode 100644 index 0000000000..1f1636b458 --- /dev/null +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/SynchronizedLazyLoadedSingletonUnitTest.java @@ -0,0 +1,44 @@ +package com.baledung.billpugh; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SynchronizedLazyLoadedSingletonUnitTest { + Logger logger = LoggerFactory.getLogger(SynchronizedLazyLoadedSingletonUnitTest.class); + @Test + void giveSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + Set setHoldingSingletonObj = new HashSet<>(); + List> futures = new ArrayList<>(); + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Callable runnableTask = () -> { + logger.info("run called for:" + Thread.currentThread().getName()); + return SynchronizedLazyLoadedSingleton.getInstance(); + }; + + int count = 0; + while(count < 10) { + futures.add(executorService.submit(runnableTask)); + count++; + } + futures.forEach(e -> { + try { + setHoldingSingletonObj.add(e.get()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + executorService.shutdown(); + assertEquals(1, setHoldingSingletonObj.size()); + } + +} From 4596614dc9721bc246c587f35092c86330a92629 Mon Sep 17 00:00:00 2001 From: Niket Agrawal Date: Sun, 29 Oct 2023 01:42:22 +0530 Subject: [PATCH 044/283] Initial Commit --- .../core-java-persistence-3/pom.xml | 35 ++++++ .../ResultSetToMapUnitTest.java | 105 ++++++++++++++++++ persistence-modules/pom.xml | 1 + 3 files changed, 141 insertions(+) create mode 100644 persistence-modules/core-java-persistence-3/pom.xml create mode 100644 persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java diff --git a/persistence-modules/core-java-persistence-3/pom.xml b/persistence-modules/core-java-persistence-3/pom.xml new file mode 100644 index 0000000000..6868da27be --- /dev/null +++ b/persistence-modules/core-java-persistence-3/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + com.baeldung.core-java-persistence-3 + core-java-persistence-3 + core-java-persistence-3 + 0.1.0-SNAPSHOT + jar + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + com.h2database + h2 + ${h2.version} + + + org.springframework + spring-jdbc + ${spring-jdbc.version} + + + commons-dbutils + commons-dbutils + ${commons-dbutils.version} + + + + 2.1.214 + 5.3.29 + 1.8.1 + + \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java new file mode 100644 index 0000000000..b483cc04c9 --- /dev/null +++ b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.resultsettomap; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.ResultSetHandler; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ResultSetToMapUnitTest { + private static Connection connection = null; + private static final String JDBC_URL = "jdbc:h2:mem:testDatabase"; + private static final String USERNAME = "dbUser"; + private static final String PASSWORD = "dbPassword"; + + @Before + public void setup() throws Exception { + connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + initialDataSetup(); + } + + private void initialDataSetup() throws SQLException { + Statement statement = connection.createStatement(); + String sql = "CREATE TABLE EMPLOYEE (empId INTEGER not null, empName VARCHAR(50), empCity VARCHAR(50), PRIMARY KEY (empId))"; + statement.executeUpdate(sql); + List sqlQueryList = Arrays.asList("INSERT INTO EMPLOYEE VALUES (1, 'Steve','London')", "INSERT INTO EMPLOYEE VALUES (2, 'John','London')", "INSERT INTO EMPLOYEE VALUES (3, 'David', 'Sydney')", + "INSERT INTO EMPLOYEE VALUES (4, 'Kevin','London')", "INSERT INTO EMPLOYEE VALUES (5, 'Jade', 'Sydney')"); + for (String query : sqlQueryList) { + statement.executeUpdate(query); + } + } + + @Test + public void whenUsingNativeJava_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM EMPLOYEE") + .executeQuery(); + Map> valueMap = new HashMap<>(); + + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + if (!valueMap.containsKey(empCity)) { + valueMap.putIfAbsent(empCity, new ArrayList<>()); + } + valueMap.get(empCity) + .add(empName); + } + assertEquals(3, valueMap.get("London") + .size()); + } + + @Test + public void whenUsingLambda_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM EMPLOYEE") + .executeQuery(); + Map> valueMap = new HashMap<>(); + + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); + } + assertEquals(3, valueMap.get("London") + .size()); + } + + @Test + public void whenUsingDbUtils_thenConvertResultSetToMap() throws SQLException { + + ResultSetHandler>> handler = new ResultSetHandler>>() { + public Map> handle(ResultSet resultSet) throws SQLException { + Map> result = new HashMap<>(); + while (resultSet.next()) { + String empCity = resultSet.getString("empCity"); + String empName = resultSet.getString("empName"); + result.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); + } + return result; + } + }; + QueryRunner run = new QueryRunner(); + Map> valueMap = run.query(connection, "SELECT * FROM EMPLOYEE", handler); + assertEquals(3, valueMap.get("London") + .size()); + } + + @After + public void preDestroy() throws Exception { + connection.close(); + } +} diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index a99a180390..162894f1e0 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -21,6 +21,7 @@ blaze-persistence core-java-persistence core-java-persistence-2 + core-java-persistence-3 elasticsearch flyway flyway-repair From 6d2e874c264e67437078e9506e19dca6f0c181a9 Mon Sep 17 00:00:00 2001 From: Niket Agrawal Date: Sun, 29 Oct 2023 01:46:23 +0530 Subject: [PATCH 045/283] Updated Pom --- persistence-modules/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 53e408c3a5..9c150a28d7 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -21,6 +21,7 @@ blaze-persistence core-java-persistence core-java-persistence-2 + core-java-persistence-3 couchbase elasticsearch flyway From 832584c68cdeadbb14cf17ee11ca215bfa4bfb40 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 31 Oct 2023 20:37:18 +0530 Subject: [PATCH 046/283] JAVA-26280 Improve libraries-testing module build time --- .../{SmurfsArchUnitTest.java => SmurfsArchManualTest.java} | 2 +- ...erStatusIntegrationTest.java => MemberStatusManualTest.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename libraries-testing/src/test/java/com/baeldung/archunit/smurfs/{SmurfsArchUnitTest.java => SmurfsArchManualTest.java} (98%) rename libraries-testing/src/test/java/com/baeldung/serenity/{MemberStatusIntegrationTest.java => MemberStatusManualTest.java} (98%) diff --git a/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java similarity index 98% rename from libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java rename to libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java index 9724c2bcae..7db104bd57 100644 --- a/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchUnitTest.java +++ b/libraries-testing/src/test/java/com/baeldung/archunit/smurfs/SmurfsArchManualTest.java @@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; -public class SmurfsArchUnitTest { +public class SmurfsArchManualTest { @Test public void givenPresentationLayerClasses_thenWrongCheckFails() { diff --git a/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java similarity index 98% rename from libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java rename to libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java index e95b63aa96..ec5346d27b 100644 --- a/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java +++ b/libraries-testing/src/test/java/com/baeldung/serenity/MemberStatusManualTest.java @@ -14,7 +14,7 @@ import static com.baeldung.serenity.membership.MemberGrade.Gold; import static com.baeldung.serenity.membership.MemberGrade.Silver; @RunWith(SerenityRunner.class) -public class MemberStatusIntegrationTest { +public class MemberStatusManualTest { @Steps private MemberStatusSteps memberSteps; From 44aea845c9dfb11da3075adea740410461079e9f Mon Sep 17 00:00:00 2001 From: gaepi Date: Tue, 31 Oct 2023 18:41:10 +0100 Subject: [PATCH 047/283] JAVA-18614 | fixing log-out. --- .../com/baeldung/saml/SecurityConfig.java | 8 ++--- .../src/main/resources/application.yml | 2 +- .../resources/metadata/metadata-idp-okta.xml | 34 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java b/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java index 9078953d02..524cb3b0bc 100644 --- a/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java +++ b/spring-security-modules/spring-security-saml2/src/main/java/com/baeldung/saml/SecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.saml2.provider.service.metadata.OpenSamlMetadataResolver; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; @@ -25,10 +26,9 @@ public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository); - Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver()); - - http.authorizeHttpRequests(authorize -> authorize.anyRequest() - .authenticated()) + Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver()); + + http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()) .saml2Login(withDefaults()) .saml2Logout(withDefaults()) .addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class); diff --git a/spring-security-modules/spring-security-saml2/src/main/resources/application.yml b/spring-security-modules/spring-security-saml2/src/main/resources/application.yml index 75b9612b47..a9adbf6212 100644 --- a/spring-security-modules/spring-security-saml2/src/main/resources/application.yml +++ b/spring-security-modules/spring-security-saml2/src/main/resources/application.yml @@ -9,7 +9,7 @@ spring: - private-key-location: classpath:local.key certificate-location: classpath:local.crt singlelogout: - url: https://dev-56617222.okta.com/app/dev-56617222_springbootsaml_1/exk8b5jr6vYQqVXp45d7/slo/saml + url: https://dev-92830632.okta.com/app/dev-92830632_baeldungspringsecuritysaml2app_1/exkd0u28geAHN4ViI5d7/slo/saml binding: POST response-url: "{baseUrl}/logout/saml2/slo" assertingparty: diff --git a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml index 83976805c4..675aa4be2f 100644 --- a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml +++ b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml @@ -1,17 +1,17 @@ -MIIDqDCCApCgAwIBAgIGAYZ6plFwMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG -A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU -MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEcMBoGCSqGSIb3DQEJ -ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzAyMjIxOTQxNDVaFw0zMzAyMjIxOTQyNDVaMIGUMQswCQYD -VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG -A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEc -MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMCoER+Qlx6xBBUAcIxRk5ItmfldF+Rc+z+FCY/Ow7+cNBOIenRGfQLirQMwKzvZAg2o52xm -OrtqsHX3NLEnSQDyQp/sE7MueHQCGcDnCAQEeOVbDSPW7bDOeK/qNyecTPKZreL70TQLPpeA9x7l -WA59zxOX9or9BLuQJrXKOU/cZ4BXzue351R2qmuj7IqbXmsbetKegVFShYJZ9e9ta42OK1T8oDez -dKZbPj5el1kj2jJ08GzO3TDg9j5B21x3sz2bxg6vFMP7e10hgLicxKVw1P5ZG995wUA+E8YbFehi -YXRlcJiiKhmjRvHFl1F5vM4DPLaL4b8BJ1E21Byhb2cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA -FMy00eWU4klEdV2PhoOPZE8Phj6tVDtEjr+ol7L7RJh6u2WPwLm6U9vE9wQ0/OYhOjThUsZqxqjL -SqhZeMiFwohL6K5cmW2wTkxgfICyPY9g3BVDtogsZgbI0clIG5slwgiy9Kn7wQpSHWDvpEZXwmyV -KodcWIpgBf0dUdBhsx+o34eG7ajsLb9HEisF0ntxlKdG2LJqlkJBtiUgI2Wo2jNshfzA7Cp9cNio -+j3f1dwyWmmwWkyxGkEw8UwuwKMDHfuAwyBmZJmmG9zkHMlHkgQxxq3iI8Bs9E3lKYXtwLE7K+xe -rTdWegAfIP7LXC3JKN1N/Meke5FJLXmWAMXKIw==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file +MIIDqDCCApCgAwIBAgIGAYuBc2vlMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG + A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU + MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi05MjgzMDYzMjEcMBoGCSqGSIb3DQEJ + ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzEwMzAxNjM3MjdaFw0zMzEwMzAxNjM4MjZaMIGUMQswCQYD + VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG + A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi05MjgzMDYzMjEc + MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC + ggEBAJqFFWDXTf0mCTQ0U781/jRMzuRqNAwaskN0obVXXSjtXmbXcdUWJO1P037zvQuR/53BEK+Y + kDQvqgCdL5E/IlPm1nlZoaZ5sobNvQJaTfY5RUlFO0wKW2kwOyPA2yey8r3yfETuyqmzOWjFlli1 + 77mHRCsSBPrFPYxUrCgosT1gdTarb5ZmepyB5jszhRmKDgRL0SSdsGlW05nWjp0GJlW9wzBJd+fD + MoWY9l4bDBCB+UgpiZ+78Yo6w01JAByJdm6+t00iqEQweNBZPXHaJ48GgIAKpqZqRBu+ZgkFFfXa + kof3RutsTLwxtVuzJ6I4SeiOtxTES+GiMj0d8eHwUbUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA + Spx5Vag/UES0TB09fBwXW5NYMykDdBRo1/aP/pKsBZdvzMv70hjPYFS699i9EX++i2WpAcr/Cht7 + NM+VdOgY7ZaQM5c6djYu1thByrCVzY1LuK6OnfE/x6RzeHUNdfqJHU5P9FVJbt74Vu22qKoA7uxW + sGbDHGyGyTYHj0udMOrTP9EFkhNqvkcvqJLLES/03ylMA79n00PH3qvjSZQJHardnYYtqboezbvs + PFJvxzAhh6l+tmseQx42uSB2xF3rKcF40i/h1AfX1e6hlRyG2enjQb7h8WpX1JOk6Sbbbz4xKFtO + vTjrqbvR9K5LdSFJddaE5U/WFYbRIQeW1T2y9A==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file From f49e4d934964aeea4948947bfc296e5a10bd2071 Mon Sep 17 00:00:00 2001 From: gaepi Date: Tue, 31 Oct 2023 18:44:49 +0100 Subject: [PATCH 048/283] JAVA-18614 | fixing log-out. --- .../src/main/resources/application.yml | 2 +- .../resources/metadata/metadata-idp-okta.xml | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spring-security-modules/spring-security-saml2/src/main/resources/application.yml b/spring-security-modules/spring-security-saml2/src/main/resources/application.yml index a9adbf6212..75b9612b47 100644 --- a/spring-security-modules/spring-security-saml2/src/main/resources/application.yml +++ b/spring-security-modules/spring-security-saml2/src/main/resources/application.yml @@ -9,7 +9,7 @@ spring: - private-key-location: classpath:local.key certificate-location: classpath:local.crt singlelogout: - url: https://dev-92830632.okta.com/app/dev-92830632_baeldungspringsecuritysaml2app_1/exkd0u28geAHN4ViI5d7/slo/saml + url: https://dev-56617222.okta.com/app/dev-56617222_springbootsaml_1/exk8b5jr6vYQqVXp45d7/slo/saml binding: POST response-url: "{baseUrl}/logout/saml2/slo" assertingparty: diff --git a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml index 675aa4be2f..785effccc6 100644 --- a/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml +++ b/spring-security-modules/spring-security-saml2/src/main/resources/metadata/metadata-idp-okta.xml @@ -1,17 +1,17 @@ -MIIDqDCCApCgAwIBAgIGAYuBc2vlMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG +MIIDqDCCApCgAwIBAgIGAYZ6plFwMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU - MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi05MjgzMDYzMjEcMBoGCSqGSIb3DQEJ - ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzEwMzAxNjM3MjdaFw0zMzEwMzAxNjM4MjZaMIGUMQswCQYD + MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEcMBoGCSqGSIb3DQEJ + ARYNaW5mb0Bva3RhLmNvbTAeFw0yMzAyMjIxOTQxNDVaFw0zMzAyMjIxOTQyNDVaMIGUMQswCQYD VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG - A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi05MjgzMDYzMjEc + A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi01NjYxNzIyMjEc MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC - ggEBAJqFFWDXTf0mCTQ0U781/jRMzuRqNAwaskN0obVXXSjtXmbXcdUWJO1P037zvQuR/53BEK+Y - kDQvqgCdL5E/IlPm1nlZoaZ5sobNvQJaTfY5RUlFO0wKW2kwOyPA2yey8r3yfETuyqmzOWjFlli1 - 77mHRCsSBPrFPYxUrCgosT1gdTarb5ZmepyB5jszhRmKDgRL0SSdsGlW05nWjp0GJlW9wzBJd+fD - MoWY9l4bDBCB+UgpiZ+78Yo6w01JAByJdm6+t00iqEQweNBZPXHaJ48GgIAKpqZqRBu+ZgkFFfXa - kof3RutsTLwxtVuzJ6I4SeiOtxTES+GiMj0d8eHwUbUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA - Spx5Vag/UES0TB09fBwXW5NYMykDdBRo1/aP/pKsBZdvzMv70hjPYFS699i9EX++i2WpAcr/Cht7 - NM+VdOgY7ZaQM5c6djYu1thByrCVzY1LuK6OnfE/x6RzeHUNdfqJHU5P9FVJbt74Vu22qKoA7uxW - sGbDHGyGyTYHj0udMOrTP9EFkhNqvkcvqJLLES/03ylMA79n00PH3qvjSZQJHardnYYtqboezbvs - PFJvxzAhh6l+tmseQx42uSB2xF3rKcF40i/h1AfX1e6hlRyG2enjQb7h8WpX1JOk6Sbbbz4xKFtO - vTjrqbvR9K5LdSFJddaE5U/WFYbRIQeW1T2y9A==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file + ggEBAMCoER+Qlx6xBBUAcIxRk5ItmfldF+Rc+z+FCY/Ow7+cNBOIenRGfQLirQMwKzvZAg2o52xm + OrtqsHX3NLEnSQDyQp/sE7MueHQCGcDnCAQEeOVbDSPW7bDOeK/qNyecTPKZreL70TQLPpeA9x7l + WA59zxOX9or9BLuQJrXKOU/cZ4BXzue351R2qmuj7IqbXmsbetKegVFShYJZ9e9ta42OK1T8oDez + dKZbPj5el1kj2jJ08GzO3TDg9j5B21x3sz2bxg6vFMP7e10hgLicxKVw1P5ZG995wUA+E8YbFehi + YXRlcJiiKhmjRvHFl1F5vM4DPLaL4b8BJ1E21Byhb2cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA + FMy00eWU4klEdV2PhoOPZE8Phj6tVDtEjr+ol7L7RJh6u2WPwLm6U9vE9wQ0/OYhOjThUsZqxqjL + SqhZeMiFwohL6K5cmW2wTkxgfICyPY9g3BVDtogsZgbI0clIG5slwgiy9Kn7wQpSHWDvpEZXwmyV + KodcWIpgBf0dUdBhsx+o34eG7ajsLb9HEisF0ntxlKdG2LJqlkJBtiUgI2Wo2jNshfzA7Cp9cNio + +j3f1dwyWmmwWkyxGkEw8UwuwKMDHfuAwyBmZJmmG9zkHMlHkgQxxq3iI8Bs9E3lKYXtwLE7K+xe + rTdWegAfIP7LXC3JKN1N/Meke5FJLXmWAMXKIw==urn:oasis:names:tc:SAML:1.1:nameid-format:unspecifiedurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress \ No newline at end of file From feca50daca29d74b161e7ccb6fff6bde710f01e6 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Tue, 31 Oct 2023 20:17:39 -0400 Subject: [PATCH 049/283] Incorporated review comments --- .../baeldung/kafka/message/ordering/Config.java | 3 +++ .../ordering/ExtSeqWithTimeWindowConsumer.java | 6 +++--- .../ordering/ExtSeqWithTimeWindowProducer.java | 12 ++++++++---- .../message/ordering/MultiPartitionConsumer.java | 9 +++++---- .../message/ordering/MultiPartitionProducer.java | 14 +++++++++----- .../message/ordering/ProducerConfigurations.java | 2 +- .../message/ordering/SinglePartitionConsumer.java | 6 +++--- .../message/ordering/SinglePartitionProducer.java | 14 +++++++++----- 8 files changed, 41 insertions(+), 25 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java index 2635e72431..12acfecf51 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java @@ -2,4 +2,7 @@ package com.baeldung.kafka.message.ordering; public class Config { public static final String CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS = "value.deserializer.serializedClass"; + public static final String KAFKA_LOCAL = "localhost:9092"; + public static final String MULTI_PARTITION_TOPIC = "multi_partition_topic"; + public static final String SINGLE_PARTITION_TOPIC = "single_partition_topic"; } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java index 639a980462..06cb7104b7 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java @@ -17,14 +17,14 @@ public class ExtSeqWithTimeWindowConsumer { public static void main(String[] args) { Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList("multi_partition_topic")); + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); while (true) { @@ -42,7 +42,7 @@ public class ExtSeqWithTimeWindowConsumer { private static void processBuffer(List buffer) { Collections.sort(buffer); buffer.forEach(userEvent -> { - System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", event nano time : " + userEvent.getEventNanoTime()); + System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java index c18e35b351..73a62c0bf2 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java @@ -5,15 +5,18 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.LongSerializer; import java.util.Properties; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; public class ExtSeqWithTimeWindowProducer { - public static void main(String[] args) { + public static void main(String[] args) throws ExecutionException, InterruptedException { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); @@ -21,8 +24,9 @@ public class ExtSeqWithTimeWindowProducer { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); userEvent.setGlobalSequenceNumber(sequenceNumber); - producer.send(new ProducerRecord<>("multi_partition_topic", sequenceNumber, userEvent)); - System.out.println("User Event Nano time : " + userEvent.getEventNanoTime() + ", User Event Id: " + userEvent.getUserEventId()); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); + RecordMetadata metadata = future.get(); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } producer.close(); System.out.println("ExternalSequencingProducer Completed."); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java index e738832425..82f05cc80e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java @@ -14,22 +14,23 @@ import java.util.Properties; public class MultiPartitionConsumer { private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); + public static void main(String[] args) { Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); - props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList("multi_partition_topic")); + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); while (true) { ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { UserEvent userEvent = record.value(); if (userEvent != null) { - System.out.println("Process message with event nano time : " + userEvent.getEventNanoTime() + ", Event ID: " + userEvent.getUserEventId()); + System.out.println("User Event ID: " + userEvent.getUserEventId()); } }); } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java index db02c87bbe..52da49ab80 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java @@ -5,25 +5,29 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.LongSerializer; import java.util.Properties; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; public class MultiPartitionProducer { - public static void main(String[] args) { + public static void main(String[] args) throws ExecutionException, InterruptedException { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); for (long count = 1; count <= 10 ; count++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); - producer.send(new ProducerRecord<>("multi_partition_topic", count, userEvent)); - System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, count, userEvent)); + RecordMetadata metadata = future.get(); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } producer.close(); - System.out.println("SinglePartitionProducer Completed."); + System.out.println("MultiPartitionProducer Completed."); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 0eb563910e..61c9cb48aa 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -10,7 +10,7 @@ import java.util.Properties; public class ProducerConfigurations { public static void main(String[] args) { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java index 5f5ce86924..1c50f3cf7a 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java @@ -17,19 +17,19 @@ public class SinglePartitionConsumer { public static void main(String[] args) { Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList("single_partition_topic")); + consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC)); while (true) { ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { UserEvent userEvent = record.value(); - System.out.println("Process message with event nano time : " + userEvent.getEventNanoTime() + ", Event ID: " + userEvent.getUserEventId()); + System.out.println("User Event ID: " + userEvent.getUserEventId()); }); } } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java index 2a7719e34f..9306abaebf 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java @@ -5,24 +5,28 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; 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.serialization.LongSerializer; import java.time.Instant; import java.util.Properties; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; public class SinglePartitionProducer { - public static void main(String[] args) { + public static void main(String[] args) throws ExecutionException, InterruptedException { Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); KafkaProducer producer = new KafkaProducer<>(props); - for (long count = 1; count <= 10 ; count++) { + for (long count = 1; count <= 10; count++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); - producer.send(new ProducerRecord<>("single_partition_topic", count, userEvent)); - System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); + Future future = producer.send(new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, count, userEvent)); + RecordMetadata metadata = future.get(); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } producer.close(); System.out.println("SinglePartitionProducer Completed."); From 88f85963bb1614a10025cadb123ab5b26bc2b489 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Tue, 31 Oct 2023 22:04:32 -0400 Subject: [PATCH 050/283] Config changes --- .../kafka/message/ordering/ConsumerConfigurations.java | 4 ++-- .../kafka/message/ordering/ProducerConfigurations.java | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java index 15562cfcef..5b5a1f8e0b 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java @@ -16,7 +16,7 @@ import java.util.Properties; public class ConsumerConfigurations { public static void main(String[] args) { Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); @@ -24,7 +24,7 @@ public class ConsumerConfigurations { props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, "1"); props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList("multi_partition_topic")); + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); while (true) { ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java index 61c9cb48aa..79fc42be3d 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java @@ -16,14 +16,15 @@ public class ProducerConfigurations { props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); + props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); KafkaProducer producer = new KafkaProducer<>(props); for (int i = 0; i < 10; i++) { - String key = "Key-" + (i % 3); // Assuming 3 partitions - producer.send(new ProducerRecord<>("multi_partition_topic", key, "Message-" + i)); + String key = "Key-" + (i % 5); // Assuming 5 partitions + producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, key, "Message-" + i)); } producer.close(); - System.out.println("MultiPartitionProducer Completed."); + System.out.println("Producer Configurations Completed."); } } From a5d58617e2aac4e7605914a3f771d1a6617d9e7f Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:21:59 +0530 Subject: [PATCH 051/283] BAEL-7177 Modifying Objects within Stream while iterating --- .../modifystream/entity/ImmutablePerson.java | 25 ++++ .../baledung/modifystream/entity/Person.java | 27 ++++ .../modifystream/ModifyStreamUnitTest.java | 140 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java create mode 100644 core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java create mode 100644 core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java new file mode 100644 index 0000000000..bb7f3b8eb3 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/ImmutablePerson.java @@ -0,0 +1,25 @@ +package com.baledung.modifystream.entity; + +public class ImmutablePerson { + + private String name; + private String email; + + public ImmutablePerson(String name, String email) { + this.name = name; + this.email = email; + } + + public ImmutablePerson withEmail(String email) { + + return new ImmutablePerson(this.name, email); + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java new file mode 100644 index 0000000000..c82c159059 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baledung/modifystream/entity/Person.java @@ -0,0 +1,27 @@ +package com.baledung.modifystream.entity; + +public class Person { + private String name; + private String email; + + public Person(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java new file mode 100644 index 0000000000..72183ec94a --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java @@ -0,0 +1,140 @@ +package com.baeldung.modifystream; + +import com.baledung.modifystream.entity.ImmutablePerson; +import com.baledung.modifystream.entity.Person; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ModifyStreamUnitTest { + Logger logger = LoggerFactory.getLogger(ModifyStreamUnitTest.class); + List personLst = new ArrayList(); + List immutablePersonList = new ArrayList(); + + @BeforeEach + void prepare() { + Person person1 = new Person("John", "john@gmail.com"); + Person person2 = new Person("Peter", "peter@gmail.com"); + Person person3 = new Person("Mary", "mary@gmail.com"); + Person person4 = new Person("William", "william@gmail.com"); + + personLst.add(person1); + personLst.add(person2); + personLst.add(person3); + personLst.add(person4); + } + + @BeforeEach + void prepareImmutablePerson() { + ImmutablePerson immutablePerson1 = new ImmutablePerson("John", "john@gmail.com"); + ImmutablePerson immutablePerson2 = new ImmutablePerson("Peter", "peter@gmail.com"); + ImmutablePerson immutablePerson3 = new ImmutablePerson("Mary", "mary@gmail.com"); + ImmutablePerson immutablePerson4 = new ImmutablePerson("William", "william@gmail.com"); + + immutablePersonList.add(immutablePerson1); + immutablePersonList.add(immutablePerson2); + immutablePersonList.add(immutablePerson3); + immutablePersonList.add(immutablePerson4); + } + + @Test + void givenPersonLst_whenRemoveWhileIterating_thenThrowException() { + assertThrows(NullPointerException.class, () -> { + personLst.stream().forEach(e -> { + if(e.getName().equals("John")) { + personLst.remove(e); + } + }); + }); + } + + @Test + void givenPersonLst_whenRemoveWhileIteratingWithForEach_thenThrowException() { + assertThrows(ConcurrentModificationException.class, () -> { + personLst.forEach(e -> { + if(e.getName().equals("John")) { + personLst.remove(e); + } + }); + }); + } + + @Test + void givenPersonLst_whenRemoveWhileIterating_thenPersonRemoved() { + assertEquals(4, personLst.size()); + + CopyOnWriteArrayList cps = new CopyOnWriteArrayList<>(personLst); + cps.stream().forEach(e -> { + if(e.getName().equals("John")) { + cps.remove(e); + } + }); + + assertEquals(3, cps.size()); + } + + + @Test + void givenPersonLst_whenRemovePersonWithFilter_thenPersonRemoved() { + assertEquals(4, personLst.size()); + + List newPersonLst = personLst.stream() + .filter(e -> !e.getName().equals("John")) + .collect(Collectors.toList()); + + assertEquals(3, newPersonLst.size()); + } + + @Test + void givenPersonLst_whenRemovePersonWithRemoveIf_thenPersonRemoved() { + assertEquals(4, personLst.size()); + + personLst.removeIf(e -> e.getName().equals("John")); + + assertEquals(3, personLst.size()); + } + + @Test + void givenPersonLst_whenUpdatePersonEmailByInterferingWithForEach_thenPersonEmailUpdated() { + personLst.stream().forEach(e -> e.setEmail(e.getEmail().toUpperCase())); + + personLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + + @Test + void givenPersonLst_whenUpdatePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newPersonLst = personLst.stream() + .map(e -> new Person(e.getName(), e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + newPersonLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + + @Test + void givenPersonLst_whenUpdateImmutablePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newImmutablePersonLst = immutablePersonList.stream() + .map(e -> e.withEmail(e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + newImmutablePersonLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + @Test + void givenPersonLst_whenUpdatePersonEmailByInterferingWithPeek_thenPersonEmailUpdated() { + personLst.stream() + .peek(e -> e.setEmail(e.getEmail().toUpperCase())) + .collect(Collectors.toList()); + + personLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + } + +} From aa2701442567f6efc2a50ef095ef449b836546eb Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:12:45 +0530 Subject: [PATCH 052/283] BAEL-7177 Modifying Objects within Stream while iterating --- .../modifystream/ModifyStreamUnitTest.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java index 72183ec94a..f5fab408b8 100644 --- a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java @@ -18,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; public class ModifyStreamUnitTest { Logger logger = LoggerFactory.getLogger(ModifyStreamUnitTest.class); - List personLst = new ArrayList(); + List personList = new ArrayList(); List immutablePersonList = new ArrayList(); @BeforeEach @@ -28,10 +28,10 @@ public class ModifyStreamUnitTest { Person person3 = new Person("Mary", "mary@gmail.com"); Person person4 = new Person("William", "william@gmail.com"); - personLst.add(person1); - personLst.add(person2); - personLst.add(person3); - personLst.add(person4); + personList.add(person1); + personList.add(person2); + personList.add(person3); + personList.add(person4); } @BeforeEach @@ -48,32 +48,32 @@ public class ModifyStreamUnitTest { } @Test - void givenPersonLst_whenRemoveWhileIterating_thenThrowException() { + void givenPersonList_whenRemoveWhileIterating_thenThrowException() { assertThrows(NullPointerException.class, () -> { - personLst.stream().forEach(e -> { + personList.stream().forEach(e -> { if(e.getName().equals("John")) { - personLst.remove(e); + personList.remove(e); } }); }); } @Test - void givenPersonLst_whenRemoveWhileIteratingWithForEach_thenThrowException() { + void givenPersonList_whenRemoveWhileIteratingWithForEach_thenThrowException() { assertThrows(ConcurrentModificationException.class, () -> { - personLst.forEach(e -> { + personList.forEach(e -> { if(e.getName().equals("John")) { - personLst.remove(e); + personList.remove(e); } }); }); } @Test - void givenPersonLst_whenRemoveWhileIterating_thenPersonRemoved() { - assertEquals(4, personLst.size()); + void givenPersonList_whenRemoveWhileIterating_thenPersonRemoved() { + assertEquals(4, personList.size()); - CopyOnWriteArrayList cps = new CopyOnWriteArrayList<>(personLst); + CopyOnWriteArrayList cps = new CopyOnWriteArrayList<>(personList); cps.stream().forEach(e -> { if(e.getName().equals("John")) { cps.remove(e); @@ -85,56 +85,56 @@ public class ModifyStreamUnitTest { @Test - void givenPersonLst_whenRemovePersonWithFilter_thenPersonRemoved() { - assertEquals(4, personLst.size()); + void givenPersonList_whenRemovePersonWithFilter_thenPersonRemoved() { + assertEquals(4, personList.size()); - List newPersonLst = personLst.stream() + List newPersonList = personList.stream() .filter(e -> !e.getName().equals("John")) .collect(Collectors.toList()); - assertEquals(3, newPersonLst.size()); + assertEquals(3, newPersonList.size()); } @Test - void givenPersonLst_whenRemovePersonWithRemoveIf_thenPersonRemoved() { - assertEquals(4, personLst.size()); + void givenPersonList_whenRemovePersonWithRemoveIf_thenPersonRemoved() { + assertEquals(4, personList.size()); - personLst.removeIf(e -> e.getName().equals("John")); + personList.removeIf(e -> e.getName().equals("John")); - assertEquals(3, personLst.size()); + assertEquals(3, personList.size()); } @Test - void givenPersonLst_whenUpdatePersonEmailByInterferingWithForEach_thenPersonEmailUpdated() { - personLst.stream().forEach(e -> e.setEmail(e.getEmail().toUpperCase())); + void givenPersonList_whenUpdatePersonEmailByInterferingWithForEach_thenPersonEmailUpdated() { + personList.stream().forEach(e -> e.setEmail(e.getEmail().toUpperCase())); - personLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + personList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } @Test - void givenPersonLst_whenUpdatePersonEmailWithMapMethod_thenPersonEmailUpdated() { - List newPersonLst = personLst.stream() + void givenPersonList_whenUpdatePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newPersonList = personList.stream() .map(e -> new Person(e.getName(), e.getEmail().toUpperCase())) .collect(Collectors.toList()); - newPersonLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + newPersonList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } @Test - void givenPersonLst_whenUpdateImmutablePersonEmailWithMapMethod_thenPersonEmailUpdated() { - List newImmutablePersonLst = immutablePersonList.stream() + void givenPersonList_whenUpdateImmutablePersonEmailWithMapMethod_thenPersonEmailUpdated() { + List newImmutablePersonList = immutablePersonList.stream() .map(e -> e.withEmail(e.getEmail().toUpperCase())) .collect(Collectors.toList()); - newImmutablePersonLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + newImmutablePersonList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } @Test - void givenPersonLst_whenUpdatePersonEmailByInterferingWithPeek_thenPersonEmailUpdated() { - personLst.stream() + void givenPersonList_whenUpdatePersonEmailByInterferingWithPeek_thenPersonEmailUpdated() { + personList.stream() .peek(e -> e.setEmail(e.getEmail().toUpperCase())) .collect(Collectors.toList()); - personLst.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); + personList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } } From 3fe81a3e075ae05044038788b23fa8729115f734 Mon Sep 17 00:00:00 2001 From: Niket Agrawal Date: Fri, 3 Nov 2023 03:49:06 +0530 Subject: [PATCH 053/283] Formatting changes --- .../core-java-persistence-3/pom.xml | 6 --- .../ResultSetToMapUnitTest.java | 44 ++++++++----------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/persistence-modules/core-java-persistence-3/pom.xml b/persistence-modules/core-java-persistence-3/pom.xml index 6868da27be..26ac2a5218 100644 --- a/persistence-modules/core-java-persistence-3/pom.xml +++ b/persistence-modules/core-java-persistence-3/pom.xml @@ -16,11 +16,6 @@ h2 ${h2.version} - - org.springframework - spring-jdbc - ${spring-jdbc.version} - commons-dbutils commons-dbutils @@ -29,7 +24,6 @@ 2.1.214 - 5.3.29 1.8.1 \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java index b483cc04c9..c8a6351804 100644 --- a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java +++ b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java @@ -33,48 +33,43 @@ public class ResultSetToMapUnitTest { private void initialDataSetup() throws SQLException { Statement statement = connection.createStatement(); - String sql = "CREATE TABLE EMPLOYEE (empId INTEGER not null, empName VARCHAR(50), empCity VARCHAR(50), PRIMARY KEY (empId))"; - statement.executeUpdate(sql); - List sqlQueryList = Arrays.asList("INSERT INTO EMPLOYEE VALUES (1, 'Steve','London')", "INSERT INTO EMPLOYEE VALUES (2, 'John','London')", "INSERT INTO EMPLOYEE VALUES (3, 'David', 'Sydney')", - "INSERT INTO EMPLOYEE VALUES (4, 'Kevin','London')", "INSERT INTO EMPLOYEE VALUES (5, 'Jade', 'Sydney')"); + String ddlQuery = "CREATE TABLE employee (empId INTEGER not null, empName VARCHAR(50), empCity VARCHAR(50), PRIMARY KEY (empId))"; + statement.execute(ddlQuery); + List sqlQueryList = Arrays.asList("INSERT INTO employee VALUES (1, 'Steve','London')", "INSERT INTO employee VALUES (2, 'John','London')", "INSERT INTO employee VALUES (3, 'David', 'Sydney')", + "INSERT INTO employee VALUES (4, 'Kevin','London')", "INSERT INTO employee VALUES (5, 'Jade', 'Sydney')"); + for (String query : sqlQueryList) { - statement.executeUpdate(query); + statement.execute(query); } } @Test - public void whenUsingNativeJava_thenConvertResultSetToMap() throws SQLException { - ResultSet resultSet = connection.prepareStatement("SELECT * FROM EMPLOYEE") - .executeQuery(); + public void whenUsingContainsKey_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee").executeQuery(); Map> valueMap = new HashMap<>(); while (resultSet.next()) { String empCity = resultSet.getString("empCity"); String empName = resultSet.getString("empName"); if (!valueMap.containsKey(empCity)) { - valueMap.putIfAbsent(empCity, new ArrayList<>()); + valueMap.put(empCity, new ArrayList<>()); } - valueMap.get(empCity) - .add(empName); + valueMap.get(empCity).add(empName); } - assertEquals(3, valueMap.get("London") - .size()); + assertEquals(3, valueMap.get("London").size()); } @Test - public void whenUsingLambda_thenConvertResultSetToMap() throws SQLException { - ResultSet resultSet = connection.prepareStatement("SELECT * FROM EMPLOYEE") - .executeQuery(); + public void whenUsingComputeIfAbsent_thenConvertResultSetToMap() throws SQLException { + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee").executeQuery(); Map> valueMap = new HashMap<>(); while (resultSet.next()) { String empCity = resultSet.getString("empCity"); String empName = resultSet.getString("empName"); - valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()) - .add(empName); + valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()).add(empName); } - assertEquals(3, valueMap.get("London") - .size()); + assertEquals(3, valueMap.get("London").size()); } @Test @@ -86,16 +81,15 @@ public class ResultSetToMapUnitTest { while (resultSet.next()) { String empCity = resultSet.getString("empCity"); String empName = resultSet.getString("empName"); - result.computeIfAbsent(empCity, data -> new ArrayList<>()) - .add(empName); + result.computeIfAbsent(empCity, data -> new ArrayList<>()).add(empName); } return result; } }; + QueryRunner run = new QueryRunner(); - Map> valueMap = run.query(connection, "SELECT * FROM EMPLOYEE", handler); - assertEquals(3, valueMap.get("London") - .size()); + Map> valueMap = run.query(connection, "SELECT * FROM employee", handler); + assertEquals(3, valueMap.get("London").size()); } @After From b7d743c62973913c244eed64befca97b45c6c8ee Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:40:36 -0400 Subject: [PATCH 054/283] Incorporated Review comments --- .../kafka/message/ordering/Config.java | 5 +- .../ordering/ConsumerConfigurations.java | 36 -------------- .../ExtSeqWithTimeWindowConsumer.java | 49 ------------------- .../ExtSeqWithTimeWindowProducer.java | 34 ------------- .../ordering/MultiPartitionConsumer.java | 39 --------------- .../ordering/MultiPartitionProducer.java | 33 ------------- .../ordering/ProducerConfigurations.java | 30 ------------ .../ordering/SinglePartitionConsumer.java | 37 -------------- .../ordering/SinglePartitionProducer.java | 35 ------------- .../ExtSeqWithTimeWindowIntegrationTest.java | 16 +++--- .../MultiplePartitionIntegrationTest.java | 15 +++--- .../SinglePartitionIntegrationTest.java | 15 +++--- 12 files changed, 25 insertions(+), 319 deletions(-) delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java delete mode 100644 apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java index 12acfecf51..9cc6314309 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java @@ -2,7 +2,10 @@ package com.baeldung.kafka.message.ordering; public class Config { public static final String CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS = "value.deserializer.serializedClass"; - public static final String KAFKA_LOCAL = "localhost:9092"; public static final String MULTI_PARTITION_TOPIC = "multi_partition_topic"; public static final String SINGLE_PARTITION_TOPIC = "single_partition_topic"; + + public static final int MULTIPLE_PARTITIONS = 5; + public static final int SINGLE_PARTITION = 1; + public static short REPLICATION_FACTOR = 1; } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java deleted file mode 100644 index 5b5a1f8e0b..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ConsumerConfigurations.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.clients.producer.ProducerConfig; -import org.apache.kafka.common.serialization.StringDeserializer; -import org.apache.kafka.common.serialization.StringSerializer; - -import java.time.Duration; -import java.util.Collections; -import java.util.Properties; - -public class ConsumerConfigurations { - public static void main(String[] args) { - Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); - props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "500"); - props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, "1"); - props.put(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG, "500"); - Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); - - while (true) { - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - records.forEach(record -> { - System.out.println("Partition: " + record.partition() + ", Message: " + record.value()); - }); - } - } -} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java deleted file mode 100644 index 06cb7104b7..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowConsumer.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.common.serialization.LongDeserializer; - -import java.time.Duration; -import java.util.*; - -public class ExtSeqWithTimeWindowConsumer { - private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); - - public static void main(String[] args) { - Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); - props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); - Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); - List buffer = new ArrayList<>(); - long lastProcessedTime = System.nanoTime(); - while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); - records.forEach(record -> { - buffer.add(record.value()); - }); - if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { - processBuffer(buffer); - lastProcessedTime = System.nanoTime(); - } - } - } - - private static void processBuffer(List buffer) { - Collections.sort(buffer); - buffer.forEach(userEvent -> { - System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); - }); - buffer.clear(); - } -} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java deleted file mode 100644 index 73a62c0bf2..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowProducer.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; -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.serialization.LongSerializer; - -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -public class ExtSeqWithTimeWindowProducer { - public static void main(String[] args) throws ExecutionException, InterruptedException { - Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long sequenceNumber = 1; sequenceNumber <= 10 ; sequenceNumber++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); - userEvent.setEventNanoTime(System.nanoTime()); - userEvent.setGlobalSequenceNumber(sequenceNumber); - Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); - RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); - } - producer.close(); - System.out.println("ExternalSequencingProducer Completed."); - } -} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java deleted file mode 100644 index 82f05cc80e..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionConsumer.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.common.serialization.LongDeserializer; - -import java.time.Duration; -import java.util.Collections; -import java.util.Properties; - -public class MultiPartitionConsumer { - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); - - public static void main(String[] args) { - Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); - props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); - props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); - while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); - records.forEach(record -> { - UserEvent userEvent = record.value(); - if (userEvent != null) { - System.out.println("User Event ID: " + userEvent.getUserEventId()); - } - }); - } - } -} - diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java deleted file mode 100644 index 52da49ab80..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/MultiPartitionProducer.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; -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.serialization.LongSerializer; - -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -public class MultiPartitionProducer { - public static void main(String[] args) throws ExecutionException, InterruptedException { - Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long count = 1; count <= 10 ; count++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); - userEvent.setEventNanoTime(System.nanoTime()); - Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, count, userEvent)); - RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); - } - producer.close(); - System.out.println("MultiPartitionProducer Completed."); - } -} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java deleted file mode 100644 index 79fc42be3d..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/ProducerConfigurations.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -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.serialization.StringSerializer; - -import java.util.Properties; - -public class ProducerConfigurations { - public static void main(String[] args) { - Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); - props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1"); - props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384"); - props.put(ProducerConfig.LINGER_MS_CONFIG, "5"); - props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); - KafkaProducer producer = new KafkaProducer<>(props); - - for (int i = 0; i < 10; i++) { - String key = "Key-" + (i % 5); // Assuming 5 partitions - producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, key, "Message-" + i)); - } - - producer.close(); - System.out.println("Producer Configurations Completed."); - } -} diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java deleted file mode 100644 index 1c50f3cf7a..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionConsumer.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerConfig; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.common.serialization.LongDeserializer; - -import java.time.Duration; -import java.util.Collections; -import java.util.Properties; - -public class SinglePartitionConsumer { - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(100); - - public static void main(String[] args) { - Properties props = new Properties(); - props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); - props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JacksonDeserializer.class.getName()); - props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); - props.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); - Consumer consumer = new KafkaConsumer<>(props); - consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC)); - while (true) { - ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); - records.forEach(record -> { - UserEvent userEvent = record.value(); - System.out.println("User Event ID: " + userEvent.getUserEventId()); - }); - } - } -} - diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java deleted file mode 100644 index 9306abaebf..0000000000 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/SinglePartitionProducer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.kafka.message.ordering; - -import com.baeldung.kafka.message.ordering.payload.UserEvent; -import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; -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.serialization.LongSerializer; - -import java.time.Instant; -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -public class SinglePartitionProducer { - public static void main(String[] args) throws ExecutionException, InterruptedException { - Properties props = new Properties(); - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, Config.KAFKA_LOCAL); - props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); - props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - KafkaProducer producer = new KafkaProducer<>(props); - for (long count = 1; count <= 10; count++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); - userEvent.setEventNanoTime(System.nanoTime()); - Future future = producer.send(new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, count, userEvent)); - RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); - } - producer.close(); - System.out.println("SinglePartitionProducer Completed."); - } - -} diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index 5f540d5b50..0535e3c4e6 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -30,9 +30,7 @@ import static org.junit.jupiter.api.Assertions.*; @Testcontainers public class ExtSeqWithTimeWindowIntegrationTest { - private static String TOPIC = "multi_partition_topic"; - private static int PARTITIONS = 5; - private static short REPLICATION_FACTOR = 1; + private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; @@ -65,10 +63,10 @@ public class ExtSeqWithTimeWindowIntegrationTest { producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + NewTopic newTopic = new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR); topicList.add(newTopic); CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(TOPIC); + KafkaFuture future = result.values().get(Config.MULTI_PARTITION_TOPIC); future.whenComplete((voidResult, exception) -> { if (exception != null) { System.err.println("Error creating the topic: " + exception.getMessage()); @@ -91,14 +89,14 @@ public class ExtSeqWithTimeWindowIntegrationTest { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); userEvent.setGlobalSequenceNumber(sequenceNumber); - Future future = producer.send(new ProducerRecord<>(TOPIC, sequenceNumber, userEvent)); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("Partition : " + metadata.partition()); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } boolean isOrderMaintained = true; - consumer.subscribe(Collections.singletonList(TOPIC)); + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); @@ -131,7 +129,7 @@ public class ExtSeqWithTimeWindowIntegrationTest { Collections.sort(buffer); buffer.forEach(userEvent -> { receivedUserEventList.add(userEvent); - System.out.println("Process message with Event ID: " + userEvent.getUserEventId()); + System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index d4b88ad06f..bbe9fcf7f8 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -30,9 +30,7 @@ import static org.junit.jupiter.api.Assertions.*; @Testcontainers public class MultiplePartitionIntegrationTest { - private static String TOPIC = "multi_partition_topic"; - private static int PARTITIONS = 5; - private static short REPLICATION_FACTOR = 1; + private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; @@ -63,10 +61,10 @@ public class MultiplePartitionIntegrationTest { producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + NewTopic newTopic = new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR); topicList.add(newTopic); CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(TOPIC); + KafkaFuture future = result.values().get(Config.MULTI_PARTITION_TOPIC); future.whenComplete((voidResult, exception) -> { if (exception != null) { System.err.println("Error creating the topic: " + exception.getMessage()); @@ -88,18 +86,19 @@ public class MultiplePartitionIntegrationTest { for (long count = 1; count <= 10 ; count++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); - Future future = producer.send(new ProducerRecord<>(TOPIC, count, userEvent)); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, count, userEvent)); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("Partition : " + metadata.partition()); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } boolean isOrderMaintained = true; - consumer.subscribe(Collections.singletonList(TOPIC)); + consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { UserEvent userEvent = record.value(); receivedUserEventList.add(userEvent); + System.out.println("User Event ID: " + userEvent.getUserEventId()); }); for (int insertPosition = 0; insertPosition <= receivedUserEventList.size() - 1; insertPosition++) { if (isOrderMaintained){ diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index b41dc67686..6894b0fe80 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -32,9 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers public class SinglePartitionIntegrationTest { - private static String TOPIC = "single_partition_topic"; - private static int PARTITIONS = 1; - private static short REPLICATION_FACTOR = 1; + private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; @@ -67,10 +65,10 @@ public class SinglePartitionIntegrationTest { producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(TOPIC, PARTITIONS, REPLICATION_FACTOR); + NewTopic newTopic = new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR); topicList.add(newTopic); CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(TOPIC); + KafkaFuture future = result.values().get(Config.SINGLE_PARTITION_TOPIC); future.whenComplete((voidResult, exception) -> { if (exception != null) { System.err.println("Error creating the topic: " + exception.getMessage()); @@ -92,18 +90,19 @@ public class SinglePartitionIntegrationTest { for (long count = 1; count <= 10 ; count++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); - ProducerRecord producerRecord = new ProducerRecord<>(TOPIC, userEvent); + ProducerRecord producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent); Future future = producer.send(producerRecord); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("Partition : " + metadata.partition()); + System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } - consumer.subscribe(Collections.singletonList(TOPIC)); + consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC)); ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { UserEvent userEvent = record.value(); receivedUserEventList.add(userEvent); + System.out.println("User Event ID: " + userEvent.getUserEventId()); }); boolean result = true; for (int count = 0; count <= 9 ; count++) { From 667620821b143d5c750bb4869fceb939dbc60c47 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:41:15 -0400 Subject: [PATCH 055/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../message/ordering/ExtSeqWithTimeWindowIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index 0535e3c4e6..ab3e37916a 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -38,7 +38,7 @@ public class ExtSeqWithTimeWindowIntegrationTest { private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds @Container - private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5).toNanos(); @BeforeAll static void setup() throws ExecutionException, InterruptedException { From d0edfbc423a834b8ce6a6674cf54713a44ea4513 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:41:27 -0400 Subject: [PATCH 056/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../message/ordering/ExtSeqWithTimeWindowIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index ab3e37916a..af4aa53cc0 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -34,7 +34,7 @@ public class ExtSeqWithTimeWindowIntegrationTest { private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds @Container From 83d6d89db5287e00c9e563737e24b4d979a2d2d9 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:41:34 -0400 Subject: [PATCH 057/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/SinglePartitionIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 6894b0fe80..35b6602510 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -37,7 +37,7 @@ public class SinglePartitionIntegrationTest { private static KafkaProducer producer; private static KafkaConsumer consumer; - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); From bfa7c53b5463ad47c32dc595c234b2d6e5837da2 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:41:54 -0400 Subject: [PATCH 058/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../message/ordering/MultiplePartitionIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index bbe9fcf7f8..64a063c6c9 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -34,7 +34,7 @@ public class MultiplePartitionIntegrationTest { private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; - private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofMillis(5000); + private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); From 02e02f928f4ff4e4bad974b1e3e30e17b2fbc8ed Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 2 Nov 2023 17:47:02 -0600 Subject: [PATCH 059/283] [BAEL-7074] Synchronization for static data examples --- .../retry/RetryCompletableFuture.java | 2 +- .../threadpool/CustomCompletableFuture.java | 8 +- .../atomicinteger/Employee.java | 32 +++++++ .../synchronizestatic/none/Employee.java | 28 ++++++ .../reentrantlock/Employee.java | 44 +++++++++ .../synchronizedblock/Employee.java | 34 +++++++ .../synchronizedmethod/Employee.java | 27 ++++++ .../volatilekeyword/Employee.java | 29 ++++++ .../SychronizeStaticDataUnitTest.java | 89 +++++++++++++++++++ 9 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java index a3df6b3624..a46665559f 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java @@ -48,7 +48,7 @@ public class RetryCompletableFuture { CompletableFuture cf = CompletableFuture.supplyAsync(supplier); sleep(100); for (int i = 0; i < maxRetries; i++) { - cf = cf.exceptionallyAsync(__ -> supplier.get()); + //cf = cf.exceptionallyAsync(__ -> supplier.get()); } return cf; } diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java index 1f3997768e..473cc562ca 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java @@ -20,9 +20,9 @@ public class CustomCompletableFuture extends CompletableFuture { return future; } - @Override - public Executor defaultExecutor() { - return executor; - } +// @Override +// public Executor defaultExecutor() { +// return executor; +// } } \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java new file mode 100644 index 0000000000..845dd65ce6 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java @@ -0,0 +1,32 @@ +package com.baeldung.concurrent.synchronizestatic.atomicinteger; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Synchronizing static variable with AtomicInteger. + */ +public class Employee { + + private static final AtomicInteger count = new AtomicInteger(0); + + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + count.incrementAndGet(); + System.out.println("Count = " + count.get()); + } + + public static int getCount() { + return count.get(); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java new file mode 100644 index 0000000000..f050a68be4 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java @@ -0,0 +1,28 @@ +package com.baeldung.concurrent.synchronizestatic.none; + +/** + * No synchronization. + */ +public class Employee { + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + System.out.println("Count = " + ++count); + } + + public static Integer getCount() { + return count; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java new file mode 100644 index 0000000000..2ac0b0d3f2 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java @@ -0,0 +1,44 @@ +package com.baeldung.concurrent.synchronizestatic.reentrantlock; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Synchronizing static variable with a Reenatrant Lock. + */ +public class Employee { + + private static final ReentrantLock lock = new ReentrantLock(); + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + lock.lock(); + try { + System.out.println("Count = " + ++count); + } + finally { + lock.unlock(); + } + } + + public static int getCount() { + lock.lock(); + try { + return count; + } + finally { + lock.unlock(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java new file mode 100644 index 0000000000..9c078e7abe --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java @@ -0,0 +1,34 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedblock; + +/** + * Synchronizing static variable with a synchronized block. + */ +public class Employee { + + private static final Object lock = new Object(); + + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + synchronized(lock) { + System.out.println("Count = " + ++count); + } + } + + public static int getCount() { + synchronized(lock) { + return count; + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java new file mode 100644 index 0000000000..f0a785c427 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedmethod/Employee.java @@ -0,0 +1,27 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedmethod; + +/** + * Synchronizing static variable with a synchronized method. + */ +public class Employee { + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static synchronized void incrementCount() { + System.out.println("Count = " + ++count); + } + + public static synchronized int getCount() { + return count; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java new file mode 100644 index 0000000000..f41b10e160 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java @@ -0,0 +1,29 @@ +package com.baeldung.concurrent.synchronizestatic.volatilekeyword; + +/** + * No synchronization. + */ +public class Employee +{ + + volatile static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + System.out.println("Count = " + ++count); + } + + public static Integer getCount() { + return count; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java new file mode 100644 index 0000000000..d8d9a344f1 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java @@ -0,0 +1,89 @@ +package com.baeldung.concurrent.synchronizestatic; + +import org.junit.Test; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class SychronizeStaticDataUnitTest +{ + private final Executor pool = Executors.newFixedThreadPool(4); + + @Test + public void whenNotSynchronized_thenDataOutOfOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenVolatile_thenDataInOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.volatilekeyword.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenSynchronizedMethod_thenDataInOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenSynchronizedBlock_thenDataInOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenAtomicInteger_thenDataInOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.atomicinteger.Employee(finalI, "John", "Smith"); + }); + } + } + + @Test + public void whenReentrantLock_thenDataInOrder() { + int numberToTest = 100; + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith"); + }); + } + } +} From 1ab4017ad65984900919fa396e52a51637555a3b Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 19:47:05 -0400 Subject: [PATCH 060/283] Issue fixes --- .../ordering/ExtSeqWithTimeWindowIntegrationTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index af4aa53cc0..a18efe9961 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -35,11 +35,11 @@ public class ExtSeqWithTimeWindowIntegrationTest { private static KafkaProducer producer; private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); - - private static final long BUFFER_PERIOD_NS = 5000L * 1000000; // 5000 milliseconds converted to nanoseconds - @Container private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5).toNanos(); + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + @BeforeAll static void setup() throws ExecutionException, InterruptedException { KAFKA_CONTAINER.addExposedPort(9092); From 45bc3d94d407819a1d4c4e139c9b79b38e797e54 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Thu, 2 Nov 2023 20:18:19 -0400 Subject: [PATCH 061/283] Code Formatting --- .../ordering/SinglePartitionIntegrationTest.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 35b6602510..0c65618014 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -24,10 +24,12 @@ import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; + import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers @@ -53,6 +55,7 @@ public class SinglePartitionIntegrationTest { producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); + producer = new KafkaProducer<>(producerProperties); Properties consumerProperties = new Properties(); consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); @@ -61,9 +64,10 @@ public class SinglePartitionIntegrationTest { consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - admin = Admin.create(adminProperties); - producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); + admin = Admin.create(adminProperties); + + List topicList = new ArrayList<>(); NewTopic newTopic = new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR); topicList.add(newTopic); @@ -87,7 +91,7 @@ public class SinglePartitionIntegrationTest { void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); - for (long count = 1; count <= 10 ; count++) { + for (long count = 1; count <= 10; count++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); userEvent.setEventNanoTime(System.nanoTime()); ProducerRecord producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent); @@ -105,10 +109,10 @@ public class SinglePartitionIntegrationTest { System.out.println("User Event ID: " + userEvent.getUserEventId()); }); boolean result = true; - for (int count = 0; count <= 9 ; count++) { + for (int count = 0; count <= 9; count++) { UserEvent sentUserEvent = sentUserEventList.get(count); UserEvent receivedUserEvent = receivedUserEventList.get(count); - if (!sentUserEvent.equals(receivedUserEvent) && result){ + if (!sentUserEvent.equals(receivedUserEvent) && result) { result = false; } } From 38f30e733fc9ecf70a79a90c65f2ed82947d05b4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Thu, 2 Nov 2023 19:23:43 -0600 Subject: [PATCH 062/283] [BAEL-7074] Update tests --- .../atomicinteger/Employee.java | 1 - .../volatilekeyword/Employee.java | 29 ------------ .../SychronizeStaticDataUnitTest.java | 45 ++++++++----------- 3 files changed, 19 insertions(+), 56 deletions(-) delete mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java index 845dd65ce6..9c3c9b987c 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java @@ -23,7 +23,6 @@ public class Employee { private static void incrementCount() { count.incrementAndGet(); - System.out.println("Count = " + count.get()); } public static int getCount() { diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java deleted file mode 100644 index f41b10e160..0000000000 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/volatilekeyword/Employee.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.concurrent.synchronizestatic.volatilekeyword; - -/** - * No synchronization. - */ -public class Employee -{ - - volatile static int count; - int id; - String name; - String title; - - public Employee(int id, String name, String title) - { - incrementCount(); - this.id = id; - this.name = name; - this.title = title; - } - - private static void incrementCount() { - System.out.println("Count = " + ++count); - } - - public static Integer getCount() { - return count; - } -} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java index d8d9a344f1..7e5dca9f2b 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java @@ -5,13 +5,22 @@ import org.junit.Test; import java.util.concurrent.Executor; import java.util.concurrent.Executors; +/** + * The tests in this class show the output of creating multiple + * types of Employee classes in the synchronizedstatic + * package. When not synchronized the out will not be sequential; + * when it is synchronized the output will be in sequential. + */ public class SychronizeStaticDataUnitTest { private final Executor pool = Executors.newFixedThreadPool(4); + private final int numberToTest = 100; + @Test public void whenNotSynchronized_thenDataOutOfOrder() { - int numberToTest = 100; + + System.out.println("No synchronization"); for(int i = 0; i < numberToTest; i++) { int finalI = i; @@ -22,22 +31,10 @@ public class SychronizeStaticDataUnitTest } } - @Test - public void whenVolatile_thenDataInOrder() { - int numberToTest = 100; - - for(int i = 0; i < numberToTest; i++) { - int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.volatilekeyword.Employee(finalI, "John", "Smith"); - }); - } - } - @Test public void whenSynchronizedMethod_thenDataInOrder() { - int numberToTest = 100; + + System.out.println("Synchronization with synchronized method"); for(int i = 0; i < numberToTest; i++) { int finalI = i; @@ -50,7 +47,8 @@ public class SychronizeStaticDataUnitTest @Test public void whenSynchronizedBlock_thenDataInOrder() { - int numberToTest = 100; + + System.out.println("Synchronization with synchronized block"); for(int i = 0; i < numberToTest; i++) { int finalI = i; @@ -63,20 +61,15 @@ public class SychronizeStaticDataUnitTest @Test public void whenAtomicInteger_thenDataInOrder() { - int numberToTest = 100; - - for(int i = 0; i < numberToTest; i++) { - int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.atomicinteger.Employee(finalI, "John", "Smith"); - }); - } + // Not straight forward to test this because we cannot log/print + // and increment values in a synchronized fashion like other + // tests } @Test public void whenReentrantLock_thenDataInOrder() { - int numberToTest = 100; + + System.out.println("Synchronization with ReentrantLock"); for(int i = 0; i < numberToTest; i++) { int finalI = i; From 3d561e24df46720097f8f2e1eeaea780c18d102d Mon Sep 17 00:00:00 2001 From: Sam Gardner Date: Fri, 3 Nov 2023 12:43:44 +0000 Subject: [PATCH 063/283] BAEL-7105 Add code for StringBuilder comparison --- .../core-java-string-apis-2/pom.xml | 10 +++++ .../StringBuilderCompare.java | 17 ++++++++ .../StringBuilderComparisonUnitTest.java | 43 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java create mode 100644 core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java diff --git a/core-java-modules/core-java-string-apis-2/pom.xml b/core-java-modules/core-java-string-apis-2/pom.xml index 814d301532..0289a18e85 100644 --- a/core-java-modules/core-java-string-apis-2/pom.xml +++ b/core-java-modules/core-java-string-apis-2/pom.xml @@ -33,6 +33,16 @@ core-java-string-apis-2 + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + src/main/resources diff --git a/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java b/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java new file mode 100644 index 0000000000..2d2dc04b83 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/main/java/stringbuildercomparison/StringBuilderCompare.java @@ -0,0 +1,17 @@ +package stringbuildercomparison; + +public class StringBuilderCompare { + + public static boolean compare(StringBuilder one, StringBuilder two){ + if(one.length() != two.length()){ + return false; + } + for(int i = 0; i < one.length(); i++){ + if(one.charAt(i) != two.charAt(i)){ + return false; + } + } + return true; + } + +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java new file mode 100644 index 0000000000..b1a5a83770 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringbuildercomparison/StringBuilderComparisonUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.stringbuildercomparison; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotSame; + +import org.junit.Test; + +import stringbuildercomparison.StringBuilderCompare; + +public class StringBuilderComparisonUnitTest { + + @Test + public void whenUsingJavaEight_givenTwoIdenticalStringBuilders_thenCorrectlyMatch(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("Hello"); + boolean result = StringBuilderCompare.compare(one, two); + assertEquals(true, result); + } + + @Test + public void whenUsingJavaEight_givenTwoDifferentStringBuilders_thenCorrectlyIdentifyDifference(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("World"); + boolean result = StringBuilderCompare.compare(one, two); + assertEquals(false, result); + } + + @Test + public void whenUsingJavaEleven_givenTwoIdenticalStringBuilders_thenCorrectlyMatch(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("Hello"); + assertEquals(0, one.compareTo(two)); + } + + @Test + public void whenUsingJavaEleven_givenTwoDifferentStringBuilders_thenCorrectlyIdentifyDifference(){ + StringBuilder one = new StringBuilder("Hello"); + StringBuilder two = new StringBuilder("World"); + assertNotSame(0, one.compareTo(two)); + } + + +} From 1aa2f849f49c5f14c25e07966e199593ca449e80 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 3 Nov 2023 13:10:24 -0600 Subject: [PATCH 064/283] Revert 2 changes unrelated to BAEL-7074 --- .../completablefuture/retry/RetryCompletableFuture.java | 2 +- .../threadpool/CustomCompletableFuture.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java index a46665559f..a3df6b3624 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/retry/RetryCompletableFuture.java @@ -48,7 +48,7 @@ public class RetryCompletableFuture { CompletableFuture cf = CompletableFuture.supplyAsync(supplier); sleep(100); for (int i = 0; i < maxRetries; i++) { - //cf = cf.exceptionallyAsync(__ -> supplier.get()); + cf = cf.exceptionallyAsync(__ -> supplier.get()); } return cf; } diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java index 473cc562ca..1f3997768e 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java @@ -20,9 +20,9 @@ public class CustomCompletableFuture extends CompletableFuture { return future; } -// @Override -// public Executor defaultExecutor() { -// return executor; -// } + @Override + public Executor defaultExecutor() { + return executor; + } } \ No newline at end of file From 159461815d99562f7d8f1babe787c7f784145a92 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 3 Nov 2023 15:31:25 -0600 Subject: [PATCH 065/283] New example and unit test --- .../synchronizedclass/Employee.java | 32 +++++++++++++++++++ .../SychronizeStaticDataUnitTest.java | 16 +++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java new file mode 100644 index 0000000000..a69b633f3b --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java @@ -0,0 +1,32 @@ +package com.baeldung.concurrent.synchronizestatic.synchronizedclass; + +/** + * Synchronizing static variable with a synchronized block. + */ +public class Employee +{ + static int count; + int id; + String name; + String title; + + public Employee(int id, String name, String title) + { + incrementCount(); + this.id = id; + this.name = name; + this.title = title; + } + + private static void incrementCount() { + synchronized(Employee.class) { + System.out.println("Count = " + ++count); + } + } + + public static int getCount() { + synchronized(Employee.class) { + return count; + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java index 7e5dca9f2b..e633005c6f 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java @@ -45,10 +45,24 @@ public class SychronizeStaticDataUnitTest } } + @Test + public void whenSynchronizedClass_thenDataInOrder() { + + System.out.println("Synchronization with synchronized block on class"); + + for(int i = 0; i < numberToTest; i++) { + int finalI = i; + pool.execute(() -> + { + new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith"); + }); + } + } + @Test public void whenSynchronizedBlock_thenDataInOrder() { - System.out.println("Synchronization with synchronized block"); + System.out.println("Synchronization with synchronized block on a private object"); for(int i = 0; i < numberToTest; i++) { int finalI = i; From 0f6149ef8cbbd7b60312b2726f7501dcdd85dc13 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Fri, 3 Nov 2023 23:31:49 +0200 Subject: [PATCH 066/283] [JAVA-26735] Upgraded gson library to 2.10.1 version --- aws-modules/aws-dynamodb/pom.xml | 2 +- aws-modules/aws-miscellaneous/pom.xml | 2 +- java-websocket/pom.xml | 2 +- json-modules/gson/pom.xml | 2 +- .../JsonObjectConversionsUnitTest.java | 31 ++++++++++++------- json-modules/json-arrays/pom.xml | 2 +- json-modules/json/pom.xml | 2 +- libraries-data-io/pom.xml | 2 +- libraries-data/pom.xml | 2 +- libraries-http-2/pom.xml | 2 +- libraries-http/pom.xml | 2 +- web-modules/javax-servlets/pom.xml | 2 +- web-modules/spark-java/pom.xml | 2 +- 13 files changed, 31 insertions(+), 24 deletions(-) diff --git a/aws-modules/aws-dynamodb/pom.xml b/aws-modules/aws-dynamodb/pom.xml index 37b88327f4..adce036733 100644 --- a/aws-modules/aws-dynamodb/pom.xml +++ b/aws-modules/aws-dynamodb/pom.xml @@ -79,7 +79,7 @@ - 2.8.0 + 2.10.1 1.21.1 3.1.1 diff --git a/aws-modules/aws-miscellaneous/pom.xml b/aws-modules/aws-miscellaneous/pom.xml index 4126256fb9..5fdd7fa04d 100644 --- a/aws-modules/aws-miscellaneous/pom.xml +++ b/aws-modules/aws-miscellaneous/pom.xml @@ -73,7 +73,7 @@ - 2.8.0 + 2.10.1 1.21.1 1.10.L001 0.9.4.0006L diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index d529b32022..fd97fd9db3 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -29,7 +29,7 @@ 1.1 - 2.8.0 + 2.10.1 \ No newline at end of file diff --git a/json-modules/gson/pom.xml b/json-modules/gson/pom.xml index ecfbaa7be4..ba968d9ae1 100644 --- a/json-modules/gson/pom.xml +++ b/json-modules/gson/pom.xml @@ -64,7 +64,7 @@ - 2.8.0 + 2.10.1 2.9.6 diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java index 9f07617969..18d9ccaf06 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java @@ -1,7 +1,9 @@ package com.baeldung.gson.conversion; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.google.gson.*; -import org.junit.Assert; import org.junit.jupiter.api.Test; public class JsonObjectConversionsUnitTest { @@ -10,24 +12,29 @@ public class JsonObjectConversionsUnitTest { void whenUsingJsonParser_thenConvertToJsonObject() throws Exception { // Example 1: Using JsonParser String json = "{ \"name\": \"Baeldung\", \"java\": true }"; - - JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); - - Assert.assertTrue(jsonObject.isJsonObject()); - Assert.assertTrue(jsonObject.get("name").getAsString().equals("Baeldung")); - Assert.assertTrue(jsonObject.get("java").getAsBoolean() == true); + + JsonObject jsonObject = JsonParser.parseString(json) + .getAsJsonObject(); + + assertTrue(jsonObject.isJsonObject()); + assertEquals("Baeldung", jsonObject.get("name") + .getAsString()); + assertTrue(jsonObject.get("java") + .getAsBoolean()); } @Test void whenUsingGsonInstanceFromJson_thenConvertToJsonObject() throws Exception { // Example 2: Using fromJson String json = "{ \"name\": \"Baeldung\", \"java\": true }"; - + JsonObject convertedObject = new Gson().fromJson(json, JsonObject.class); - - Assert.assertTrue(convertedObject.isJsonObject()); - Assert.assertTrue(convertedObject.get("name").getAsString().equals("Baeldung")); - Assert.assertTrue(convertedObject.get("java").getAsBoolean() == true); + + assertTrue(convertedObject.isJsonObject()); + assertEquals("Baeldung", convertedObject.get("name") + .getAsString()); + assertTrue(convertedObject.get("java") + .getAsBoolean()); } } diff --git a/json-modules/json-arrays/pom.xml b/json-modules/json-arrays/pom.xml index 10c487fbda..ec492b49cc 100644 --- a/json-modules/json-arrays/pom.xml +++ b/json-modules/json-arrays/pom.xml @@ -38,7 +38,7 @@ 1.0 - 2.8.5 + 2.10.1 1.1.2 2.28.0 diff --git a/json-modules/json/pom.xml b/json-modules/json/pom.xml index 27c9262279..ba075be679 100644 --- a/json-modules/json/pom.xml +++ b/json-modules/json/pom.xml @@ -68,7 +68,7 @@ 1.0.72 1.0 1.0.1 - 2.8.5 + 2.10.1 1.1.2 2.28.0 diff --git a/libraries-data-io/pom.xml b/libraries-data-io/pom.xml index 2e126610d4..0a8afa02e2 100644 --- a/libraries-data-io/pom.xml +++ b/libraries-data-io/pom.xml @@ -106,7 +106,7 @@ v4-rev493-1.21.0 6.1.2 2.3.1 - 2.8.7 + 2.10.1 1.15 0.14.2 3.17.3 diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index a721e967d2..85ef01e704 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -210,7 +210,7 @@ 3.3.1 2.14.0 2.9.1 - 2.9.1 + 2.10.1 1.1.1 1.5.0 5.2.0 diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index fa3b6534db..c80c5729a7 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -110,7 +110,7 @@ 4.9.1 - 2.8.5 + 2.10.1 4.9.1 1.0.3 9.4.19.v20190610 diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index 18ba571f60..c726b56b5d 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -103,7 +103,7 @@ - 2.8.5 + 2.10.1 4.5.3 4.9.1 1.23.0 diff --git a/web-modules/javax-servlets/pom.xml b/web-modules/javax-servlets/pom.xml index 80a1e3af9f..406cfc05c1 100644 --- a/web-modules/javax-servlets/pom.xml +++ b/web-modules/javax-servlets/pom.xml @@ -49,7 +49,7 @@ 4.5.3 - 2.8.2 + 2.10.1 \ No newline at end of file diff --git a/web-modules/spark-java/pom.xml b/web-modules/spark-java/pom.xml index da09467212..e49be68319 100644 --- a/web-modules/spark-java/pom.xml +++ b/web-modules/spark-java/pom.xml @@ -30,7 +30,7 @@ 2.5.4 - 2.8.0 + 2.10.1 \ No newline at end of file From a324fc5c33993d3721f210c9e9079fb3233b4161 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Fri, 3 Nov 2023 23:52:59 +0200 Subject: [PATCH 067/283] [JAVA-26735] Replaced deprecated API JsonParser --- .../JsonObjectConversionsUnitTest.java | 2 ++ .../test/GsonDeserializationUnitTest.java | 8 ++--- .../gson/jsoncompare/JsonCompareUnitTest.java | 34 +++++++------------ .../serialization/GsonSerializeUnitTest.java | 3 +- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java index 18d9ccaf06..e1e5e48269 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/conversion/JsonObjectConversionsUnitTest.java @@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.gson.*; + +import org.junit.Assert; import org.junit.jupiter.api.Test; public class JsonObjectConversionsUnitTest { diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java index adc046ed8e..81d59cf364 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/deserialization/test/GsonDeserializationUnitTest.java @@ -3,8 +3,9 @@ package com.baeldung.gson.deserialization.test; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; + import java.lang.reflect.Type; import java.util.ArrayList; @@ -68,7 +69,7 @@ public class GsonDeserializationUnitTest { final GenericFoo targetObject = new Gson().fromJson(json, typeToken); - assertEquals(targetObject.theValue, new Integer(1)); + assertEquals(targetObject.theValue, Integer.valueOf(1)); } // tests - multiple elements @@ -98,8 +99,7 @@ public class GsonDeserializationUnitTest { @Test public void whenDeserializingJsonIntoElements_thenCorrect() { final String jsonSourceObject = "{\"valueInt\":7,\"valueString\":\"seven\"}"; - final JsonParser jParser = new JsonParser(); - final JsonElement jElement = jParser.parse(jsonSourceObject); + final JsonElement jElement = JsonParser.parseString(jsonSourceObject); final JsonObject jObject = jElement.getAsJsonObject(); final int intValue = jObject.get("valueInt").getAsInt(); final String stringValue = jObject.get("valueString").getAsString(); diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java index 84989a7411..4235eb426a 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/jsoncompare/JsonCompareUnitTest.java @@ -16,79 +16,71 @@ public class JsonCompareUnitTest { @Test public void givenIdenticalSimpleObjects_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}"; String string2 = "{\"customer\": {\"id\": \"44521\", \"fullName\": \"Emily Jenkins\",\"age\": 27}}"; - assertTrue(parser.parse(string1) - .isJsonObject()); - assertEquals(parser.parse(string1), parser.parse(string2)); + assertTrue(JsonParser.parseString(string1).isJsonObject()); + assertEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenSameObjectsInDifferentOrder_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"age\": 27, \"fullName\": \"Emily Jenkins\" }}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenIdenticalArrays_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "[10, 20, 30]"; String string2 = "[10, 20, 30]"; - assertTrue(parser.parse(string1) + assertTrue(JsonParser.parseString(string1) .isJsonArray()); - assertEquals(parser.parse(string1), parser.parse(string2)); + assertEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenArraysInDifferentOrder_whenCompared_thenNotEqual() { - JsonParser parser = new JsonParser(); String string1 = "[20, 10, 30]"; String string2 = "[10, 20, 30]"; - assertNotEquals(parser.parse(string1), parser.parse(string2)); + assertNotEquals(JsonParser.parseString(string1), JsonParser.parseString(string2)); } @Test public void givenIdenticalNestedObjects_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"fav_product\": \"Coke\", \"last_buy\": \"2012-04-23\"}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"fav_product\": \"Coke\"}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenIdenticalNestedObjectsWithArray_whenCompared_thenEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertEquals(json1, json2); } @Test public void givenNestedObjectsDifferentArrayOrder_whenCompared_thenNotEqual() { - JsonParser parser = new JsonParser(); String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}"; String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"eggs\", \"banana\"]}}}"; - JsonElement json1 = parser.parse(string1); - JsonElement json2 = parser.parse(string2); + JsonElement json1 = JsonParser.parseString(string1); + JsonElement json2 = JsonParser.parseString(string2); assertNotEquals(json1, json2); } diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java index 21d2bedd24..0d54cffbb4 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/serialization/GsonSerializeUnitTest.java @@ -41,8 +41,7 @@ public class GsonSerializeUnitTest { .serializeNulls() .disableHtmlEscaping() .create() - .toJson(new JsonParser() - .parse("{\"imdbId\":null,\"actors\":[{\"IMDB Code\":\"nm2199632\",\"Date Of Birth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}")); + .toJson(JsonParser.parseString("{\"imdbId\":null,\"actors\":[{\"IMDB Code\":\"nm2199632\",\"Date Of Birth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}")); Assert.assertEquals(gson.toJson(movieWithNullValue), expectedOutput); } } From 22ad2b88a8d02dd92316f159e4d31656a4aa922b Mon Sep 17 00:00:00 2001 From: vaibhav007jain <72961247+vaibhav007jain@users.noreply.github.com> Date: Sat, 4 Nov 2023 11:02:23 +0530 Subject: [PATCH 068/283] Bael-7075: Initial Commit (#15053) * Create VectorOperations.java BAEL-7075: Initial Commit * BAEL-7075: Create VectorOperationsUnitTest.java * Delete core-java-modules/core-java-collections-5/src/main/java/com/baeldung/vectors/VectorOperations.java * Update VectorOperationsUnitTest.java * Update VectorOperationsUnitTest.java - Added one more test case --- .../vectors/VectorOperationsUnitTest.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java diff --git a/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java new file mode 100644 index 0000000000..c948ce2481 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/vectors/VectorOperationsUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.vectors; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Vector; + +import org.junit.Test; + +public class VectorOperationsUnitTest { + + private static Vector getVector() { + Vector vector = new Vector(); + vector.add("Today"); + vector.add("is"); + vector.add("a"); + vector.add("great"); + vector.add("day!"); + + return vector; + } + + @Test + public void givenAVector_whenAddElementsUsingAddMethod_thenElementsGetAddedAtEnd() { + Vector vector = getVector(); + vector.add("Hello"); + assertEquals(6, vector.size()); + } + + @Test + public void givenAVector_whenUpdateElementAtIndex_thenElementAtIndexGetsUpdated() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + assertEquals("great", vector.get(3)); + vector.set(3, "good"); + assertEquals("good", vector.get(3)); + } + + @Test + public void givenAVector_whenRemoveAnElement_thenElementGetsRemovedFromTheVector() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + + // remove a specific element + vector.remove("a"); + assertEquals(4, vector.size()); + + // remove at specific index + vector.remove(2); + assertEquals("day!", vector.get(2)); + assertEquals(3, vector.size()); + + assertEquals(false, vector.remove("SomethingThatDoesn'tExist")); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void givenAVector_whenIndexIsBeyondRange_thenRemoveMethodThrowsArrayIndexOutOfBoundsException() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + vector.remove(10); + } + + @Test + public void givenAVector_whenGetElementWithinARange_thenGetMethodGetsAnElementFromTheVector() { + Vector vector = getVector(); + String fourthElement = vector.get(3); + assertEquals("great", fourthElement); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void givenAVector_whenGetElementBeyondARange_thenGetMethodThrowsArrayIndexOutOfBoundsException() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + vector.get(10); + } + + @Test + public void givenAVector_whenAddElementFromACollection_thenAllElementsGetAdeddToTheVector() { + Vector vector = getVector(); + assertEquals(5, vector.size()); + ArrayList words = new ArrayList<>(Arrays.asList("Baeldung", "is", "cool!")); + vector.addAll(words); + assertEquals(8, vector.size()); + assertEquals("cool!", vector.get(7)); + } +} From 049770733ccef4e7e364c2cd6768f66b66e85e77 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 4 Nov 2023 12:24:35 +0530 Subject: [PATCH 069/283] JAVA-27176 Upgrade hibernate validator version in core-java-string-operations-2 module --- .../core-java-string-operations-2/pom.xml | 22 +++++-------------- .../SomeClassWithValidations.java | 2 +- .../emptystrings/EmptyStringsUnitTest.java | 8 +++---- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml index 902e8f09b4..383a3b4a40 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -14,11 +14,6 @@ - - javax.validation - validation-api - ${validation-api.version} - org.apache.commons commons-lang3 @@ -30,14 +25,9 @@ ${hibernate-validator.version} - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} + org.glassfish.expressly + expressly + ${expressly.version} org.openjdk.jmh @@ -95,10 +85,8 @@ - 2.0.0.Final - 6.0.2.Final - 3.0.0 - 2.2.6 + 8.0.1.Final + 5.0.0 1.14 5.3.0 diff --git a/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java b/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java index 058d53ba82..abe311938a 100644 --- a/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java +++ b/core-java-modules/core-java-string-operations-2/src/main/java/com/baeldung/emptystrings/SomeClassWithValidations.java @@ -1,6 +1,6 @@ package com.baeldung.emptystrings; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.Pattern; class SomeClassWithValidations { diff --git a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java b/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java index 9652e0e770..c756953c70 100644 --- a/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java +++ b/core-java-modules/core-java-string-operations-2/src/test/java/com/baeldung/emptystrings/EmptyStringsUnitTest.java @@ -5,10 +5,10 @@ import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.springframework.util.ObjectUtils; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import java.util.Set; import static org.hamcrest.Matchers.iterableWithSize; From 674f03a8fe8eee695e78aac18fe9cbe472f466e9 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 4 Nov 2023 12:43:56 +0530 Subject: [PATCH 070/283] JAVA-27177 Upgrade hibernate-validator version in atomikos module --- atomikos/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atomikos/pom.xml b/atomikos/pom.xml index cd798825d1..d2ef7c84b2 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -114,7 +114,7 @@ 1.1 1.0 2.0.1.Final - 6.1.2.Final + 8.0.1.Final 3.0.0 2.2.4 From 20361bec8ebc4b3f059b2ce9a98e2433e9622781 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 4 Nov 2023 12:59:59 +0530 Subject: [PATCH 071/283] JAVA-27178 Upgrade hibernate-validator in javaxval module --- javaxval/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaxval/pom.xml b/javaxval/pom.xml index bececb2ea7..c4a30f915d 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -37,7 +37,7 @@ - 6.2.0.Final + 8.0.1.Final 3.0.4 From 885111ea75a8e4edb6b5fd82e94389effc8232ae Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 4 Nov 2023 13:13:28 +0530 Subject: [PATCH 072/283] JAVA-27177 Upragde hibernate validator- Remove dependencies no longer needed --- atomikos/pom.xml | 18 ------------------ .../atomikos/spring/jpa/Application.java | 8 ++++---- .../atomikos/spring/jpa/order/Order.java | 2 +- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/atomikos/pom.xml b/atomikos/pom.xml index d2ef7c84b2..2cbc106268 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -82,26 +82,11 @@ geronimo-jta_1.0.1B_spec ${geronimo.version} - - javax.validation - validation-api - ${validation-api.version} - org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} - @@ -113,10 +98,7 @@ 10.8.1.2 1.1 1.0 - 2.0.1.Final 8.0.1.Final - 3.0.0 - 2.2.4 \ No newline at end of file diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java index cf1fef2cd8..ad828bd2ca 100644 --- a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java +++ b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java @@ -3,10 +3,10 @@ package com.baeldung.atomikos.spring.jpa; import java.util.Set; import java.util.UUID; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java index 4b9ae2dd1d..3a580e6448 100644 --- a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java +++ b/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java @@ -3,7 +3,7 @@ package com.baeldung.atomikos.spring.jpa.order; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import javax.validation.constraints.Max; +import jakarta.validation.constraints.Max; @Entity @Table(name = "ORDERS") From 36a30dcda86fd7417c0c6ad90d733e131da3d52c Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Sat, 4 Nov 2023 09:41:18 +0100 Subject: [PATCH 073/283] JAVA-13263 | Moved some gradle7 and gradle8 modules. (#15046) --- gradle-modules/gradle-7/README.md | 3 +- .../conditional-dependency-demo/.gitignore | 2 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../conditional-dependency-demo/gradlew | 234 ----------------- .../conditional-dependency-demo/gradlew.bat | 89 ------- .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../gradle-7/gradle-javadoc/gradlew | 240 ----------------- .../gradle-7/gradle-javadoc/gradlew.bat | 91 ------- .../gradle-7/gradle-wsdl-stubs/build.gradle | 5 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 61608 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - .../gradle-7/gradle-wsdl-stubs/gradlew | 244 ------------------ .../gradle-7/gradle-wsdl-stubs/gradlew.bat | 92 ------- .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../gradle-7/{toolchains-feature => }/gradlew | 22 +- .../{dependency-version => }/gradlew.bat | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../multiple-repositories/gradlew | 234 ----------------- .../multiple-repositories/gradlew.bat | 89 ------- .../gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../publish-package/gradlew | 234 ----------------- .../publish-package/gradlew.bat | 89 ------- .../settings.gradle | 4 + gradle-modules/gradle-7/settings.gradle | 7 + gradle-modules/gradle-8/README.md | 4 + .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../dependency-version => gradle-8}/gradlew | 29 ++- .../gradlew.bat | 0 gradle-modules/gradle-8/settings.gradle | 3 + .../toolchains-feature/.gitattributes | 0 .../toolchains-feature/.gitignore | 0 .../toolchains-feature/build.gradle | 0 .../toolchains-feature/settings.gradle | 0 .../gradle-protobuf/gradlew | 0 gradle-modules/settings.gradle | 2 + 39 files changed, 58 insertions(+), 1691 deletions(-) delete mode 100644 gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradle-modules/gradle-7/conditional-dependency-demo/gradlew delete mode 100644 gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat delete mode 100644 gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradle-modules/gradle-7/gradle-javadoc/gradlew delete mode 100644 gradle-modules/gradle-7/gradle-javadoc/gradlew.bat delete mode 100644 gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew delete mode 100644 gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat rename gradle-modules/gradle-7/{toolchains-feature => }/gradle/wrapper/gradle-wrapper.properties (82%) rename gradle-modules/gradle-7/{toolchains-feature => }/gradlew (91%) mode change 100755 => 100644 rename gradle-modules/gradle-7/{dependency-version => }/gradlew.bat (100%) delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew delete mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat create mode 100644 gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle create mode 100644 gradle-modules/gradle-7/settings.gradle create mode 100644 gradle-modules/gradle-8/README.md rename gradle-modules/{gradle-7/dependency-version => gradle-8}/gradle/wrapper/gradle-wrapper.properties (82%) rename gradle-modules/{gradle-7/dependency-version => gradle-8}/gradlew (91%) mode change 100755 => 100644 rename gradle-modules/{gradle-7/toolchains-feature => gradle-8}/gradlew.bat (100%) create mode 100644 gradle-modules/gradle-8/settings.gradle rename gradle-modules/{gradle-7 => gradle-8}/toolchains-feature/.gitattributes (100%) rename gradle-modules/{gradle-7 => gradle-8}/toolchains-feature/.gitignore (100%) rename gradle-modules/{gradle-7 => gradle-8}/toolchains-feature/build.gradle (100%) rename gradle-modules/{gradle-7 => gradle-8}/toolchains-feature/settings.gradle (100%) mode change 100755 => 100644 gradle-modules/gradle-customization/gradle-protobuf/gradlew diff --git a/gradle-modules/gradle-7/README.md b/gradle-modules/gradle-7/README.md index e59b59f9fd..fe05a4b9bc 100644 --- a/gradle-modules/gradle-7/README.md +++ b/gradle-modules/gradle-7/README.md @@ -5,5 +5,4 @@ - [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories) - [Different Dependency Version Declarations in Gradle](https://www.baeldung.com/gradle-different-dependency-version-declarations) - [Generating Javadoc With Gradle](https://www.baeldung.com/java-gradle-javadoc) -- [Generating WSDL Stubs With Gradle](https://www.baeldung.com/java-gradle-create-wsdl-stubs) -- [Gradle Toolchains Support for JVM Projects](https://www.baeldung.com/java-gradle-toolchains-jvm-projects) +- [Generating WSDL Stubs With Gradle](https://www.baeldung.com/java-gradle-create-wsdl-stubs) \ No newline at end of file diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore b/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore index c2065bc262..d33fc4ef35 100644 --- a/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore +++ b/gradle-modules/gradle-7/conditional-dependency-demo/.gitignore @@ -1,7 +1,7 @@ HELP.md .gradle build/ -!gradle/wrapper/gradle-wrapper.jar +!../gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d4fb3f96a785543079b8df6723c946b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59821 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 diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 00e33edef6..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew b/gradle-modules/gradle-7/conditional-dependency-demo/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat b/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/conditional-dependency-demo/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle-javadoc/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/gradle-javadoc/gradlew.bat b/gradle-modules/gradle-7/gradle-javadoc/gradlew.bat deleted file mode 100644 index 53a6b238d4..0000000000 --- a/gradle-modules/gradle-7/gradle-javadoc/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle index e368dc5c06..6d0cfc1972 100644 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle +++ b/gradle-modules/gradle-7/gradle-wsdl-stubs/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id("com.github.bjornvester.wsdl2java") version "1.2" + id 'com.github.bjornvester.wsdl2java' version '2.0.2' } repositories { @@ -17,7 +17,6 @@ test { useJUnitPlatform() } - wsdl2java { - cxfVersion.set("3.4.4") + cxfVersion.set("4.0.2") } diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index ccebba7710deaf9f98673a68957ea02138b60d0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61608 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 diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 42defcc94b..0000000000 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip -networkTimeout=10000 -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew deleted file mode 100755 index 79a61d421c..0000000000 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew +++ /dev/null @@ -1,244 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat b/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat deleted file mode 100644 index 6689b85bee..0000000000 --- a/gradle-modules/gradle-7/gradle-wsdl-stubs/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties similarity index 82% rename from gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties rename to gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties index 37aef8d3f0..878fe049c2 100644 --- a/gradle-modules/gradle-7/toolchains-feature/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/toolchains-feature/gradlew b/gradle-modules/gradle-7/gradlew old mode 100755 new mode 100644 similarity index 91% rename from gradle-modules/gradle-7/toolchains-feature/gradlew rename to gradle-modules/gradle-7/gradlew index aeb74cbb43..1aa94a4269 --- a/gradle-modules/gradle-7/toolchains-feature/gradlew +++ b/gradle-modules/gradle-7/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradle-modules/gradle-7/dependency-version/gradlew.bat b/gradle-modules/gradle-7/gradlew.bat similarity index 100% rename from gradle-modules/gradle-7/dependency-version/gradlew.bat rename to gradle-modules/gradle-7/gradlew.bat diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d4fb3f96a785543079b8df6723c946b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59821 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 diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 070cb702f0..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat b/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/multiple-repositories/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927a4d4fb3f96a785543079b8df6723c946b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59821 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 diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 070cb702f0..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew deleted file mode 100755 index 1b6c787337..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat b/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/gradle-modules/gradle-7/multiple-repositories-demo/publish-package/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle b/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle new file mode 100644 index 0000000000..b5c2e6ecaa --- /dev/null +++ b/gradle-modules/gradle-7/multiple-repositories-demo/settings.gradle @@ -0,0 +1,4 @@ +rootProject.name = 'multiple-repositories-demo' + +include 'multiple-repositories' +include 'publish-package' \ No newline at end of file diff --git a/gradle-modules/gradle-7/settings.gradle b/gradle-modules/gradle-7/settings.gradle new file mode 100644 index 0000000000..0685ca8f59 --- /dev/null +++ b/gradle-modules/gradle-7/settings.gradle @@ -0,0 +1,7 @@ +rootProject.name = 'gradle-7' + +include 'conditional-dependency-demo' +include 'dependency-version' +include 'gradle-javadoc' +include 'gradle-wsdl-stubs' +include 'multiple-repositories-demo' \ No newline at end of file diff --git a/gradle-modules/gradle-8/README.md b/gradle-modules/gradle-8/README.md new file mode 100644 index 0000000000..53e5fa4ae0 --- /dev/null +++ b/gradle-modules/gradle-8/README.md @@ -0,0 +1,4 @@ + +### Relevant Articles: + +- [Gradle Toolchains Support for JVM Projects](https://www.baeldung.com/java-gradle-toolchains-jvm-projects) diff --git a/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties similarity index 82% rename from gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties rename to gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1e..3fa8f862f7 100644 --- a/gradle-modules/gradle-7/dependency-version/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle-7/dependency-version/gradlew b/gradle-modules/gradle-8/gradlew old mode 100755 new mode 100644 similarity index 91% rename from gradle-modules/gradle-7/dependency-version/gradlew rename to gradle-modules/gradle-8/gradlew index 79a61d421c..1aa94a4269 --- a/gradle-modules/gradle-7/dependency-version/gradlew +++ b/gradle-modules/gradle-8/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradle-modules/gradle-7/toolchains-feature/gradlew.bat b/gradle-modules/gradle-8/gradlew.bat similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/gradlew.bat rename to gradle-modules/gradle-8/gradlew.bat diff --git a/gradle-modules/gradle-8/settings.gradle b/gradle-modules/gradle-8/settings.gradle new file mode 100644 index 0000000000..f2098b2611 --- /dev/null +++ b/gradle-modules/gradle-8/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'gradle-8' + +include 'toolchains-feature' \ No newline at end of file diff --git a/gradle-modules/gradle-7/toolchains-feature/.gitattributes b/gradle-modules/gradle-8/toolchains-feature/.gitattributes similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/.gitattributes rename to gradle-modules/gradle-8/toolchains-feature/.gitattributes diff --git a/gradle-modules/gradle-7/toolchains-feature/.gitignore b/gradle-modules/gradle-8/toolchains-feature/.gitignore similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/.gitignore rename to gradle-modules/gradle-8/toolchains-feature/.gitignore diff --git a/gradle-modules/gradle-7/toolchains-feature/build.gradle b/gradle-modules/gradle-8/toolchains-feature/build.gradle similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/build.gradle rename to gradle-modules/gradle-8/toolchains-feature/build.gradle diff --git a/gradle-modules/gradle-7/toolchains-feature/settings.gradle b/gradle-modules/gradle-8/toolchains-feature/settings.gradle similarity index 100% rename from gradle-modules/gradle-7/toolchains-feature/settings.gradle rename to gradle-modules/gradle-8/toolchains-feature/settings.gradle diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradlew b/gradle-modules/gradle-customization/gradle-protobuf/gradlew old mode 100755 new mode 100644 diff --git a/gradle-modules/settings.gradle b/gradle-modules/settings.gradle index 34dbd0cf53..cfd8b14d48 100644 --- a/gradle-modules/settings.gradle +++ b/gradle-modules/settings.gradle @@ -3,3 +3,5 @@ include 'gradle' include 'gradle-5' include 'gradle-6' include 'gradle-7' +include 'gradle-8' +include 'gradle-customization' From 3ee56ca66ed6aebf9f2ba92e3eaafd4b474e089c Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sat, 4 Nov 2023 11:12:34 +0200 Subject: [PATCH 074/283] [JAVA-26735] Fixed test case --- .../primitives/PrimitiveValuesUnitTest.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java b/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java index e1241fa92a..00edcd426a 100644 --- a/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java +++ b/json-modules/gson/src/test/java/com/baeldung/gson/primitives/PrimitiveValuesUnitTest.java @@ -43,8 +43,8 @@ public class PrimitiveValuesUnitTest { gson.toJson(model); } - @Test(expected = IllegalArgumentException.class) public void - whenSerializingNaN_thenShouldRaiseAnException() { + @Test(expected = IllegalArgumentException.class) + public void whenSerializingNaN_thenShouldRaiseAnException() { FloatExample model = new FloatExample(); model.value = Float.NaN; @@ -52,7 +52,8 @@ public class PrimitiveValuesUnitTest { gson.toJson(model); } - @Test public void whenDeserializingFromJSON_thenShouldParseTheValueInTheString() { + @Test + public void whenDeserializingFromJSON_thenShouldParseTheValueInTheString() { String json = "{\"byteValue\": 17, \"shortValue\": 3, \"intValue\": 3, " + "\"longValue\": 3, \"floatValue\": 3.5" + ", \"doubleValue\": 3.5" + ", \"booleanValue\": true, \"charValue\": \"a\"}"; @@ -72,14 +73,16 @@ public class PrimitiveValuesUnitTest { // @formatter:on } - @Test public void whenDeserializingHighPrecissionNumberIntoFloat_thenShouldPerformRounding() { + @Test + public void whenDeserializingHighPrecissionNumberIntoFloat_thenShouldPerformRounding() { String json = "{\"value\": 12.123425589123456}"; Gson gson = new Gson(); FloatExample model = gson.fromJson(json, FloatExample.class); assertEquals(12.123426f, model.value, 0.000001); } - @Test public void whenDeserializingHighPrecissiongNumberIntoDouble_thenShouldPerformRounding() { + @Test + public void whenDeserializingHighPrecissiongNumberIntoDouble_thenShouldPerformRounding() { String json = "{\"value\": 12.123425589123556}"; Gson gson = new Gson(); DoubleExample model = gson.fromJson(json, DoubleExample.class); @@ -87,12 +90,12 @@ public class PrimitiveValuesUnitTest { } - @Test public void whenDeserializingValueThatOverflows_thenShouldOverflowSilently() { + @Test(expected = JsonSyntaxException.class) + public void whenDeserializingValueThatOverflows_thenShouldRaiseAnException() { Gson gson = new Gson(); String json = "{\"value\": \"300\"}"; ByteExample model = gson.fromJson(json, ByteExample.class); - assertEquals(44, model.value); } @Test public void whenDeserializingRealIntoByte_thenShouldRaiseAnException() { From df78df7a81cdef885646fde4ebf589bed857149c Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 4 Nov 2023 14:53:37 +0530 Subject: [PATCH 075/283] JAVA-26394 Move java-native to core-java modules (#15092) --- {java-native => core-java-modules/java-native}/README.md | 0 {java-native => core-java-modules/java-native}/pom.xml | 6 +++--- .../src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp | 0 .../src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h | 0 .../src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp | 0 .../src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h | 0 .../src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp | 0 .../src/main/cpp/com_baeldung_jni_HelloWorldJNI.h | 0 .../cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp | 0 .../cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h | 0 .../java-native}/src/main/cpp/generateNativeLib.bat | 0 .../java-native}/src/main/cpp/generateNativeLib.sh | 0 .../java-native}/src/main/cpp/generateNativeLibMac.sh | 0 .../com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp | 0 .../com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h | 0 .../src/main/cpp/unsatisfiedlink/generateNativeLib.sh | 0 .../java-native}/src/main/java/com/baeldung/jna/CMath.java | 0 .../java-native}/src/main/java/com/baeldung/jna/Main.java | 0 .../src/main/java/com/baeldung/jna/NativeFS.java | 0 .../java-native}/src/main/java/com/baeldung/jna/StdC.java | 0 .../src/main/java/com/baeldung/jni/ExampleObjectsJNI.java | 0 .../main/java/com/baeldung/jni/ExampleParametersJNI.java | 0 .../src/main/java/com/baeldung/jni/HelloWorldJNI.java | 0 .../java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java | 0 .../src/main/java/com/baeldung/jni/UserData.java | 0 .../main/java/com/baeldung/jvmbitversion/JVMBitVersion.java | 0 .../com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java | 0 .../java-native}/src/main/resources/logback.xml | 0 .../src/main/resources/unsatisfiedlink/jni.policy | 0 .../src/test/java/com/baeldung/jna/CMathUnitTest.java | 0 .../src/test/java/com/baeldung/jna/NativeFSUnitTest.java | 0 .../src/test/java/com/baeldung/jna/StdCUnitTest.java | 0 .../src/test/java/com/baeldung/jni/JNINativeManualTest.java | 0 .../jni/registernatives/JNIRegisterNativesManualTest.java | 0 .../com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java | 0 .../unsatisfiedlink/JniUnsatisfiedLinkManualTest.java | 0 core-java-modules/pom.xml | 1 + pom.xml | 2 -- 38 files changed, 4 insertions(+), 5 deletions(-) rename {java-native => core-java-modules/java-native}/README.md (100%) rename {java-native => core-java-modules/java-native}/pom.xml (87%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/generateNativeLib.bat (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/generateNativeLib.sh (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/generateNativeLibMac.sh (100%) mode change 100755 => 100644 rename {java-native => core-java-modules/java-native}/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h (100%) rename {java-native => core-java-modules/java-native}/src/main/cpp/unsatisfiedlink/generateNativeLib.sh (100%) mode change 100755 => 100644 rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jna/CMath.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jna/Main.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jna/NativeFS.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jna/StdC.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jni/ExampleParametersJNI.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jni/HelloWorldJNI.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jni/UserData.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java (100%) rename {java-native => core-java-modules/java-native}/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java (100%) rename {java-native => core-java-modules/java-native}/src/main/resources/logback.xml (100%) rename {java-native => core-java-modules/java-native}/src/main/resources/unsatisfiedlink/jni.policy (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jna/CMathUnitTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jna/NativeFSUnitTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jna/StdCUnitTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jni/JNINativeManualTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java (100%) rename {java-native => core-java-modules/java-native}/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java (100%) diff --git a/java-native/README.md b/core-java-modules/java-native/README.md similarity index 100% rename from java-native/README.md rename to core-java-modules/java-native/README.md diff --git a/java-native/pom.xml b/core-java-modules/java-native/pom.xml similarity index 87% rename from java-native/pom.xml rename to core-java-modules/java-native/pom.xml index 95cb24bd98..2c4a8ea4ee 100644 --- a/java-native/pom.xml +++ b/core-java-modules/java-native/pom.xml @@ -7,9 +7,9 @@ java-native - com.baeldung - parent-modules - 1.0.0-SNAPSHOT + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h diff --git a/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.cpp diff --git a/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h b/core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h similarity index 100% rename from java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h rename to core-java-modules/java-native/src/main/cpp/com_baeldung_jni_RegisterNativesHelloWorldJNI.h diff --git a/java-native/src/main/cpp/generateNativeLib.bat b/core-java-modules/java-native/src/main/cpp/generateNativeLib.bat similarity index 100% rename from java-native/src/main/cpp/generateNativeLib.bat rename to core-java-modules/java-native/src/main/cpp/generateNativeLib.bat diff --git a/java-native/src/main/cpp/generateNativeLib.sh b/core-java-modules/java-native/src/main/cpp/generateNativeLib.sh similarity index 100% rename from java-native/src/main/cpp/generateNativeLib.sh rename to core-java-modules/java-native/src/main/cpp/generateNativeLib.sh diff --git a/java-native/src/main/cpp/generateNativeLibMac.sh b/core-java-modules/java-native/src/main/cpp/generateNativeLibMac.sh old mode 100755 new mode 100644 similarity index 100% rename from java-native/src/main/cpp/generateNativeLibMac.sh rename to core-java-modules/java-native/src/main/cpp/generateNativeLibMac.sh diff --git a/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.cpp diff --git a/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/com_baeldung_unsatisfiedlink_JniUnsatisfiedLink.h diff --git a/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh b/core-java-modules/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh old mode 100755 new mode 100644 similarity index 100% rename from java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh rename to core-java-modules/java-native/src/main/cpp/unsatisfiedlink/generateNativeLib.sh diff --git a/java-native/src/main/java/com/baeldung/jna/CMath.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/CMath.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/CMath.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/CMath.java diff --git a/java-native/src/main/java/com/baeldung/jna/Main.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/Main.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/Main.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/Main.java diff --git a/java-native/src/main/java/com/baeldung/jna/NativeFS.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/NativeFS.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/NativeFS.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/NativeFS.java diff --git a/java-native/src/main/java/com/baeldung/jna/StdC.java b/core-java-modules/java-native/src/main/java/com/baeldung/jna/StdC.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jna/StdC.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jna/StdC.java diff --git a/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/ExampleParametersJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/HelloWorldJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/RegisterNativesHelloWorldJNI.java diff --git a/java-native/src/main/java/com/baeldung/jni/UserData.java b/core-java-modules/java-native/src/main/java/com/baeldung/jni/UserData.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jni/UserData.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jni/UserData.java diff --git a/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java b/core-java-modules/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java similarity index 100% rename from java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java rename to core-java-modules/java-native/src/main/java/com/baeldung/jvmbitversion/JVMBitVersion.java diff --git a/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java b/core-java-modules/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java similarity index 100% rename from java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java rename to core-java-modules/java-native/src/main/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLink.java diff --git a/java-native/src/main/resources/logback.xml b/core-java-modules/java-native/src/main/resources/logback.xml similarity index 100% rename from java-native/src/main/resources/logback.xml rename to core-java-modules/java-native/src/main/resources/logback.xml diff --git a/java-native/src/main/resources/unsatisfiedlink/jni.policy b/core-java-modules/java-native/src/main/resources/unsatisfiedlink/jni.policy similarity index 100% rename from java-native/src/main/resources/unsatisfiedlink/jni.policy rename to core-java-modules/java-native/src/main/resources/unsatisfiedlink/jni.policy diff --git a/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/CMathUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/NativeFSUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jna/StdCUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jni/JNINativeManualTest.java diff --git a/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jni/registernatives/JNIRegisterNativesManualTest.java diff --git a/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/jvmbitversion/JVMBitVersionUnitTest.java diff --git a/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java b/core-java-modules/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java similarity index 100% rename from java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java rename to core-java-modules/java-native/src/test/java/com/baeldung/unsatisfiedlink/JniUnsatisfiedLinkManualTest.java diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index bf5b90cd32..79596d2067 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -199,6 +199,7 @@ core-java-date-operations-1 core-java-httpclient + java-native diff --git a/pom.xml b/pom.xml index ab1fffa8b9..12a8f3dc1d 100644 --- a/pom.xml +++ b/pom.xml @@ -840,7 +840,6 @@ jgit jib - java-native jsoup ksqldb jsf @@ -1124,7 +1123,6 @@ jgit jib - java-native jsoup jsf ksqldb From 1baaca3e378786244dc52ce6a4ddb1e6ea0e6228 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Sat, 4 Nov 2023 10:01:25 +0000 Subject: [PATCH 076/283] [JAVA-26432] Update "Introduction to Java 8 Streams" article Clean up (#15038) --- .../streams/Java8StreamsUnitTest.java | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java index f46fa79b08..6f1cac1903 100644 --- a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/Java8StreamsUnitTest.java @@ -1,7 +1,11 @@ package com.baeldung.streams; -import org.junit.Before; -import org.junit.Test; +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 org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.nio.file.Path; import java.nio.file.Paths; @@ -11,14 +15,12 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.junit.Assert.*; +class Java8StreamsUnitTest { -public class Java8StreamsUnitTest { + private static List list; - private List list; - - @Before - public void init() { + @BeforeAll + public static void init() { list = new ArrayList<>(); list.add("One"); list.add("OneAndOnly"); @@ -42,60 +44,73 @@ public class Java8StreamsUnitTest { Stream streamOf = Stream.of("a", "b", "c"); assertEquals(streamOf.count(), 3); - long count = list.stream().distinct().count(); + long count = list.stream() + .distinct() + .count(); assertEquals(count, 9); } @Test - public void checkStreamCount_whenOperationFilter_thanCorrect() { - Stream streamFilter = list.stream().filter(element -> element.isEmpty()); + void checkStreamCount_whenOperationFilter_thanCorrect() { + Stream streamFilter = list.stream() + .filter(element -> element.isEmpty()); assertEquals(streamFilter.count(), 2); } @Test - public void checkStreamCount_whenOperationMap_thanCorrect() { + void checkStreamCount_whenOperationMap_thanCorrect() { List uris = new ArrayList<>(); uris.add("C:\\My.txt"); - Stream streamMap = uris.stream().map(uri -> Paths.get(uri)); + Stream streamMap = uris.stream() + .map(uri -> Paths.get(uri)); assertEquals(streamMap.count(), 1); List details = new ArrayList<>(); details.add(new Detail()); details.add(new Detail()); - Stream streamFlatMap = details.stream().flatMap(detail -> detail.getParts().stream()); + Stream streamFlatMap = details.stream() + .flatMap(detail -> detail.getParts() + .stream()); assertEquals(streamFlatMap.count(), 4); } @Test - public void checkStreamCount_whenOperationMatch_thenCorrect() { - boolean isValid = list.stream().anyMatch(element -> element.contains("h")); - boolean isValidOne = list.stream().allMatch(element -> element.contains("h")); - boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h")); + void checkStreamCount_whenOperationMatch_thenCorrect() { + boolean isValid = list.stream() + .anyMatch(element -> element.contains("h")); + boolean isValidOne = list.stream() + .allMatch(element -> element.contains("h")); + boolean isValidTwo = list.stream() + .noneMatch(element -> element.contains("h")); assertTrue(isValid); assertFalse(isValidOne); assertFalse(isValidTwo); } @Test - public void checkStreamReducedValue_whenOperationReduce_thenCorrect() { + void checkStreamReducedValue_whenOperationReduce_thenCorrect() { List integers = new ArrayList<>(); integers.add(1); integers.add(1); integers.add(1); - Integer reduced = integers.stream().reduce(23, (a, b) -> a + b); + Integer reduced = integers.stream() + .reduce(23, (a, b) -> a + b); assertTrue(reduced == 26); } @Test - public void checkStreamContains_whenOperationCollect_thenCorrect() { - List resultList = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList()); + void checkStreamContains_whenOperationCollect_thenCorrect() { + List resultList = list.stream() + .map(element -> element.toUpperCase()) + .collect(Collectors.toList()); assertEquals(resultList.size(), list.size()); assertTrue(resultList.contains("")); } @Test public void checkParallelStream_whenDoWork() { - list.parallelStream().forEach(element -> doWork(element)); + list.parallelStream() + .forEach(element -> doWork(element)); } private void doWork(String string) { From d9fd96773e203e27af2ff494e1d20a3a5e21bcd4 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Sat, 4 Nov 2023 13:23:42 +0000 Subject: [PATCH 077/283] [JAVA-26720] Upgraded opencsv to 5.8 version (#15126) --- core-java-modules/core-java-io-conversions-2/pom.xml | 2 +- core-java-modules/core-java-string-operations-4/pom.xml | 2 +- .../commaseparatedstring/SplitCommaSeparatedString.java | 3 ++- .../SplitCommaSeparatedStringUnitTest.java | 4 +++- libraries-data-io/pom.xml | 2 +- libraries-io/pom.xml | 2 +- spring-batch/pom.xml | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/core-java-modules/core-java-io-conversions-2/pom.xml b/core-java-modules/core-java-io-conversions-2/pom.xml index 2c49bbfd81..9be165eaff 100644 --- a/core-java-modules/core-java-io-conversions-2/pom.xml +++ b/core-java-modules/core-java-io-conversions-2/pom.xml @@ -56,7 +56,7 @@ 11 11 20200518 - 4.1 + 5.8 \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index 5cd1bd3c56..27c2bf91bd 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -58,7 +58,7 @@ 11 11 - 4.1 + 5.8 5.3.13 3.12.0 1.10.0 diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java index c3bbdb4dfb..f2ae96128c 100644 --- a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedString.java @@ -12,6 +12,7 @@ import com.opencsv.CSVParser; import com.opencsv.CSVParserBuilder; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; +import com.opencsv.exceptions.CsvException; public class SplitCommaSeparatedString { @@ -50,7 +51,7 @@ public class SplitCommaSeparatedString { return splitter.splitToList(input); } - public static List splitMultiLineWithOpenCSV(String input) throws IOException { + public static List splitMultiLineWithOpenCSV(String input) throws IOException, CsvException { CSVParser parser = new CSVParserBuilder().withSeparator(',') .build(); diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java index ca34430099..953acc6c78 100644 --- a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/commaseparatedstring/SplitCommaSeparatedStringUnitTest.java @@ -14,6 +14,8 @@ import java.util.List; import org.junit.Test; +import com.opencsv.exceptions.CsvException; + public class SplitCommaSeparatedStringUnitTest { @Test @@ -27,7 +29,7 @@ public class SplitCommaSeparatedStringUnitTest { } @Test - public void givenMultiLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() throws IOException { + public void givenMultiLineInput_whenParsing_shouldIgnoreCommasInsideDoubleQuotes() throws IOException, CsvException { String input = "baeldung,tutorial,splitting,text,\"ignoring this comma,\"" + System.lineSeparator() + "splitting,a,regular,line,no double quotes"; diff --git a/libraries-data-io/pom.xml b/libraries-data-io/pom.xml index 2e126610d4..d83357b27a 100644 --- a/libraries-data-io/pom.xml +++ b/libraries-data-io/pom.xml @@ -101,7 +101,7 @@ 1.21 4.0.1 1.7.0 - 4.1 + 5.8 1.23.0 v4-rev493-1.21.0 6.1.2 diff --git a/libraries-io/pom.xml b/libraries-io/pom.xml index fa89ebeabe..08ad0afc3f 100644 --- a/libraries-io/pom.xml +++ b/libraries-io/pom.xml @@ -59,7 +59,7 @@ 0.27.0 2.4 2.9.0 - 5.7.1 + 5.8 17 17 UTF-8 diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index 7d9becf089..20b0ef6d1c 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -74,7 +74,7 @@ 6.0.6 - 5.7.1 + 5.8 4.0.0 4.0.2 2.14.2 From 1394665355ba988ac79b65b98158fa3cd1c0eb97 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:46:09 -0400 Subject: [PATCH 078/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../ordering/SinglePartitionIntegrationTest.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 0c65618014..068d536b1a 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -68,18 +68,7 @@ public class SinglePartitionIntegrationTest { admin = Admin.create(adminProperties); - List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR); - topicList.add(newTopic); - CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(Config.SINGLE_PARTITION_TOPIC); - future.whenComplete((voidResult, exception) -> { - if (exception != null) { - System.err.println("Error creating the topic: " + exception.getMessage()); - } else { - System.out.println("Topic created successfully!"); - } - }).get(); + admin.createTopics(ImmutableList.of(new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR))).all().get(); } @AfterAll From c2453a503f9e7168469f5fa32084c632b1380913 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:46:17 -0400 Subject: [PATCH 079/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../ExtSeqWithTimeWindowIntegrationTest.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index a18efe9961..f723d290c2 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -62,18 +62,7 @@ public class ExtSeqWithTimeWindowIntegrationTest { admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); - List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR); - topicList.add(newTopic); - CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(Config.MULTI_PARTITION_TOPIC); - future.whenComplete((voidResult, exception) -> { - if (exception != null) { - System.err.println("Error creating the topic: " + exception.getMessage()); - } else { - System.out.println("Topic created successfully!"); - } - }).get(); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))).all().get(); } @AfterAll From e5da66643251d2f66eecd0ca3d607e10fa143179 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:49:26 -0400 Subject: [PATCH 080/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../ordering/MultiplePartitionIntegrationTest.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index 64a063c6c9..88281014b6 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -60,18 +60,7 @@ public class MultiplePartitionIntegrationTest { admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); - List topicList = new ArrayList<>(); - NewTopic newTopic = new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR); - topicList.add(newTopic); - CreateTopicsResult result = admin.createTopics(topicList); - KafkaFuture future = result.values().get(Config.MULTI_PARTITION_TOPIC); - future.whenComplete((voidResult, exception) -> { - if (exception != null) { - System.err.println("Error creating the topic: " + exception.getMessage()); - } else { - System.out.println("Topic created successfully!"); - } - }).get(); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))).all().get(); } @AfterAll From 41ab2ed2213b8a20fbeb8f3ee52357757b552e31 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:55:03 -0400 Subject: [PATCH 081/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java Co-authored-by: Liam Williams --- .../com/baeldung/kafka/message/ordering/payload/UserEvent.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java index 0c4018e624..040c7d6995 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -3,9 +3,7 @@ package com.baeldung.kafka.message.ordering.payload; import java.util.Objects; public class UserEvent implements Comparable { private String userEventId; - private long eventNanoTime; - private long globalSequenceNumber; public UserEvent(){ From 0399cf0e5f0d788367d5209def3ad41be8ae92d3 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:55:32 -0400 Subject: [PATCH 082/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java Co-authored-by: Liam Williams --- .../baeldung/kafka/message/ordering/payload/UserEvent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java index 040c7d6995..67e6b70c08 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -6,11 +6,11 @@ public class UserEvent implements Comparable { private long eventNanoTime; private long globalSequenceNumber; + @SuppressWarnings("unused") public UserEvent(){ - + // Required for Jackson Serialization and Deserialization } - //Required for Kafka Serialization and Deserialization public UserEvent(String userEventId) { this.userEventId = userEventId; } From d4842ac511422a11dd746d07d337fe9dda74e76f Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:56:07 -0400 Subject: [PATCH 083/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java Co-authored-by: Liam Williams --- .../message/ordering/serialization/JacksonDeserializer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index be2b104761..2cc0bde853 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -8,7 +8,6 @@ import java.util.Map; /** * Configured via {@link org.apache.kafka.clients.consumer.ConsumerConfig#VALUE_DESERIALIZER_CLASS_CONFIG} */ -@SuppressWarnings("unused") public class JacksonDeserializer implements Deserializer { private final ObjectMapper objectMapper = new ObjectMapper(); private Class type; From aeb5f55e0e27a67aaa18fd756fdf21664e56f6d4 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:56:47 -0400 Subject: [PATCH 084/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java Co-authored-by: Liam Williams --- .../message/ordering/serialization/JacksonDeserializer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 2cc0bde853..300a43ca7c 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -33,9 +33,8 @@ public class JacksonDeserializer implements Deserializer { try { return objectMapper.readValue(bytes, type); } catch (Exception e) { - //throw new RuntimeException("Error deserializing value", e); + throw new RuntimeException("Error deserializing value", e); } - return null; } } From 9a76f1a6375eceba23f8ce24748db06e9c1519f8 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:57:02 -0400 Subject: [PATCH 085/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../message/ordering/ExtSeqWithTimeWindowIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index f723d290c2..e9a77bd2d7 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -29,7 +29,7 @@ import java.util.concurrent.Future; import static org.junit.jupiter.api.Assertions.*; @Testcontainers -public class ExtSeqWithTimeWindowIntegrationTest { +public class ExternalSequenceWithTimeWindowIntegrationTest { private static Admin admin; private static KafkaProducer producer; From 33b18c0ca49d4814eb032df2122dc302e2bb5ebf Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:57:19 -0400 Subject: [PATCH 086/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../message/ordering/ExtSeqWithTimeWindowIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index e9a77bd2d7..f47a01486c 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -92,7 +92,7 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { records.forEach(record -> { buffer.add(record.value()); }); - while (buffer.size() > 0) { + while (!buffer.isEmpty()) { if (System.nanoTime() - lastProcessedTime > BUFFER_PERIOD_NS) { processBuffer(buffer, receivedUserEventList); lastProcessedTime = System.nanoTime(); From 3e2975196d8842459acfaa23d4b22b86e5d08f1b Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:57:32 -0400 Subject: [PATCH 087/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java Co-authored-by: Liam Williams --- .../ExtSeqWithTimeWindowIntegrationTest.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java index f47a01486c..76e4a47d17 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java @@ -102,16 +102,9 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { buffer.add(record.value()); }); } - for (int insertPosition = 0; insertPosition <= receivedUserEventList.size() - 1; insertPosition++) { - if (isOrderMaintained){ - UserEvent sentUserEvent = sentUserEventList.get(insertPosition); - UserEvent receivedUserEvent = receivedUserEventList.get(insertPosition); - if (!sentUserEvent.equals(receivedUserEvent)) { - isOrderMaintained = false; - } - } - } - assertTrue(isOrderMaintained); + assertThat(receivedUserEventList) + .isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); } private static void processBuffer(List buffer, List receivedUserEventList) { From 9c463c752b17ca3843490cef337a44f1a96f07f3 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:57:47 -0400 Subject: [PATCH 088/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../ordering/MultiplePartitionIntegrationTest.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index 88281014b6..752514c09a 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -89,15 +89,8 @@ public class MultiplePartitionIntegrationTest { receivedUserEventList.add(userEvent); System.out.println("User Event ID: " + userEvent.getUserEventId()); }); - for (int insertPosition = 0; insertPosition <= receivedUserEventList.size() - 1; insertPosition++) { - if (isOrderMaintained){ - UserEvent sentUserEvent = sentUserEventList.get(insertPosition); - UserEvent receivedUserEvent = receivedUserEventList.get(insertPosition); - if (!sentUserEvent.equals(receivedUserEvent)) { - isOrderMaintained = false; - } - } - } - assertFalse(isOrderMaintained); + assertThat(receivedUserEventList) + .isNotEqualTo(sentUserEventList) + .containsExactlyInAnyOrderElementsOf(sentUserEventList); } } From ddc5e0a5efbfb15a8a19c6bf0b91a2986883efbe Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:58:01 -0400 Subject: [PATCH 089/283] Update apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java Co-authored-by: Liam Williams --- .../ordering/SinglePartitionIntegrationTest.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 068d536b1a..a767133627 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -97,14 +97,8 @@ public class SinglePartitionIntegrationTest { receivedUserEventList.add(userEvent); System.out.println("User Event ID: " + userEvent.getUserEventId()); }); - boolean result = true; - for (int count = 0; count <= 9; count++) { - UserEvent sentUserEvent = sentUserEventList.get(count); - UserEvent receivedUserEvent = receivedUserEventList.get(count); - if (!sentUserEvent.equals(receivedUserEvent) && result) { - result = false; - } - } - assertTrue(result); + assertThat(receivedUserEventList) + .isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); } } From cb274a7ed4a86fbdb1fa129d1a68c31d316a8011 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:58:28 -0400 Subject: [PATCH 090/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java Co-authored-by: Liam Williams --- .../kafka/message/ordering/serialization/JacksonSerializer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java index 2d7432cc7b..4c081de3cc 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java @@ -6,7 +6,6 @@ import org.apache.kafka.common.serialization.Serializer; /** * Configured via {@link org.apache.kafka.clients.producer.ProducerConfig#VALUE_SERIALIZER_CLASS_CONFIG} */ -@SuppressWarnings("unused") public class JacksonSerializer implements Serializer { private final ObjectMapper objectMapper = new ObjectMapper(); From b24851bfcee4223b94d51e5b3d2d079824f8cb09 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 16:59:10 -0400 Subject: [PATCH 091/283] Update apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java Co-authored-by: Liam Williams --- .../ordering/serialization/JacksonDeserializer.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 300a43ca7c..4868ecaf2e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -12,13 +12,6 @@ public class JacksonDeserializer implements Deserializer { private final ObjectMapper objectMapper = new ObjectMapper(); private Class type; - public JacksonDeserializer(Class type) { - this.type = type; - } - - public JacksonDeserializer() { - - } @Override public void configure(Map configs, boolean isKey) { From 2cecae1dfb6af13c311e48d89dfc38d1f70ba181 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 17:18:20 -0400 Subject: [PATCH 092/283] Incorporate Review comments --- .../com/baeldung/kafka/message/ordering/Config.java | 2 +- ...ternalSequenceWithTimeWindowIntegrationTest.java} | 12 +++++------- .../ordering/MultiplePartitionIntegrationTest.java | 7 +++---- .../ordering/SinglePartitionIntegrationTest.java | 6 ++---- 4 files changed, 11 insertions(+), 16 deletions(-) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{ExtSeqWithTimeWindowIntegrationTest.java => ExternalSequenceWithTimeWindowIntegrationTest.java} (95%) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java index 9cc6314309..7fae8403b5 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/Config.java @@ -7,5 +7,5 @@ public class Config { public static final int MULTIPLE_PARTITIONS = 5; public static final int SINGLE_PARTITION = 1; - public static short REPLICATION_FACTOR = 1; + public static final short REPLICATION_FACTOR = 1; } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java similarity index 95% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java index 76e4a47d17..0c64f663f3 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExtSeqWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java @@ -11,7 +11,6 @@ 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.KafkaFuture; import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; @@ -25,8 +24,8 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; - -import static org.junit.jupiter.api.Assertions.*; +import com.google.common.collect.ImmutableList; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers public class ExternalSequenceWithTimeWindowIntegrationTest { @@ -84,7 +83,6 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } - boolean isOrderMaintained = true; consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); List buffer = new ArrayList<>(); long lastProcessedTime = System.nanoTime(); @@ -102,9 +100,9 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { buffer.add(record.value()); }); } - assertThat(receivedUserEventList) - .isEqualTo(sentUserEventList) - .containsExactlyElementsOf(sentUserEventList); + assertThat(receivedUserEventList) + .isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); } private static void processBuffer(List buffer, List receivedUserEventList) { diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index 752514c09a..2fde24114c 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -11,7 +11,6 @@ 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.KafkaFuture; import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; @@ -25,8 +24,8 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; - -import static org.junit.jupiter.api.Assertions.*; +import com.google.common.collect.ImmutableList; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers public class MultiplePartitionIntegrationTest { @@ -89,7 +88,7 @@ public class MultiplePartitionIntegrationTest { receivedUserEventList.add(userEvent); System.out.println("User Event ID: " + userEvent.getUserEventId()); }); - assertThat(receivedUserEventList) + assertThat(receivedUserEventList) .isNotEqualTo(sentUserEventList) .containsExactlyInAnyOrderElementsOf(sentUserEventList); } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index a767133627..0826365f97 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -5,7 +5,6 @@ import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.clients.admin.AdminClientConfig; -import org.apache.kafka.clients.admin.CreateTopicsResult; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -14,7 +13,6 @@ 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.KafkaFuture; import org.apache.kafka.common.serialization.LongDeserializer; import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; @@ -29,8 +27,8 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; - -import static org.junit.jupiter.api.Assertions.assertTrue; +import com.google.common.collect.ImmutableList; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers public class SinglePartitionIntegrationTest { From 2a6e561f769cd38cfa43c2c1d7742a24b43e52d7 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 18:09:21 -0400 Subject: [PATCH 093/283] Fixed unit test case failures --- .../kafka/message/ordering/payload/UserEvent.java | 10 +++++++--- .../ordering/MultiplePartitionIntegrationTest.java | 6 +++--- .../ordering/SinglePartitionIntegrationTest.java | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java index 67e6b70c08..676b469ce8 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -42,15 +42,19 @@ public class UserEvent implements Comparable { @Override public boolean equals(Object obj) { - if (obj == this) { + if (this == obj) { return true; } if (!(obj instanceof UserEvent)) { return false; } UserEvent userEvent = (UserEvent) obj; - return Objects.equals(this.userEventId, userEvent.getUserEventId()) - && userEvent.getEventNanoTime() == this.eventNanoTime; + return this.globalSequenceNumber == userEvent.globalSequenceNumber; + } + + @Override + public int hashCode() { + return Objects.hash(globalSequenceNumber); } } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index 2fde24114c..0405184074 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -71,16 +71,16 @@ public class MultiplePartitionIntegrationTest { void givenMultiplePartitions_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); - for (long count = 1; count <= 10 ; count++) { + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setGlobalSequenceNumber(sequenceNumber); userEvent.setEventNanoTime(System.nanoTime()); - Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, count, userEvent)); + Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } - boolean isOrderMaintained = true; consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); ConsumerRecords records = consumer.poll(TIMEOUT_WAIT_FOR_MESSAGES); records.forEach(record -> { diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 0826365f97..39d298826c 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -78,8 +78,9 @@ public class SinglePartitionIntegrationTest { void givenASinglePartition_whenPublishedToKafkaAndConsumed_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); - for (long count = 1; count <= 10; count++) { + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + userEvent.setGlobalSequenceNumber(sequenceNumber); userEvent.setEventNanoTime(System.nanoTime()); ProducerRecord producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent); Future future = producer.send(producerRecord); From 80cd71fff3e37122a22884fa85b394537e709e20 Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sat, 4 Nov 2023 18:33:09 -0400 Subject: [PATCH 094/283] Removing slf4j-log4j12, deleting log4j.properties and adding a standard src/test/resources/logback.xml, since the Kafka libraries use the logback SLF4J binding. --- apache-kafka-2/log4j.properties | 1 - apache-kafka-2/pom.xml | 5 ----- ...ExternalSequenceWithTimeWindowIntegrationTest.java | 9 +++++++-- .../ordering/MultiplePartitionIntegrationTest.java | 8 ++++++-- .../ordering/SinglePartitionIntegrationTest.java | 7 +++++-- apache-kafka-2/src/test/resources/logback.xml | 11 +++++++++++ 6 files changed, 29 insertions(+), 12 deletions(-) delete mode 100644 apache-kafka-2/log4j.properties create mode 100644 apache-kafka-2/src/test/resources/logback.xml diff --git a/apache-kafka-2/log4j.properties b/apache-kafka-2/log4j.properties deleted file mode 100644 index 2173c5d96f..0000000000 --- a/apache-kafka-2/log4j.properties +++ /dev/null @@ -1 +0,0 @@ -log4j.rootLogger=INFO, stdout diff --git a/apache-kafka-2/pom.xml b/apache-kafka-2/pom.xml index d0838a386e..d1f74e8aae 100644 --- a/apache-kafka-2/pom.xml +++ b/apache-kafka-2/pom.xml @@ -23,11 +23,6 @@ slf4j-api ${org.slf4j.version} - - org.slf4j - slf4j-log4j12 - ${org.slf4j.version} - com.google.guava guava diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java index 0c64f663f3..a5ec7a98a3 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java @@ -1,5 +1,6 @@ package com.baeldung.kafka.message.ordering; +import com.baeldung.kafka.headers.KafkaMessageHeaders; import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; @@ -16,6 +17,8 @@ import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -36,6 +39,8 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5).toNanos(); + private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowIntegrationTest.class); + @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); @@ -80,7 +85,7 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); @@ -109,7 +114,7 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { Collections.sort(buffer); buffer.forEach(userEvent -> { receivedUserEventList.add(userEvent); - System.out.println("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); + logger.info("Processing message with Global Sequence number: " + userEvent.getGlobalSequenceNumber() + ", User Event Id: " + userEvent.getUserEventId()); }); buffer.clear(); } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index 0405184074..adfa9a0399 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -16,6 +16,8 @@ import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -34,6 +36,8 @@ public class MultiplePartitionIntegrationTest { private static KafkaProducer producer; private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); + + private static Logger logger = LoggerFactory.getLogger(MultiplePartitionIntegrationTest.class); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); @@ -78,7 +82,7 @@ public class MultiplePartitionIntegrationTest { Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } consumer.subscribe(Collections.singletonList(Config.MULTI_PARTITION_TOPIC)); @@ -86,7 +90,7 @@ public class MultiplePartitionIntegrationTest { records.forEach(record -> { UserEvent userEvent = record.value(); receivedUserEventList.add(userEvent); - System.out.println("User Event ID: " + userEvent.getUserEventId()); + logger.info("User Event ID: " + userEvent.getUserEventId()); }); assertThat(receivedUserEventList) .isNotEqualTo(sentUserEventList) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 39d298826c..7280a1218a 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -18,6 +18,8 @@ import org.apache.kafka.common.serialization.LongSerializer; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -39,6 +41,7 @@ public class SinglePartitionIntegrationTest { private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); + private static Logger logger = LoggerFactory.getLogger(SinglePartitionIntegrationTest.class); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); @@ -86,7 +89,7 @@ public class SinglePartitionIntegrationTest { Future future = producer.send(producerRecord); sentUserEventList.add(userEvent); RecordMetadata metadata = future.get(); - System.out.println("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); + logger.info("User Event ID: " + userEvent.getUserEventId() + ", Partition : " + metadata.partition()); } consumer.subscribe(Collections.singletonList(Config.SINGLE_PARTITION_TOPIC)); @@ -94,7 +97,7 @@ public class SinglePartitionIntegrationTest { records.forEach(record -> { UserEvent userEvent = record.value(); receivedUserEventList.add(userEvent); - System.out.println("User Event ID: " + userEvent.getUserEventId()); + logger.info("User Event ID: " + userEvent.getUserEventId()); }); assertThat(receivedUserEventList) .isEqualTo(sentUserEventList) diff --git a/apache-kafka-2/src/test/resources/logback.xml b/apache-kafka-2/src/test/resources/logback.xml new file mode 100644 index 0000000000..6156c2188e --- /dev/null +++ b/apache-kafka-2/src/test/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file From cea912e42ff8fc40bac122b0e78625f5ca92811a Mon Sep 17 00:00:00 2001 From: Vladyslav Chernov Date: Sat, 4 Nov 2023 15:33:30 -0700 Subject: [PATCH 095/283] BAEL-5852: remove comments --- .../src/main/java/com/baeldung/holder/SupplierService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java index 473a4de423..66889f99bf 100644 --- a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java +++ b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java @@ -2,8 +2,6 @@ package com.baeldung.holder; public class SupplierService { public void getSupplierByZipCode(String zip, Holder resultHolder) { - // Let's pretend we did some work here to get the supplier - // And let's say all zip codes starting with "9" are valid, just for this example if (zip.startsWith("9")) { resultHolder.value = true; } else { From ee97389e28c04795bd0c45a543a5eebfce05429f Mon Sep 17 00:00:00 2001 From: Vladyslav Chernov Date: Sat, 4 Nov 2023 15:38:37 -0700 Subject: [PATCH 096/283] BAEL-5755: remove BAEL-5852 commits --- .../main/java/com/baeldung/holder/Holder.java | 9 ------ .../com/baeldung/holder/SupplierService.java | 11 ------- .../holder/SupplierServiceUnitTest.java | 31 ------------------- 3 files changed, 51 deletions(-) delete mode 100644 core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java delete mode 100644 core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java delete mode 100644 core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java deleted file mode 100644 index da066ee5c6..0000000000 --- a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/Holder.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.holder; - -public class Holder { - public T value; - - public Holder(T value) { - this.value = value; - } -} diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java deleted file mode 100644 index 66889f99bf..0000000000 --- a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/holder/SupplierService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.holder; - -public class SupplierService { - public void getSupplierByZipCode(String zip, Holder resultHolder) { - if (zip.startsWith("9")) { - resultHolder.value = true; - } else { - resultHolder.value = false; - } - } -} diff --git a/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java deleted file mode 100644 index e1446fc229..0000000000 --- a/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/holder/SupplierServiceUnitTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.baeldung.holder; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -public class SupplierServiceUnitTest { - - @Test - public void givenValidZipCode_whenGetSupplierByZipCode_thenTrue() { - SupplierService service = new SupplierService(); - Holder resultHolder = new Holder<>(false); - String zipCode = "98682"; - - service.getSupplierByZipCode(zipCode, resultHolder); - - assertTrue(resultHolder.value); - } - - @Test - public void givenInvalidZipCode_whenGetSupplierByZipCode_thenFalse() { - SupplierService service = new SupplierService(); - Holder resultHolder = new Holder<>(true); - String zipCode = "12345"; - - service.getSupplierByZipCode(zipCode, resultHolder); - - assertFalse(resultHolder.value); - } -} From 89744aff6c5287bd014140e0698c39b45f379293 Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Sun, 5 Nov 2023 05:06:13 +0200 Subject: [PATCH 097/283] This commit is related to BAEL-7161 (#15132) This commit aims to add a test class "StreamToMapAndMultiMapUnitTest" that provides several approaches to convert Java stream to Map or MultiMap. --- .../StreamToMapAndMultiMapUnitTest.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java new file mode 100644 index 0000000000..4d957fd704 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java @@ -0,0 +1,100 @@ +package com.baeldung.streamtomapandmultimap; + +import com.google.common.collect.LinkedHashMultimap; +import org.junit.Test; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +public class StreamToMapAndMultiMapUnitTest { + @Test + public void givenStringStream_whenConvertingToMapWithMerge_thenExpectedMapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map mergedMap = stringStream.collect( + Collectors.toMap(s -> s, s -> s, (s1, s2) -> s1 + ", " + s2) + ); + + // Define the expected map + Map expectedMap = Map.of( + "one", "one", + "two", "two, two", + "three", "three" + ); + + assertEquals(expectedMap, mergedMap); + } + + @Test + public void givenStringStream_whenConvertingToMultimap_thenExpectedMultimapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + LinkedHashMultimap multimap = LinkedHashMultimap.create(); + + stringStream.collect(Collectors.groupingBy( + s -> s, + Collectors.mapping(s -> s, Collectors.toList()) + )).forEach((key, value) -> multimap.putAll(key, value)); + + LinkedHashMultimap expectedMultimap = LinkedHashMultimap.create(); + expectedMultimap.put("one", "one"); + expectedMultimap.put("two", "two"); + expectedMultimap.put("three", "three"); + + assertEquals(expectedMultimap, multimap); + } + + @Test + public void givenStringStream_whenConvertingToMultimapWithStreamReduce_thenExpectedMultimapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map> multimap = stringStream.reduce( + new HashMap<>(), + (map, element) -> { + map.computeIfAbsent(element, k -> new ArrayList<>()).add(element); + return map; + }, + (map1, map2) -> { + map2.forEach((key, value) -> map1.merge(key, value, (list1, list2) -> { + list1.addAll(list2); + return list1; + })); + return map1; + } + ); + + Map> expectedMultimap = new HashMap<>(); + expectedMultimap.put("one", Collections.singletonList("one")); + expectedMultimap.put("two", Arrays.asList("two", "two")); + expectedMultimap.put("three", Collections.singletonList("three")); + + assertEquals(expectedMultimap, multimap); + } + + @Test + public void givenStringStream_whenConvertingToMapWithStreamReduce_thenExpectedMapIsGenerated() { + Stream stringStream = Stream.of("one", "two", "three", "two"); + + Map resultMap = stringStream.reduce( + new HashMap<>(), + (map, element) -> { + map.put(element, element); + return map; + }, + (map1, map2) -> { + map1.putAll(map2); + return map1; + } + ); + + Map expectedMap = new HashMap<>(); + expectedMap.put("one", "one"); + expectedMap.put("two", "two"); + expectedMap.put("three", "three"); + + assertEquals(expectedMap, resultMap); + } +} \ No newline at end of file From 88a874082de402224520387bfb59d2ed05c0eb78 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 12:49:07 +0800 Subject: [PATCH 098/283] Update README.md [skip ci] --- core-java-modules/core-java-strings/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-strings/README.md b/core-java-modules/core-java-strings/README.md index dbbfcc79b6..e782793fea 100644 --- a/core-java-modules/core-java-strings/README.md +++ b/core-java-modules/core-java-strings/README.md @@ -15,3 +15,4 @@ Listed here there are only those articles that does not fit into other core-java - [Java Multi-line String](https://www.baeldung.com/java-multiline-string) - [Reuse StringBuilder for Efficiency](https://www.baeldung.com/java-reuse-stringbuilder-for-efficiency) - [How to Iterate Over the String Characters in Java](https://www.baeldung.com/java-iterate-string-characters) +- [Passing Strings by Reference in Java](https://www.baeldung.com/java-method-pass-string-reference) From 252696e2b3572fed41fee8cd65e51ef483ddc010 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 12:58:15 +0800 Subject: [PATCH 099/283] Update README.md [skip ci] --- core-java-modules/core-java-concurrency-basic-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 179a69495c..09d085a32b 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency. - [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool) - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) +- [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert) - [[<-- Prev]](../core-java-concurrency-basic-2) From 67d1902524af4d229dd672b8fb1b57fac0cd68de Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:02:33 +0800 Subject: [PATCH 100/283] Update README.md [skip ci] --- core-java-modules/core-java-io-apis-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 3ec3220424..043e0c1ee3 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -8,3 +8,4 @@ This module contains articles about core Java input/output(IO) APIs. - [Check if a File Is Empty in Java](https://www.baeldung.com/java-check-file-empty) - [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths) - [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file) +- [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference) From 9d7705309e0e2453b128b000bb8a10939866fdde Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:08:59 +0800 Subject: [PATCH 101/283] Create README.md [skip ci] --- persistence-modules/spring-jdbc-2/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 persistence-modules/spring-jdbc-2/README.md diff --git a/persistence-modules/spring-jdbc-2/README.md b/persistence-modules/spring-jdbc-2/README.md new file mode 100644 index 0000000000..5edb34f4c5 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [A Guide to Spring 6 JdbcClient API](https://www.baeldung.com/spring-6-jdbcclient-api) From 686196c0402c773681add1669951be7ebc86b56c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:16:48 +0800 Subject: [PATCH 102/283] Update README.md [skip ci] --- core-java-modules/core-java-io-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-5/README.md b/core-java-modules/core-java-io-5/README.md index 3cc514e087..4578cf3777 100644 --- a/core-java-modules/core-java-io-5/README.md +++ b/core-java-modules/core-java-io-5/README.md @@ -5,5 +5,6 @@ This module contains articles about core Java input and output (IO) ### Relevant Articles: - [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension) - [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks) +- [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream) - [[<-- Prev]](/core-java-modules/core-java-io-4) From 4ee135819b1b11dc3b1cd6505fc8602d3c85afc0 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:24:26 +0800 Subject: [PATCH 103/283] Create README.md [skip ci] --- libraries-llms/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 libraries-llms/README.md diff --git a/libraries-llms/README.md b/libraries-llms/README.md new file mode 100644 index 0000000000..78a621ffa6 --- /dev/null +++ b/libraries-llms/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Introduction to LangChain](https://www.baeldung.com/java-langchain-basics) From ac7cedb7efabac67821b43ad7bb39b9c22d7942a Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:30:32 +0800 Subject: [PATCH 104/283] Update README.md [skip ci] --- xml-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/xml-2/README.md b/xml-2/README.md index e91078dbf0..cc60ae2764 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -7,3 +7,4 @@ This module contains articles about eXtensible Markup Language (XML) - [Pretty-Print XML in Java](https://www.baeldung.com/java-pretty-print-xml) - [Validate an XML File Against an XSD File](https://www.baeldung.com/java-validate-xml-xsd) - [Converting JSON to XML in Java](https://www.baeldung.com/java-convert-json-to-xml) +- [Convert an XML Object to a String in Java](https://www.baeldung.com/java-convert-xml-object-string) From 0391a9c840e86573800ad1032b9a58142b45f5bc Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:35:00 +0800 Subject: [PATCH 105/283] Update README.md [skip ci] --- xml-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/xml-2/README.md b/xml-2/README.md index cc60ae2764..e9c1a07586 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -8,3 +8,4 @@ This module contains articles about eXtensible Markup Language (XML) - [Validate an XML File Against an XSD File](https://www.baeldung.com/java-validate-xml-xsd) - [Converting JSON to XML in Java](https://www.baeldung.com/java-convert-json-to-xml) - [Convert an XML Object to a String in Java](https://www.baeldung.com/java-convert-xml-object-string) +- [Convert String Containing XML to org.w3c.dom.Document](https://www.baeldung.com/java-convert-string-xml-dom) From 4f98043b953827532f27fb51131def85edaeaa01 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:39:48 +0800 Subject: [PATCH 106/283] Update README.md [skip ci] --- spring-cucumber/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cucumber/README.md b/spring-cucumber/README.md index 85bc1f65d5..87623b28d4 100644 --- a/spring-cucumber/README.md +++ b/spring-cucumber/README.md @@ -4,3 +4,4 @@ This module contains articles about Spring testing with Cucumber ### Relevant Articles: - [Cucumber Spring Integration](https://www.baeldung.com/cucumber-spring-integration) +- [Overriding Cucumber Option Values](https://www.baeldung.com/java-overriding-cucumber-option-values) From 9ba05068aa4aab95407db2dd16079078f54bf750 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sun, 5 Nov 2023 13:45:06 +0800 Subject: [PATCH 107/283] Create README.md [skip ci] --- .../src/test/java/com/baeldung/algorithms/connect4/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md new file mode 100644 index 0000000000..55bc2abec5 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) From 0fc112e6134f91cf528f92bfeac4654e1742bedc Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Sun, 5 Nov 2023 02:45:44 -0300 Subject: [PATCH 108/283] BAEL 6701 - MongoDB - Atlas Search using the Java Driver and Spring Data (#15069) * research 1 * new search methods * first draft * removing old code * updated to parent-boot-3 * mongo review 2 --- .../service/MovieAtlasSearchService.java | 48 +++++++++---------- .../web/MovieAtlasSearchController.java | 4 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java index 55d47759d5..90de7b3d1d 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/service/MovieAtlasSearchService.java @@ -11,13 +11,12 @@ import static com.mongodb.client.model.Projections.excludeId; import static com.mongodb.client.model.Projections.fields; import static com.mongodb.client.model.Projections.include; import static com.mongodb.client.model.Projections.metaSearchScore; +import static com.mongodb.client.model.search.SearchCollector.facet; import static com.mongodb.client.model.search.SearchCount.total; -import static com.mongodb.client.model.search.SearchFacet.combineToBson; import static com.mongodb.client.model.search.SearchFacet.numberFacet; import static com.mongodb.client.model.search.SearchFacet.stringFacet; import static com.mongodb.client.model.search.SearchOperator.compound; import static com.mongodb.client.model.search.SearchOperator.numberRange; -import static com.mongodb.client.model.search.SearchOperator.of; import static com.mongodb.client.model.search.SearchOperator.text; import static com.mongodb.client.model.search.SearchOptions.searchOptions; import static com.mongodb.client.model.search.SearchPath.fieldPath; @@ -67,7 +66,7 @@ public class MovieAtlasSearchService { builder.append("]"); LogManager.getLogger(MovieAtlasSearchService.class) - .debug(builder.toString()); + .debug(builder.toString()); } public Document late90sMovies(int skip, int limit, String keywords, SearchScore modifier) { @@ -130,7 +129,7 @@ public class MovieAtlasSearchService { debug(pipeline); return collection.aggregate(pipeline) - .first(); + .first(); } public Collection moviesByKeywords(String keywords) { @@ -150,34 +149,33 @@ public class MovieAtlasSearchService { debug(pipeline); return collection.aggregate(pipeline) - .into(new ArrayList()); + .into(new ArrayList<>()); } public Document genresThroughTheDecades(String genre) { List pipeline = asList( - searchMeta(of( - new Document("facet", - new Document("operator", - text( - fieldPath("genres"), genre - ) - ).append("facets", combineToBson(asList( - stringFacet("genresFacet", - fieldPath("genres") - ).numBuckets(5), - numberFacet("yearFacet", - fieldPath("year"), - asList(1900, 1930, 1960, 1990, 2020) - ) - ))) - )), - searchOptions() - .index(config.getFacetIndex()) + searchMeta( + facet( + text( + fieldPath("genres"), genre + ), + asList( + stringFacet("genresFacet", + fieldPath("genres") + ).numBuckets(5), + numberFacet("yearFacet", + fieldPath("year"), + asList(1900, 1930, 1960, 1990, 2020) + ) + ) + ), + searchOptions() + .index(config.getFacetIndex()) ) ); - + debug(pipeline); return collection.aggregate(pipeline) - .first(); + .first(); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java index 4c41915347..af8640179f 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/atlassearch/web/MovieAtlasSearchController.java @@ -1,5 +1,7 @@ package com.baeldung.boot.atlassearch.web; +import static com.mongodb.client.model.search.SearchPath.fieldPath; + import java.util.Collection; import org.bson.Document; @@ -33,7 +35,7 @@ public class MovieAtlasSearchController { @GetMapping("90s/{skip}/{limit}/with/{keywords}") Document getMoviesUsingScoreBoost(@PathVariable int skip, @PathVariable int limit, @PathVariable String keywords) { - return service.late90sMovies(skip, limit, keywords, SearchScore.boost(2)); + return service.late90sMovies(skip, limit, keywords, SearchScore.boost(fieldPath("imdb.votes"))); } @PostMapping("90s/{skip}/{limit}/with/{keywords}") From dad8f5cf2b58a7fa83e430743488a44f8ac02576 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 5 Nov 2023 11:48:26 +0530 Subject: [PATCH 109/283] JAVA-27180 Upgrade hibernate-validator version in hibernate-mapping module --- persistence-modules/hibernate-mapping/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index 1e3dc8be5f..0ce112b9e6 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -20,7 +20,7 @@ test - org.hibernate + org.hibernate.orm hibernate-core ${hibernate.version} @@ -36,7 +36,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -82,7 +82,7 @@ 2.1.214 6.1.7.Final 2.21.1 - 8.0.0.Final + 8.0.1.Final 3.0.1-b11 1.1 1.4.2 From a8af97e2eb5f534576447dddacc6ce8c79e206b5 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 5 Nov 2023 12:40:54 +0530 Subject: [PATCH 110/283] JAVA-27181 Update hibernate-validator version in jpa-hibarnate-cascade-type module --- .../jpa-hibernate-cascade-type/pom.xml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/persistence-modules/jpa-hibernate-cascade-type/pom.xml b/persistence-modules/jpa-hibernate-cascade-type/pom.xml index fd0ae117c7..90dd826a6e 100644 --- a/persistence-modules/jpa-hibernate-cascade-type/pom.xml +++ b/persistence-modules/jpa-hibernate-cascade-type/pom.xml @@ -24,27 +24,15 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish - javax.el - ${org.glassfish.javax.el.version} - 5.4.3.Final - 6.0.17.Final - 3.0.0 - 3.0.1-b11 + 8.0.1.Final \ No newline at end of file From 9e0b0945f7820d8e431b44c49f3a47a2d70be952 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 5 Nov 2023 13:05:01 +0530 Subject: [PATCH 111/283] JAVA-27182 Upgrade hibernate-validator version in spring-data-couchbase-2 module --- persistence-modules/spring-data-couchbase-2/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-data-couchbase-2/pom.xml b/persistence-modules/spring-data-couchbase-2/pom.xml index deb7d3b524..45462d477e 100644 --- a/persistence-modules/spring-data-couchbase-2/pom.xml +++ b/persistence-modules/spring-data-couchbase-2/pom.xml @@ -40,7 +40,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -71,7 +71,7 @@ 6.0.6 5.0.3 - 8.0.0.Final + 8.0.1.Final 2.12.2 From a575de93b1025cf723f87f98ebbbfe45bc2a6952 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 5 Nov 2023 13:36:30 +0530 Subject: [PATCH 112/283] JAVA-27183 Upgrade hibernate-validator version in spring-jpa module --- persistence-modules/spring-jpa/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index c08e4f823a..10e44c0ce4 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -71,7 +71,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -122,7 +122,7 @@ 6.0.0 - 8.0.0.Final + 8.0.1.Final 2.0.2 2.1.214 5.0.0 From 790ec2b7fb71711ab9a8c793b6d101ac3e27cae8 Mon Sep 17 00:00:00 2001 From: timis1 Date: Sun, 5 Nov 2023 23:27:26 +0200 Subject: [PATCH 113/283] JAVA-27237 Review log statements for projects - Week 16 - 2023 (moved-13) (conti-1) --- .../test/resources/META-INF/persistence.xml | 2 +- .../src/test/resources/logback-test.xml | 2 +- .../src/test/resources/logback-test.xml | 2 ++ .../config/src/main/resources/logback.xml | 6 ++++++ .../src/main/resources/logback.xml | 18 +++++++++++++++++ .../src/main/resources/logback.xml | 20 +++++++++++++++++++ .../src/test/resources/logback-test.xml | 6 ++++++ 7 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml create mode 100644 spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml diff --git a/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml b/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml index ffcf20878c..60b415abd7 100644 --- a/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml +++ b/persistence-modules/deltaspike/src/test/resources/META-INF/persistence.xml @@ -35,7 +35,7 @@ - + diff --git a/persistence-modules/deltaspike/src/test/resources/logback-test.xml b/persistence-modules/deltaspike/src/test/resources/logback-test.xml index bdc292924b..6a9aa37e7f 100644 --- a/persistence-modules/deltaspike/src/test/resources/logback-test.xml +++ b/persistence-modules/deltaspike/src/test/resources/logback-test.xml @@ -7,7 +7,7 @@ - + diff --git a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml index 8d4771e308..b9242f40a8 100644 --- a/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml +++ b/spring-cloud-modules/spring-cloud-archaius/spring-cloud-archaius-basic-config/src/test/resources/logback-test.xml @@ -6,6 +6,8 @@ + + diff --git a/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml index 7d900d8ea8..896eaf9c88 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/config/src/main/resources/logback.xml @@ -7,6 +7,12 @@ + + + + + + diff --git a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml new file mode 100644 index 0000000000..d944288ca4 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml new file mode 100644 index 0000000000..5f3e764e22 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-echo-demo/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-jenkins-pipeline/src/test/resources/logback-test.xml b/spring-jenkins-pipeline/src/test/resources/logback-test.xml index b9242f40a8..69ab60701a 100644 --- a/spring-jenkins-pipeline/src/test/resources/logback-test.xml +++ b/spring-jenkins-pipeline/src/test/resources/logback-test.xml @@ -8,6 +8,12 @@ + + + + + + From 63953b74f3cef3f6989bffa257ec32e0578c64fc Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Mon, 6 Nov 2023 02:26:25 +0100 Subject: [PATCH 114/283] Nth substring (#15120) * [nth-substring] nth substring in a string * [nth-substring] find n-th substring --- .../FindNthSubstringIndexUnitTest.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java new file mode 100644 index 0000000000..779585ffb0 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/nthsubstring/FindNthSubstringIndexUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.nthsubstring; + +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FindNthSubstringIndexUnitTest { + // "0 8 16 24 " + private final static String INPUT = "a word, a word, a word, a word"; + + @Test + void whenCallingIndexOfTwice_thenGetTheSecondSubstringIndex() { + int firstIdx = INPUT.indexOf("a"); + int result = INPUT.indexOf("a", firstIdx + "a".length()); + assertEquals(8, result); + } + + // the recursive approach + static int nthIndexOf(String input, String substring, int nth) { + if (nth == 1) { + return input.indexOf(substring); + } else { + return input.indexOf(substring, nthIndexOf(input, substring, nth - 1) + substring.length()); + } + } + + @Test + void whenCallingRecursiveMethod_thenGetTheExpectedResult() { + int result1 = nthIndexOf(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthIndexOf(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthIndexOf(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthIndexOf(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthIndexOf(INPUT, "a", 5); + assertEquals(-1, result5); + } + + // loop-based approach + static int nthIndexOf2(String input, String substring, int nth) { + int index = -1; + while (nth > 0) { + index = input.indexOf(substring, index + substring.length()); + if (index == -1) { + return -1; + } + nth--; + } + return index; + } + + @Test + void whenCallingLoopBasedMethod_thenGetTheExpectedResult() { + int result1 = nthIndexOf2(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthIndexOf2(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthIndexOf2(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthIndexOf2(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthIndexOf2(INPUT, "a", 5); + assertEquals(-1, result5); + } + + static int nthOccurrenceIndex(String input, String regexPattern, int nth) { + Matcher matcher = Pattern.compile(regexPattern).matcher(INPUT); + for (int i = 0; i < nth; i++) { + if (!matcher.find()) { + return -1; + } + } + return matcher.start(); + } + + @Test + void whenCallingRegexBasedMethod_thenGetTheExpectedResult() { + int result1 = nthOccurrenceIndex(INPUT, "a", 1); + assertEquals(0, result1); + + int result2 = nthOccurrenceIndex(INPUT, "a", 2); + assertEquals(8, result2); + + int result3 = nthOccurrenceIndex(INPUT, "a", 3); + assertEquals(16, result3); + + int result4 = nthOccurrenceIndex(INPUT, "a", 4); + assertEquals(24, result4); + + int result5 = nthOccurrenceIndex(INPUT, "a", 5); + assertEquals(-1, result5); + } +} \ No newline at end of file From da8167cf17cd23cc083853ae286bd836d686984d Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Mon, 6 Nov 2023 07:15:53 +0530 Subject: [PATCH 115/283] [BAEL-7069] Pass list as a query parameter in Jersey (#15051) * Pass list as a query parameter in Jersey * Address review comment * Address review comment --------- Co-authored-by: rajatgarg --- .../client/listdemo/JerseyListDemo.java | 15 +++++ .../jersey/client/listdemo/ListDemoApp.java | 9 +++ .../listdemo/JerseyListDemoUnitTest.java | 57 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java create mode 100644 jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java create mode 100644 jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java diff --git a/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java new file mode 100644 index 0000000000..52be341653 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/JerseyListDemo.java @@ -0,0 +1,15 @@ +package com.baeldung.jersey.client.listdemo; + +import java.util.List; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.QueryParam; + +@Path("/") +public class JerseyListDemo { + @GET + public String getItems(@QueryParam("items") List items) { + return "Received items: " + items; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java new file mode 100644 index 0000000000..7f5be883da --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/client/listdemo/ListDemoApp.java @@ -0,0 +1,9 @@ +package com.baeldung.jersey.client.listdemo; + +import org.glassfish.jersey.server.ResourceConfig; + +public class ListDemoApp extends ResourceConfig { + public ListDemoApp() { + packages("com.baeldung.jersey.client.listdemo"); + } +} diff --git a/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java new file mode 100644 index 0000000000..0aff6dcabf --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/client/listdemo/JerseyListDemoUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.jersey.client.listdemo; + +import static org.junit.Assert.assertEquals; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.junit.Test; + +import jakarta.ws.rs.core.Application; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; + +public class JerseyListDemoUnitTest extends JerseyTest { + + @Override + protected Application configure() { + enable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); + return new ListDemoApp(); + } + + @Test + public void givenList_whenUsingQueryParam_thenPassParamsAsList() { + Response response = target("/") + .queryParam("items", "item1", "item2") + .request() + .get(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Received items: [item1, item2]", response.readEntity(String.class)); + } + + @Test + public void givenList_whenUsingCommaSeparatedString_thenPassParamsAsList() { + Response response = target("/") + .queryParam("items", "item1,item2") + .request() + .get(); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Received items: [item1,item2]", response.readEntity(String.class)); + } + + @Test + public void givenList_whenUsingUriBuilder_thenPassParamsAsList() { + List itemsList = Arrays.asList("item1", "item2"); + UriBuilder builder = UriBuilder.fromUri("/"); + for (String item : itemsList) { + builder.queryParam("items", item); + } + URI uri = builder.build(); + String expectedUri = "/?items=item1&items=item2"; + assertEquals(expectedUri, uri.toString()); + } +} From 5d3f08d0e915ca8b077666253fa4b3899475155c Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 5 Nov 2023 21:32:49 -0500 Subject: [PATCH 116/283] Fix the whitespace and newline issues - wuth code formatter --- .../message/ordering/payload/UserEvent.java | 3 ++- .../serialization/JacksonDeserializer.java | 3 ++- .../serialization/JacksonSerializer.java | 1 + ...SequenceWithTimeWindowIntegrationTest.java | 22 ++++++++++++------- .../MultiplePartitionIntegrationTest.java | 14 ++++++++---- .../SinglePartitionIntegrationTest.java | 19 +++++++++------- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java index 676b469ce8..99e0cc6c7e 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/payload/UserEvent.java @@ -1,13 +1,14 @@ package com.baeldung.kafka.message.ordering.payload; import java.util.Objects; + public class UserEvent implements Comparable { private String userEventId; private long eventNanoTime; private long globalSequenceNumber; @SuppressWarnings("unused") - public UserEvent(){ + public UserEvent() { // Required for Jackson Serialization and Deserialization } diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java index 4868ecaf2e..cf72ab12df 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonDeserializer.java @@ -1,6 +1,8 @@ package com.baeldung.kafka.message.ordering.serialization; + import com.baeldung.kafka.message.ordering.Config; import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.kafka.common.serialization.Deserializer; import java.util.Map; @@ -12,7 +14,6 @@ public class JacksonDeserializer implements Deserializer { private final ObjectMapper objectMapper = new ObjectMapper(); private Class type; - @Override public void configure(Map configs, boolean isKey) { this.type = (Class) configs.get(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS); diff --git a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java index 4c081de3cc..b2ace3b8ed 100644 --- a/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java +++ b/apache-kafka-2/src/main/java/com/baeldung/kafka/message/ordering/serialization/JacksonSerializer.java @@ -1,6 +1,7 @@ package com.baeldung.kafka.message.ordering.serialization; import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.kafka.common.serialization.Serializer; /** diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java index a5ec7a98a3..caffe12620 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java @@ -4,6 +4,7 @@ import com.baeldung.kafka.headers.KafkaMessageHeaders; import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + import org.apache.kafka.clients.admin.*; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -23,11 +24,14 @@ import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; + import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + import com.google.common.collect.ImmutableList; + import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers @@ -37,8 +41,8 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { private static KafkaProducer producer; private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); - private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5).toNanos(); - + private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5) + .toNanos(); private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowIntegrationTest.class); @Container @@ -66,7 +70,9 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); - admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))).all().get(); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))) + .all() + .get(); } @AfterAll @@ -78,8 +84,9 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { void givenMultiplePartitions_whenPublishedToKafkaAndConsumedWithExtSeqNumberAndTimeWindow_thenCheckForMessageOrder() throws ExecutionException, InterruptedException { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); - for (long sequenceNumber = 1; sequenceNumber <= 10 ; sequenceNumber++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); userEvent.setEventNanoTime(System.nanoTime()); userEvent.setGlobalSequenceNumber(sequenceNumber); Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); @@ -105,9 +112,8 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { buffer.add(record.value()); }); } - assertThat(receivedUserEventList) - .isEqualTo(sentUserEventList) - .containsExactlyElementsOf(sentUserEventList); + assertThat(receivedUserEventList).isEqualTo(sentUserEventList) + .containsExactlyElementsOf(sentUserEventList); } private static void processBuffer(List buffer, List receivedUserEventList) { diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java index adfa9a0399..bb25486f00 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + import org.apache.kafka.clients.admin.*; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -22,11 +23,14 @@ import org.testcontainers.containers.KafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; + import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + import com.google.common.collect.ImmutableList; + import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers @@ -63,7 +67,9 @@ public class MultiplePartitionIntegrationTest { admin = Admin.create(adminProperties); producer = new KafkaProducer<>(producerProperties); consumer = new KafkaConsumer<>(consumerProperties); - admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))).all().get(); + admin.createTopics(ImmutableList.of(new NewTopic(Config.MULTI_PARTITION_TOPIC, Config.MULTIPLE_PARTITIONS, Config.REPLICATION_FACTOR))) + .all() + .get(); } @AfterAll @@ -76,7 +82,8 @@ public class MultiplePartitionIntegrationTest { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); userEvent.setGlobalSequenceNumber(sequenceNumber); userEvent.setEventNanoTime(System.nanoTime()); Future future = producer.send(new ProducerRecord<>(Config.MULTI_PARTITION_TOPIC, sequenceNumber, userEvent)); @@ -92,8 +99,7 @@ public class MultiplePartitionIntegrationTest { receivedUserEventList.add(userEvent); logger.info("User Event ID: " + userEvent.getUserEventId()); }); - assertThat(receivedUserEventList) - .isNotEqualTo(sentUserEventList) + assertThat(receivedUserEventList).isNotEqualTo(sentUserEventList) .containsExactlyInAnyOrderElementsOf(sentUserEventList); } } diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java index 7280a1218a..8656df1bf3 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.kafka.message.ordering; import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; + import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.clients.admin.AdminClientConfig; import org.apache.kafka.clients.admin.NewTopic; @@ -29,7 +30,9 @@ import java.time.Duration; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + import com.google.common.collect.ImmutableList; + import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers @@ -56,7 +59,6 @@ public class SinglePartitionIntegrationTest { producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class.getName()); producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JacksonSerializer.class.getName()); - producer = new KafkaProducer<>(producerProperties); Properties consumerProperties = new Properties(); consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); @@ -65,11 +67,12 @@ public class SinglePartitionIntegrationTest { consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); consumerProperties.put(Config.CONSUMER_VALUE_DESERIALIZER_SERIALIZED_CLASS, UserEvent.class); consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group"); - consumer = new KafkaConsumer<>(consumerProperties); admin = Admin.create(adminProperties); - - - admin.createTopics(ImmutableList.of(new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR))).all().get(); + producer = new KafkaProducer<>(producerProperties); + consumer = new KafkaConsumer<>(consumerProperties); + admin.createTopics(ImmutableList.of(new NewTopic(Config.SINGLE_PARTITION_TOPIC, Config.SINGLE_PARTITION, Config.REPLICATION_FACTOR))) + .all() + .get(); } @AfterAll @@ -82,7 +85,8 @@ public class SinglePartitionIntegrationTest { List sentUserEventList = new ArrayList<>(); List receivedUserEventList = new ArrayList<>(); for (long sequenceNumber = 1; sequenceNumber <= 10; sequenceNumber++) { - UserEvent userEvent = new UserEvent(UUID.randomUUID().toString()); + UserEvent userEvent = new UserEvent(UUID.randomUUID() + .toString()); userEvent.setGlobalSequenceNumber(sequenceNumber); userEvent.setEventNanoTime(System.nanoTime()); ProducerRecord producerRecord = new ProducerRecord<>(Config.SINGLE_PARTITION_TOPIC, userEvent); @@ -99,8 +103,7 @@ public class SinglePartitionIntegrationTest { receivedUserEventList.add(userEvent); logger.info("User Event ID: " + userEvent.getUserEventId()); }); - assertThat(receivedUserEventList) - .isEqualTo(sentUserEventList) + assertThat(receivedUserEventList).isEqualTo(sentUserEventList) .containsExactlyElementsOf(sentUserEventList); } } From 6e758b8438de2bd367ccf741fa2a53a01c9399ec Mon Sep 17 00:00:00 2001 From: Amol Gote Date: Sun, 5 Nov 2023 21:39:02 -0500 Subject: [PATCH 117/283] The test names should be LiveTest not IntegrationTest, as per the other similar tests in this module. This naming is used to mark these tests as manually runnable only, since they are heavy tests that spin up a container, so we don't want them to be run as part of the automatic CI build. Same for the other tests. --- ...Test.java => ExternalSequenceWithTimeWindowLiveTest.java} | 5 ++--- ...onIntegrationTest.java => MultiplePartitionLiveTest.java} | 4 ++-- ...tionIntegrationTest.java => SinglePartitionLiveTest.java} | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{ExternalSequenceWithTimeWindowIntegrationTest.java => ExternalSequenceWithTimeWindowLiveTest.java} (97%) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{MultiplePartitionIntegrationTest.java => MultiplePartitionLiveTest.java} (98%) rename apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/{SinglePartitionIntegrationTest.java => SinglePartitionLiveTest.java} (98%) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java similarity index 97% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java index caffe12620..f36c6ebd63 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/ExternalSequenceWithTimeWindowLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.kafka.message.ordering; -import com.baeldung.kafka.headers.KafkaMessageHeaders; import com.baeldung.kafka.message.ordering.payload.UserEvent; import com.baeldung.kafka.message.ordering.serialization.JacksonDeserializer; import com.baeldung.kafka.message.ordering.serialization.JacksonSerializer; @@ -35,7 +34,7 @@ import com.google.common.collect.ImmutableList; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers -public class ExternalSequenceWithTimeWindowIntegrationTest { +public class ExternalSequenceWithTimeWindowLiveTest { private static Admin admin; private static KafkaProducer producer; @@ -43,7 +42,7 @@ public class ExternalSequenceWithTimeWindowIntegrationTest { private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); private static final long BUFFER_PERIOD_NS = Duration.ofSeconds(5) .toNanos(); - private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowIntegrationTest.class); + private static Logger logger = LoggerFactory.getLogger(ExternalSequenceWithTimeWindowLiveTest.class); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java similarity index 98% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java index bb25486f00..407b4d52a9 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/MultiplePartitionLiveTest.java @@ -34,14 +34,14 @@ import com.google.common.collect.ImmutableList; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers -public class MultiplePartitionIntegrationTest { +public class MultiplePartitionLiveTest { private static Admin admin; private static KafkaProducer producer; private static KafkaConsumer consumer; private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); - private static Logger logger = LoggerFactory.getLogger(MultiplePartitionIntegrationTest.class); + private static Logger logger = LoggerFactory.getLogger(MultiplePartitionLiveTest.class); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java similarity index 98% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java index 8656df1bf3..9c6a15ebeb 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionIntegrationTest.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/message/ordering/SinglePartitionLiveTest.java @@ -36,7 +36,7 @@ import com.google.common.collect.ImmutableList; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; @Testcontainers -public class SinglePartitionIntegrationTest { +public class SinglePartitionLiveTest { private static Admin admin; private static KafkaProducer producer; @@ -44,7 +44,7 @@ public class SinglePartitionIntegrationTest { private static final Duration TIMEOUT_WAIT_FOR_MESSAGES = Duration.ofSeconds(5); - private static Logger logger = LoggerFactory.getLogger(SinglePartitionIntegrationTest.class); + private static Logger logger = LoggerFactory.getLogger(SinglePartitionLiveTest.class); @Container private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); From c61a1dace10bd3848290088204c36f1d5ed79dc5 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:24:02 +0530 Subject: [PATCH 118/283] BAEL-7091 Asserting Nested Map with JUnit --- testing-modules/hamcrest/pom.xml | 12 +++ .../AssertNestedMapUnitTest.java | 94 +++++++++++++++++++ .../matchers/NestedMapMatcher.java | 38 ++++++++ 3 files changed, 144 insertions(+) create mode 100644 testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java create mode 100644 testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java diff --git a/testing-modules/hamcrest/pom.xml b/testing-modules/hamcrest/pom.xml index df8c543edb..b5a8277deb 100644 --- a/testing-modules/hamcrest/pom.xml +++ b/testing-modules/hamcrest/pom.xml @@ -6,6 +6,18 @@ hamcrest 0.0.1-SNAPSHOT hamcrest + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + jar diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java new file mode 100644 index 0000000000..42c225695c --- /dev/null +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.hamcrest.assertnestedmap; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static com.baeldung.hamcrest.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.*; + +public class AssertNestedMapUnitTest { + + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertAll( + () -> assertTrue(outerMap.containsKey("address")), + () -> assertEquals(outerMap.get("address").get("city"), "Chicago") + ); + } + + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") + && ((Map)outerMap.get("address")).get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + assertAll( + () -> assertThat(outerMap, hasKey("address")), + () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) + ); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + @Test + void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + + @Test + void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); + } + +} diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java new file mode 100644 index 0000000000..760edebb35 --- /dev/null +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java @@ -0,0 +1,38 @@ +package com.baeldung.hamcrest.assertnestedmap.matchers; + + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +import java.util.Map; + +public class NestedMapMatcher extends TypeSafeMatcher> { + private K key; + private V subMapValue; + + public NestedMapMatcher(K key, V subMapValue) { + this.key = key; + this.subMapValue = subMapValue; + } + + @Override + protected boolean matchesSafely(Map item) { + if (item.containsKey(key)) { + Object actualValue = item.get(key); + return subMapValue.equals(actualValue); + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("a map containing key ").appendValue(key) + .appendText(" with value ").appendValue(subMapValue); + } + + public static Matcher hasNestedMapEntry(K key, V expectedValue) { + return new NestedMapMatcher(key, expectedValue); + } +} + From 91293d64b0be2e2d1bb61d44de5fa85aa5328fee Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 6 Nov 2023 08:52:53 +0000 Subject: [PATCH 119/283] =?UTF-8?q?[JAVA-26049]=20Upgraded=20spring-boot-e?= =?UTF-8?q?nvironment=20module=20to=20spring-boot=203=E2=80=A6=20(#14994)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spring-boot-environment/pom.xml | 22 +++++++++++-------- .../main/resources/META-INF/spring.factories | 6 ----- .../META-INF/spring/AutoConfiguration.imports | 1 + .../META-INF/spring/spring.factories | 3 +++ 4 files changed, 17 insertions(+), 15 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories create mode 100644 spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports create mode 100644 spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories diff --git a/spring-boot-modules/spring-boot-environment/pom.xml b/spring-boot-modules/spring-boot-environment/pom.xml index 4bdb35358c..9974d41f45 100644 --- a/spring-boot-modules/spring-boot-environment/pom.xml +++ b/spring-boot-modules/spring-boot-environment/pom.xml @@ -9,9 +9,10 @@ Demo project for Spring Boot - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -46,11 +47,6 @@ h2 runtime - - javax.persistence - javax.persistence-api - ${jpa.version} - com.google.guava guava @@ -96,6 +92,15 @@ + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.environmentpostprocessor.PriceCalculationApplication + + + @@ -151,7 +156,6 @@ - 2.2 3.1.7 4.5.8 2021.0.0 diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories deleted file mode 100644 index c36b67f8d7..0000000000 --- a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,6 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig - -org.springframework.boot.env.EnvironmentPostProcessor=\ -com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor - diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports new file mode 100644 index 0000000000..350e2efa94 --- /dev/null +++ b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/AutoConfiguration.imports @@ -0,0 +1 @@ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories new file mode 100644 index 0000000000..ff5e404c84 --- /dev/null +++ b/spring-boot-modules/spring-boot-environment/src/main/resources/META-INF/spring/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + From 81be7c4ad51e4f88a53d99dc834e8b7fd7098d80 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:45:12 +0000 Subject: [PATCH 120/283] [JAVA-26374-boot-runtime] Moved "CORS with Spring" article to spring-boot-runtime (#15096) --- spring-boot-modules/spring-boot-runtime-2/README.md | 1 - spring-boot-modules/spring-boot-runtime/README.md | 1 + .../src/main/java/com/baeldung/cors/Account.java | 0 .../src/main/java/com/baeldung/cors/AccountController.java | 0 .../src/main/java/com/baeldung/cors/config/WebConfig.java | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/{spring-boot-runtime-2 => spring-boot-runtime}/src/main/java/com/baeldung/cors/Account.java (100%) rename spring-boot-modules/{spring-boot-runtime-2 => spring-boot-runtime}/src/main/java/com/baeldung/cors/AccountController.java (100%) rename spring-boot-modules/{spring-boot-runtime-2 => spring-boot-runtime}/src/main/java/com/baeldung/cors/config/WebConfig.java (100%) diff --git a/spring-boot-modules/spring-boot-runtime-2/README.md b/spring-boot-modules/spring-boot-runtime-2/README.md index f439b0d0bd..3ee05ccc83 100644 --- a/spring-boot-modules/spring-boot-runtime-2/README.md +++ b/spring-boot-modules/spring-boot-runtime-2/README.md @@ -4,5 +4,4 @@ This module contains articles about administering a Spring Boot runtime ### Relevant Articles: - [Configure the Heap Size When Starting a Spring Boot Application](https://www.baeldung.com/spring-boot-heap-size) - - [CORS with Spring](https://www.baeldung.com/spring-cors) - [Max-HTTP-Header-Size in Spring Boot 2](https://www.baeldung.com/spring-boot-max-http-header-size) diff --git a/spring-boot-modules/spring-boot-runtime/README.md b/spring-boot-modules/spring-boot-runtime/README.md index 6f21efe793..6463aaa6c3 100644 --- a/spring-boot-modules/spring-boot-runtime/README.md +++ b/spring-boot-modules/spring-boot-runtime/README.md @@ -10,3 +10,4 @@ This module contains articles about administering a Spring Boot runtime - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring) - [Spring – Log Incoming Requests](https://www.baeldung.com/spring-http-logging) - [How to Configure Spring Boot Tomcat](https://www.baeldung.com/spring-boot-configure-tomcat) + - [CORS with Spring](https://www.baeldung.com/spring-cors) diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/Account.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/Account.java diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/AccountController.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/AccountController.java diff --git a/spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-runtime-2/src/main/java/com/baeldung/cors/config/WebConfig.java rename to spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/cors/config/WebConfig.java From dc667e03f3b9d4b94466459fbbaec99840d51f00 Mon Sep 17 00:00:00 2001 From: timis1 Date: Mon, 6 Nov 2023 13:58:00 +0200 Subject: [PATCH 121/283] JAVA-27237 Change the logging level to WARN (spring-integration) --- spring-integration/src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-integration/src/test/resources/logback-test.xml b/spring-integration/src/test/resources/logback-test.xml index 98bfc86d71..352dc719df 100644 --- a/spring-integration/src/test/resources/logback-test.xml +++ b/spring-integration/src/test/resources/logback-test.xml @@ -9,7 +9,7 @@ - + From fb2f90d88f540c2df051d318c8f176a643462bf0 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:08:47 +0530 Subject: [PATCH 122/283] BAEL-7177 review comments implemented. --- .../modifystream/ModifyStreamUnitTest.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java index f5fab408b8..9da3beb40e 100644 --- a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/modifystream/ModifyStreamUnitTest.java @@ -95,15 +95,6 @@ public class ModifyStreamUnitTest { assertEquals(3, newPersonList.size()); } - @Test - void givenPersonList_whenRemovePersonWithRemoveIf_thenPersonRemoved() { - assertEquals(4, personList.size()); - - personList.removeIf(e -> e.getName().equals("John")); - - assertEquals(3, personList.size()); - } - @Test void givenPersonList_whenUpdatePersonEmailByInterferingWithForEach_thenPersonEmailUpdated() { personList.stream().forEach(e -> e.setEmail(e.getEmail().toUpperCase())); @@ -128,11 +119,12 @@ public class ModifyStreamUnitTest { newImmutablePersonList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } + @Test void givenPersonList_whenUpdatePersonEmailByInterferingWithPeek_thenPersonEmailUpdated() { personList.stream() - .peek(e -> e.setEmail(e.getEmail().toUpperCase())) - .collect(Collectors.toList()); + .peek(e -> e.setEmail(e.getEmail().toUpperCase())) + .collect(Collectors.toList()); personList.forEach(e -> assertEquals(e.getEmail(), e.getEmail().toUpperCase())); } From e9431ce416773b07ea3efc42bc1a4cbaa783114a Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:27:07 +0530 Subject: [PATCH 123/283] BAEL-7091 Formatting fixed --- .../assertnestedmap/AssertNestedMapUnitTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java index 42c225695c..b5b4d652a0 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java @@ -11,7 +11,6 @@ import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { - @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { Map innerMap = Map.of("city", "Chicago"); @@ -26,8 +25,8 @@ public class AssertNestedMapUnitTest { Map> outerMap = Map.of("address", innerMap); assertAll( - () -> assertTrue(outerMap.containsKey("address")), - () -> assertEquals(outerMap.get("address").get("city"), "Chicago") + () -> assertTrue(outerMap.containsKey("address")), + () -> assertEquals(outerMap.get("address").get("city"), "Chicago") ); } @@ -45,8 +44,8 @@ public class AssertNestedMapUnitTest { Map innerMap = Map.of("city", "Chicago"); Map> outerMap = Map.of("address", innerMap); assertAll( - () -> assertThat(outerMap, hasKey("address")), - () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) + () -> assertThat(outerMap, hasKey("address")), + () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) ); } @@ -82,7 +81,6 @@ public class AssertNestedMapUnitTest { assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } - @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { Map innerMap = Map.of("city", "Chicago"); From 9e3c735879388af7f39456972ed516d3518d291f Mon Sep 17 00:00:00 2001 From: Anastasios Ioannidis <121166333+anastasiosioannidis@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:38:16 +0200 Subject: [PATCH 124/283] JAVA-22208 Fix port to 1030,1031 for jenkins (#15100) --- ...oadBalancerBooksClientIntegrationTest.java | 6 +++--- .../client/LoadBalancerIntegrationTest.java | 6 +++--- .../spring/cloud/client/TestConfig.java | 4 ++-- .../spring/cloud/client/WireMockConfig.java | 4 ++-- ...application-spring-cloud-balancer-test.yml | 19 ------------------- .../src/test/resources/application-test.yml | 4 ++-- 6 files changed, 12 insertions(+), 31 deletions(-) delete mode 100644 spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java index 5690c24d77..a70ae1ee22 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerBooksClientIntegrationTest.java @@ -63,12 +63,12 @@ class LoadBalancerBooksClientIntegrationTest { String serviceId = "books-service"; RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers - .toProvider(serviceId, instance(serviceId, "localhost", false), instance(serviceId, "localhost", true)), + .toProvider(serviceId, instance(serviceId, "localhost", 1030, false), instance(serviceId, "localhost", 1031, true)), serviceId, -1); } - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); + private static DefaultServiceInstance instance(String serviceId, String host, int port, boolean secure) { + return new DefaultServiceInstance(serviceId, serviceId, host, port, secure); } @Test diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java index eee4e7b860..9761b4eb64 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/LoadBalancerIntegrationTest.java @@ -80,13 +80,13 @@ class LoadBalancerIntegrationTest { void staticConfigurationWorks() { String serviceId = "test-book-service"; RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers - .toProvider(serviceId, instance(serviceId, "bookservice1", false), instance(serviceId, "bookservice2", false)), + .toProvider(serviceId, instance(serviceId, "bookservice1", 1030, false), instance(serviceId, "bookservice2", 1031, false)), serviceId, -1); assertLoadBalancer(loadBalancer, Arrays.asList("bookservice1", "bookservice2")); } - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); + private static DefaultServiceInstance instance(String serviceId, String host, int port, boolean secure) { + return new DefaultServiceInstance(serviceId, serviceId, host, port, secure); } @EnableAutoConfiguration diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java index b3770721b1..375c945054 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/TestConfig.java @@ -14,11 +14,11 @@ public class TestConfig { @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService() { - return new WireMockServer(options().port(80)); + return new WireMockServer(options().port(1030)); } @Bean(name="secondMockBooksService", initMethod = "start", destroyMethod = "stop") public WireMockServer secondBooksMockService() { - return new WireMockServer(options().port(81)); + return new WireMockServer(options().port(1031)); } } diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java index 3d4f2822f4..a41faa9c5c 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/java/com/baeldung/spring/cloud/client/WireMockConfig.java @@ -11,11 +11,11 @@ public class WireMockConfig { @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService() { - return new WireMockServer(80); + return new WireMockServer(1030); } @Bean(initMethod = "start", destroyMethod = "stop") public WireMockServer mockBooksService2() { - return new WireMockServer(81); + return new WireMockServer(1031); } } diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml deleted file mode 100644 index ad11d46ae8..0000000000 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-spring-cloud-balancer-test.yml +++ /dev/null @@ -1,19 +0,0 @@ -eureka: - client: - enabled: false - -spring: - application: - name: books-service - cloud: - loadbalancer: - ribbon: - enabled: false - discovery: - client: - simple: - instances: - books-service[0]: - uri: http://localhost:80 - books-service[1]: - uri: http://localhost:81 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml index 231d45004f..6bd5b8efc7 100644 --- a/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml +++ b/spring-cloud-modules/spring-cloud-eureka/spring-cloud-eureka-feign-client-integration-test/src/test/resources/application-test.yml @@ -14,6 +14,6 @@ spring: simple: instances: books-service[0]: - uri: http://localhost:80 + uri: http://localhost:1030 books-service[1]: - uri: http://localhost:81 + uri: http://localhost:1031 From 946f84976785a7942782d14fed6121ba48ec86ed Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:34:00 +0200 Subject: [PATCH 125/283] Update StreamToMapAndMultiMapUnitTest.java (#15146) --- .../StreamToMapAndMultiMapUnitTest.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java index 4d957fd704..f5da353551 100644 --- a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamtomapandmultimap/StreamToMapAndMultiMapUnitTest.java @@ -1,6 +1,7 @@ package com.baeldung.streamtomapandmultimap; -import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; import org.junit.Test; import java.util.*; @@ -32,16 +33,16 @@ public class StreamToMapAndMultiMapUnitTest { public void givenStringStream_whenConvertingToMultimap_thenExpectedMultimapIsGenerated() { Stream stringStream = Stream.of("one", "two", "three", "two"); - LinkedHashMultimap multimap = LinkedHashMultimap.create(); + ListMultimap multimap = stringStream.collect( + ArrayListMultimap::create, + (map, element) -> map.put(element, element), + ArrayListMultimap::putAll + ); - stringStream.collect(Collectors.groupingBy( - s -> s, - Collectors.mapping(s -> s, Collectors.toList()) - )).forEach((key, value) -> multimap.putAll(key, value)); - - LinkedHashMultimap expectedMultimap = LinkedHashMultimap.create(); + ListMultimap expectedMultimap = ArrayListMultimap.create(); expectedMultimap.put("one", "one"); expectedMultimap.put("two", "two"); + expectedMultimap.put("two", "two"); expectedMultimap.put("three", "three"); assertEquals(expectedMultimap, multimap); @@ -97,4 +98,4 @@ public class StreamToMapAndMultiMapUnitTest { assertEquals(expectedMap, resultMap); } -} \ No newline at end of file +} From 4d7e5eb5c9a143afbe37833cb7a6296fd16b41b6 Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:40:42 +0200 Subject: [PATCH 126/283] This commit is related to the article BAEL-6988 (#15149) This commit aims to add a test class "HexToIntConversionUnitTest.java" that provides several ways to convert Hex string into int. --- .../hextoint/HexToIntConversionUnitTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java diff --git a/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java b/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java new file mode 100644 index 0000000000..c236f0a818 --- /dev/null +++ b/core-java-modules/core-java-hex/test/java/com/baeldung/hextoint/HexToIntConversionUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.hextoint; + +import org.junit.Test; + +import java.math.BigInteger; + +import static org.junit.Assert.assertEquals; + +public class HexToIntConversionUnitTest { + + @Test + public void givenValidHexString_whenUsingParseInt_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + int decimalValue = Integer.parseInt(hexString.substring(2), 16); + + assertEquals(expectedDecimalValue, decimalValue); + } + + @Test + public void givenValidHexString_whenUsingIntegerDecode_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + int decimalValue = Integer.decode(hexString); + + assertEquals(expectedDecimalValue, decimalValue); + } + + @Test + public void givenValidHexString_whenUsingBigInteger_thenExpectCorrectDecimalValue() { + String hexString = "0x00FF00"; + int expectedDecimalValue = 65280; + + BigInteger bigIntegerValue = new BigInteger(hexString.substring(2), 16); + int decimalValue = bigIntegerValue.intValue(); + assertEquals(expectedDecimalValue, decimalValue); + } + + +} From 03c615201fdad5e3bd54f7c701972bb248f7d2a7 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 6 Nov 2023 16:26:35 -0300 Subject: [PATCH 127/283] Update InterruptThread.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a comment: Section 6 should be headlined with “Using System.exit()” since that’s what stops code execution, not the boolean variable (this is just a means to decide that execution should be stopped, like the negative array element in section 4. Also it’s unclear why we’d need the “if (isInterrupted())” statement in the while loop of the 8th section: how should isInterrupted() be true one line after we’ve checked in the while loop header that it’s false? Admittedly there’s a little chance that the interrupt status changed between these 2 lines, but this if statement would make much more sense somewhere in the business logic code where more time has passed since the evaluation of “while (!isInterrupted())”… and if that business code doesn’t have that complexity/length, one should omit this if statement altogether, since it creates more confusion than it helps for timely reaction on an interruption. --- .../main/java/com/baeldung/stopexecution/InterruptThread.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java index 7964ad9f52..7fcb6185cc 100644 --- a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java @@ -4,9 +4,7 @@ public class InterruptThread extends Thread { @Override public void run() { while (!isInterrupted()) { - if (isInterrupted()) { - break; - } + break; // business logic } } From 4ef6b9039f4e77075b6b199a5df9106da22f20ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan=20Cardo=C5=9F?= <106325528+sodrac@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:47:45 +0200 Subject: [PATCH 128/283] BAEL-6874 update test code for article (#15155) * BAEL-6819 convert from int to Long in Java * BAEL-6819 update package name * BAEL-6874 test code for article * BAEL-6874 rename test class * BAEL-6874 update test code for article --- .../GenericNumbersComparatorUnitTest.java | 40 ++----------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java index 37b971b5c5..0fcc0f3453 100644 --- a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java @@ -1,13 +1,12 @@ package com.baeldung.genericnumberscomparator; +import static org.assertj.core.api.Assertions.entry; import static org.junit.jupiter.api.Assertions.assertEquals; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Comparator; -import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.function.BiFunction; import java.util.function.BiPredicate; import java.util.function.Function; @@ -25,6 +24,7 @@ class GenericNumbersComparatorUnitTest { assertEquals(0, compareDouble(5, 5.0)); } + // we create a method that compares Integer, but this could also be done for other types e.g. Double, BigInteger public int compareTo(Integer int1, Integer int2) { return int1.compareTo(int2); } @@ -34,11 +34,10 @@ class GenericNumbersComparatorUnitTest { assertEquals(-1, compareTo(5, 7)); } - Map, BiFunction> comparisonMap = new HashMap<>(); + // for this example, we create a function that compares Integer, but this could also be done for other types e.g. Double, BigInteger + Map, BiFunction> comparisonMap = Map.ofEntries(entry(Integer.class, (num1, num2) -> ((Integer) num1).compareTo((Integer) num2))); public int compareUsingMap(Number num1, Number num2) { - comparisonMap.put(Integer.class, (a, b) -> ((Integer) num1).compareTo((Integer) num2)); - return comparisonMap.get(num1.getClass()) .apply(num1, num2); } @@ -70,24 +69,6 @@ class GenericNumbersComparatorUnitTest { assertEquals(-1, compareUsingReflection(5, 7)); } - interface NumberComparatorFactory { - Comparator getComparator(); - } - - class IntegerComparatorFactory implements NumberComparatorFactory { - @Override - public Comparator getComparator() { - return (num1, num2) -> ((Integer) num1).compareTo((Integer) num2); - } - } - - @Test - void givenNumbers_whenUseComparatorFactory_thenWillExecuteComparison() { - NumberComparatorFactory factory = new IntegerComparatorFactory(); - Comparator comparator = factory.getComparator(); - assertEquals(-1, comparator.compare(5, 7)); - } - Function toDouble = Number::doubleValue; BiPredicate isEqual = (num1, num2) -> toDouble.apply(num1) .equals(toDouble.apply(num2)); @@ -97,19 +78,6 @@ class GenericNumbersComparatorUnitTest { assertEquals(true, isEqual.test(5, 5.0)); } - private Number someNumber = 5; - private Number anotherNumber = 5.0; - - Optional optNum1 = Optional.ofNullable(someNumber); - Optional optNum2 = Optional.ofNullable(anotherNumber); - int comparisonResult = optNum1.flatMap(n1 -> optNum2.map(n2 -> Double.compare(n1.doubleValue(), n2.doubleValue()))) - .orElse(0); - - @Test - void givenNumbers_whenUseComparisonResult_thenWillExecuteComparison() { - assertEquals(0, comparisonResult); - } - private boolean someCondition = true; Function dynamicFunction = someCondition ? Number::doubleValue : Number::intValue; Comparator dynamicComparator = (num1, num2) -> ((Comparable) dynamicFunction.apply(num1)).compareTo(dynamicFunction.apply(num2)); From 9e995c1e417a8fc2a9d3339bc64adf7568746353 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Mon, 6 Nov 2023 22:38:36 +0100 Subject: [PATCH 129/283] BAEL-6489 Time Conversions Using TimeUnit (#14390) --- .../TimeUnitConversionsUnitTest.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java new file mode 100644 index 0000000000..cbcbcd566b --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/timeunitconversions/TimeUnitConversionsUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.timeunitconversions; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +class TimeUnitConversionsUnitTest { + + + @Test + void givenSeconds_whenConvertToMinutes_thenCorrect() { + int input = 60; + + long minutes = TimeUnit.MINUTES.convert(input, TimeUnit.SECONDS); + + assertThat(minutes).isEqualTo(1); + } + + @Test + void givenMinutes_whenConvertToSeconds_thenCorrect() { + int input = 1; + + long seconds = TimeUnit.SECONDS.convert(input, TimeUnit.MINUTES); + + assertThat(seconds).isEqualTo(60); + } + + @Test + void givenSeconds_whenToMinutes_thenCorrect() { + int input = 60; + + long minutes = TimeUnit.SECONDS.toMinutes(input); + + assertThat(minutes).isEqualTo(1); + } + + @Test + void givenMinutes_whenToSeconds_thenCorrect() { + int input = 1; + + long seconds = TimeUnit.MINUTES.toSeconds(input); + + assertThat(seconds).isEqualTo(60); + } + + @Test + void givenNegativeInput_whenToMinutes_thenCorrect() { + int input = -60; + + long minutes = TimeUnit.SECONDS.toMinutes(input); + assertThat(minutes).isEqualTo(-1); + } + + @Test + void givenNonTotalInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() { + long positiveUnder = TimeUnit.SECONDS.toMinutes(59); + long positiveAbove = TimeUnit.SECONDS.toMinutes(61); + + assertThat(positiveUnder).isEqualTo(0); + assertThat(positiveAbove).isEqualTo(1); + } + + @Test + void givenNonTotalNegativeInput_whenToMinutes_thenCorrectTotalResultWithDecimalTruncate() { + long negativeUnder = TimeUnit.SECONDS.toMinutes(-59); + long negativeAbove = TimeUnit.SECONDS.toMinutes(-61); + + assertThat(negativeUnder).isEqualTo(0); + assertThat(negativeAbove).isEqualTo(-1); + } + + @Test + void givenOverflowInput_whenToMillis_thenTruncatedToLimit() { + long maxMillis = TimeUnit.DAYS.toMillis(Long.MAX_VALUE); + long minMillis = TimeUnit.DAYS.toMillis(Long.MIN_VALUE); + + assertThat(maxMillis).isEqualTo(Long.MAX_VALUE); + assertThat(minMillis).isEqualTo(Long.MIN_VALUE); + } + + @Test + void givenInput_whenExtractFineTimeUnits_thenCorrect() { + long inputSeconds = 3672; + + long hours = TimeUnit.SECONDS.toHours(inputSeconds); + + long secondsRemainingAfterHours = inputSeconds - TimeUnit.HOURS.toSeconds(hours); + long minutes = TimeUnit.SECONDS.toMinutes(secondsRemainingAfterHours); + + long seconds = secondsRemainingAfterHours - TimeUnit.MINUTES.toSeconds(minutes); + + + assertThat(hours).isEqualTo(1); + assertThat(minutes).isEqualTo(1); + assertThat(seconds).isEqualTo(12); + + assertThat(inputSeconds).isEqualTo( + (hours * 60 * 60) + + (minutes * 60) + + (seconds) + ); + } +} From 14070ec048db08590402f87ebc4bd9b2065d23ec Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Tue, 7 Nov 2023 04:50:48 +0100 Subject: [PATCH 130/283] BAEL-6139: Added ThreadMonitorInfo (#15094) * BAEL-6139: Added ThreadMonitorInfo * BAEL-6139: Move ThreadMonitorInfo * BAEL-6139: Unsafe using park() and unpark(Thread) --- .../com/baeldung/park/ThreadMonitorInfo.java | 26 +++++++++ .../PreemptivePermitsBehaviorUnitTest.java | 27 +++++++++ ...atedPreemptivePermitsBehaviorUnitTest.java | 43 ++++++++++++++ .../ThreadInterruptedBehaviorUnitTest.java | 56 +++++++++++++++++++ .../park/TreadMonitorsBehaviorUnitTest.java | 51 +++++++++++++++++ 5 files changed, 203 insertions(+) create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java create mode 100644 core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java create mode 100644 core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java create mode 100644 core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java create mode 100644 core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java new file mode 100644 index 0000000000..948fb48fcb --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/park/ThreadMonitorInfo.java @@ -0,0 +1,26 @@ +package com.baeldung.park; + +import java.util.concurrent.locks.LockSupport; + +public class ThreadMonitorInfo { + private static final Object MONITOR = new Object(); + public static void main(String[] args) throws InterruptedException { + final Thread waitingThread = new Thread(() -> { + try { + synchronized (MONITOR) { + MONITOR.wait(); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, "Waiting Thread"); + + final Thread parkedThread = new Thread(LockSupport::park, "Parked Thread"); + + waitingThread.start(); + parkedThread.start(); + + waitingThread.join(); + parkedThread.join(); + } +} diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java new file mode 100644 index 0000000000..05bfa4ba0b --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/PreemptivePermitsBehaviorUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; + +class PreemptivePermitsBehaviorUnitTest { + + private final Thread parkedThread = new Thread() { + @Override + public void run() { + LockSupport.unpark(this); + LockSupport.park(); + } + }; + + @Test + void givenThreadWhenPreemptivePermitShouldNotPark() { + assertTimeoutPreemptively(Duration.of(1, ChronoUnit.SECONDS), () -> { + parkedThread.start(); + parkedThread.join(); + }); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java new file mode 100644 index 0000000000..98be58e9d3 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/RepeatedPreemptivePermitsBehaviorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; + +class RepeatedPreemptivePermitsBehaviorUnitTest { + + private final Thread parkedThread = new Thread() { + @Override + public void run() { + LockSupport.unpark(this); + LockSupport.unpark(this); + LockSupport.park(); + LockSupport.park(); + } + }; + + @Test + void givenThreadWhenRepeatedPreemptivePermitShouldPark() { + Callable callable = () -> { + parkedThread.start(); + parkedThread.join(); + return true; + }; + + boolean result = false; + final Future future = Executors.newSingleThreadExecutor().submit(callable); + try { + result = future.get(1, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + // Expected the thread to be parked + } + assertFalse(result, "The thread should be parked"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java new file mode 100644 index 0000000000..da7b6ffbc9 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/ThreadInterruptedBehaviorUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +class ThreadInterruptedBehaviorUnitTest { + + @Test + @Timeout(3) + void givenParkedThreadWhenInterruptedShouldNotResetInterruptedFlag() throws InterruptedException { + final Thread thread = new Thread(LockSupport::park); + thread.start(); + thread.interrupt(); + assertTrue(thread.isInterrupted(), "The thread should have the interrupted flag"); + thread.join(); + } + + @Test + @Timeout(3) + void givenParkedThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException { + final Thread thread = new Thread(LockSupport::park); + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + LockSupport.unpark(thread); + assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag"); + thread.join(); + } + + @Test + @Timeout(3) + void givenWaitingThreadWhenNotInterruptedShouldNotHaveInterruptedFlag() throws InterruptedException { + + final Thread thread = new Thread() { + @Override + public void run() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + // The thread was interrupted + } + } + } + }; + + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + thread.interrupt(); + thread.join(); + assertFalse(thread.isInterrupted(), "The thread shouldn't have the interrupted flag"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java new file mode 100644 index 0000000000..b14b674a19 --- /dev/null +++ b/core-java-modules/core-java-sun/src/test/java/com/baeldung/park/TreadMonitorsBehaviorUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.park; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.LockSupport; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + + +class TreadMonitorsBehaviorUnitTest { + + @Test + @Timeout(3) + void giveThreadWhenNotifyWithoutAcquiringMonitorThrowsException() { + final Thread thread = new Thread() { + @Override + public void run() { + synchronized (this) { + try { + this.wait(); + } catch (InterruptedException e) { + // The thread was interrupted + } + } + } + }; + + assertThrows(IllegalMonitorStateException.class, () -> { + thread.start(); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + thread.notify(); + thread.join(); + }); + } + + @Test + @Timeout(3) + void giveThreadWhenUnparkWithoutAcquiringMonitor() { + final Thread thread = new Thread(LockSupport::park); + assertTimeoutPreemptively(Duration.of(2, ChronoUnit.SECONDS), () -> { + thread.start(); + LockSupport.unpark(thread); + }); + } +} From a7f39e4155917e732664262beaa686259add6321 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:42:25 +0530 Subject: [PATCH 131/283] Spell mistake fix --- .../java/com/baledung/billpugh/BillPughSingletonUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java index b42d36229f..dcf2098b4b 100644 --- a/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java +++ b/patterns-modules/design-patterns-singleton/src/test/java/com/baledung/billpugh/BillPughSingletonUnitTest.java @@ -15,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class BillPughSingletonUnitTest { Logger logger = LoggerFactory.getLogger(BillPughSingletonUnitTest.class); @Test - void giveSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { + void givenSynchronizedLazyLoadedImpl_whenCallgetInstance_thenReturnSingleton() { Set setHoldingSingletonObj = new HashSet<>(); List> futures = new ArrayList<>(); From f1424a62ef6f8bab13fee10463435d895de9da33 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 7 Nov 2023 15:52:43 +0530 Subject: [PATCH 132/283] JAVA-26556: Changes made for Adding missed modules (#15105) /core-java-modules/core-java-numbers-conversions /core-java-modules/core-java-datetime-conversion /di-modules/avaje/persistence-modules/spring-boot-persistence-4 /spring-boot-modules/spring-boot-security-2 /spring-boot-modules/spring-boot-ssl-bundles /spring-boot-modules/spring-boot-telegram --- ...nversionsTest.java => FloatDoubleConversionsUnitTest.java} | 2 +- core-java-modules/pom.xml | 4 +++- di-modules/pom.xml | 1 + persistence-modules/pom.xml | 1 + spring-boot-modules/pom.xml | 3 +++ 5 files changed, 9 insertions(+), 2 deletions(-) rename core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/{FloatDoubleConversionsTest.java => FloatDoubleConversionsUnitTest.java} (95%) diff --git a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java similarity index 95% rename from core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java rename to core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java index 9da50276a9..2bddb6d8cd 100644 --- a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsTest.java +++ b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/floatdoubleconversions/FloatDoubleConversionsUnitTest.java @@ -3,7 +3,7 @@ package com.baeldung.floatdoubleconversions; import org.junit.Assert; import org.junit.Test; -public class FloatDoubleConversionsTest { +public class FloatDoubleConversionsUnitTest { @Test public void whenDoubleType_thenFloatTypeSuccess(){ diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 79596d2067..f4bda010e8 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -32,6 +32,7 @@ + core-java-numbers-conversions core-java-9-improvements core-java-9-streams core-java-9 @@ -195,9 +196,10 @@ core-java-records core-java-9-jigsaw + core-java-collections-set core-java-date-operations-1 - + core-java-datetime-conversion core-java-httpclient java-native diff --git a/di-modules/pom.xml b/di-modules/pom.xml index e6c86d48e6..984180cb28 100644 --- a/di-modules/pom.xml +++ b/di-modules/pom.xml @@ -18,6 +18,7 @@ dagger flyway-cdi-extension guice + avaje \ No newline at end of file diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index eb4b212771..8726b7ad87 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -120,6 +120,7 @@ scylladb spring-data-cassandra-2 spring-data-jpa-repo-3 + spring-boot-persistence-4 diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 259a40dc38..433f23f4ba 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -68,6 +68,9 @@ spring-boot-runtime spring-boot-runtime-2 spring-boot-security + spring-boot-security-2 + spring-boot-ssl-bundles + spring-boot-telegram spring-boot-springdoc spring-boot-swagger spring-boot-swagger-2 From 19e70b20a485c7abf466a7fd29557ed31787d601 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 7 Nov 2023 15:58:16 +0530 Subject: [PATCH 133/283] =?UTF-8?q?JAVA-26498:=20Changes=20made=20for=20ad?= =?UTF-8?q?ding=20missed=20module=20core-java-collectio=E2=80=A6=20(#15071?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /core-java-modules/core-java-collections-conversions-2 /core-java-modules/core-java-collections-conversions-3 /core-java-modules/core-java-concurrency-advanced-5 --- core-java-modules/pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index f4bda010e8..a237fe0ed6 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -21,7 +21,9 @@ - + core-java-collections-conversions-2 + core-java-collections-conversions-3 + core-java-concurrency-advanced-5 From 63758605c922c7daa0a8fa3413091967ff2dae5d Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 7 Nov 2023 16:45:05 +0530 Subject: [PATCH 134/283] JAVA-26557: Changes made for Adding missed modules (#15121) /libraries-ai /spring-pulsar /maven-modules/versions-maven-plugin/original --- maven-modules/versions-maven-plugin/original/pom.xml | 5 ----- maven-modules/versions-maven-plugin/pom.xml | 11 +++++++++++ pom.xml | 3 +++ spring-pulsar/pom.xml | 5 +---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/maven-modules/versions-maven-plugin/original/pom.xml b/maven-modules/versions-maven-plugin/original/pom.xml index 2d81274611..6026dac9fe 100644 --- a/maven-modules/versions-maven-plugin/original/pom.xml +++ b/maven-modules/versions-maven-plugin/original/pom.xml @@ -18,11 +18,6 @@ commons-collections4 ${commons-collections4.version} - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - org.apache.commons commons-compress diff --git a/maven-modules/versions-maven-plugin/pom.xml b/maven-modules/versions-maven-plugin/pom.xml index 9c837cefa0..ec1e0ceaba 100644 --- a/maven-modules/versions-maven-plugin/pom.xml +++ b/maven-modules/versions-maven-plugin/pom.xml @@ -7,6 +7,17 @@ versions-maven-plugin 0.0.1-SNAPSHOT versions-maven-plugin + pom + + + maven-modules + com.baeldung + 0.0.1-SNAPSHOT + + + + original + diff --git a/pom.xml b/pom.xml index 12a8f3dc1d..a16fabebc5 100644 --- a/pom.xml +++ b/pom.xml @@ -860,6 +860,7 @@ libraries-http libraries-http-2 libraries-io + libraries-ai libraries-primitive libraries-rpc libraries-server @@ -930,6 +931,7 @@ spring-kafka-2 libraries-llms + spring-pulsar @@ -1212,6 +1214,7 @@ spring-kafka-2 libraries-llms + spring-pulsar diff --git a/spring-pulsar/pom.xml b/spring-pulsar/pom.xml index 05debcab1c..a1c834f830 100644 --- a/spring-pulsar/pom.xml +++ b/spring-pulsar/pom.xml @@ -15,10 +15,6 @@ ../parent-boot-3 - - 17 - 0.2.0 - org.springframework.boot @@ -47,6 +43,7 @@ + 17 0.2.0 From 270acf62e46bc420a0517d756fa63b1742b904b2 Mon Sep 17 00:00:00 2001 From: Niket Agrawal Date: Tue, 7 Nov 2023 21:49:49 +0530 Subject: [PATCH 135/283] Formatter Changes --- .../ResultSetToMapUnitTest.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java index c8a6351804..e449beb83a 100644 --- a/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java +++ b/persistence-modules/core-java-persistence-3/src/test/java/com/baeldung/resultsettomap/ResultSetToMapUnitTest.java @@ -45,7 +45,8 @@ public class ResultSetToMapUnitTest { @Test public void whenUsingContainsKey_thenConvertResultSetToMap() throws SQLException { - ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee").executeQuery(); + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee") + .executeQuery(); Map> valueMap = new HashMap<>(); while (resultSet.next()) { @@ -54,22 +55,27 @@ public class ResultSetToMapUnitTest { if (!valueMap.containsKey(empCity)) { valueMap.put(empCity, new ArrayList<>()); } - valueMap.get(empCity).add(empName); + valueMap.get(empCity) + .add(empName); } - assertEquals(3, valueMap.get("London").size()); + assertEquals(3, valueMap.get("London") + .size()); } @Test public void whenUsingComputeIfAbsent_thenConvertResultSetToMap() throws SQLException { - ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee").executeQuery(); + ResultSet resultSet = connection.prepareStatement("SELECT * FROM employee") + .executeQuery(); Map> valueMap = new HashMap<>(); while (resultSet.next()) { String empCity = resultSet.getString("empCity"); String empName = resultSet.getString("empName"); - valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()).add(empName); + valueMap.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); } - assertEquals(3, valueMap.get("London").size()); + assertEquals(3, valueMap.get("London") + .size()); } @Test @@ -81,15 +87,17 @@ public class ResultSetToMapUnitTest { while (resultSet.next()) { String empCity = resultSet.getString("empCity"); String empName = resultSet.getString("empName"); - result.computeIfAbsent(empCity, data -> new ArrayList<>()).add(empName); + result.computeIfAbsent(empCity, data -> new ArrayList<>()) + .add(empName); } return result; } }; - + QueryRunner run = new QueryRunner(); Map> valueMap = run.query(connection, "SELECT * FROM employee", handler); - assertEquals(3, valueMap.get("London").size()); + assertEquals(3, valueMap.get("London") + .size()); } @After From 362610ca587c741843e616d387f613acad3c1340 Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Tue, 7 Nov 2023 19:21:46 +0100 Subject: [PATCH 136/283] BAEL-6776: Convert File to Byte Array in Java (#15123) --- .../FileToByteArrayUnitTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java diff --git a/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java new file mode 100644 index 0000000000..1bbd958583 --- /dev/null +++ b/core-java-modules/core-java-io-conversions-2/src/test/java/com/baeldung/filetofrombytearray/FileToByteArrayUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.filetofrombytearray; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; + +class FileToByteArrayUnitTest { + + private static final String FILE_NAME = "src" + File.separator + "test" + File.separator + "resources" + File.separator + "sample.txt"; + private final byte[] expectedByteArray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 }; + + @Test + void givenFile_whenUsingFileInputStreamClass_thenConvert() throws IOException { + File myFile = new File(FILE_NAME); + byte[] byteArray = new byte[(int) myFile.length()]; + try (FileInputStream inputStream = new FileInputStream(myFile)) { + inputStream.read(byteArray); + } + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingNioApiFilesClass_thenConvert() throws IOException { + byte[] byteArray = Files.readAllBytes(Paths.get(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingApacheCommonsIOUtilsClass_thenConvert() throws IOException { + File myFile = new File(FILE_NAME); + byte[] byteArray = new byte[(int) myFile.length()]; + try (FileInputStream inputStream = new FileInputStream(myFile)) { + byteArray = IOUtils.toByteArray(inputStream); + } + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingApacheCommonsFileUtilsClass_thenConvert() throws IOException { + byte[] byteArray = FileUtils.readFileToByteArray(new File(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + + @Test + void givenFile_whenUsingGuavaFilesClass_thenConvert() throws IOException { + byte[] byteArray = com.google.common.io.Files.toByteArray(new File(FILE_NAME)); + + assertArrayEquals(expectedByteArray, byteArray); + } + +} From 9b28d7739aade6a5baad097206b655d4aa824025 Mon Sep 17 00:00:00 2001 From: Ehsan Sasanianno Date: Wed, 8 Nov 2023 10:26:53 +0100 Subject: [PATCH 137/283] java-26718: upgrade caffeine version to 3.x (#15138) --- libraries-5/pom.xml | 2 +- spring-5-webflux-2/pom.xml | 2 +- spring-boot-modules/spring-boot-libraries/pom.xml | 2 +- spring-boot-modules/spring-caching-2/pom.xml | 2 ++ spring-boot-modules/spring-caching/pom.xml | 2 ++ 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries-5/pom.xml b/libraries-5/pom.xml index c98a66c094..a043b4bfa8 100644 --- a/libraries-5/pom.xml +++ b/libraries-5/pom.xml @@ -141,7 +141,7 @@ 2.5.11 0.8.1 3.0.14 - 2.5.5 + 3.1.8 3.0.2 4.5.1 1.0 diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 68945138d4..34cbda6c18 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -100,7 +100,7 @@ 3.4.5 - 2.9.2 + 3.1.8 1.16.2 diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml index d8ca53f013..b7b8ad17ad 100644 --- a/spring-boot-modules/spring-boot-libraries/pom.xml +++ b/spring-boot-modules/spring-boot-libraries/pom.xml @@ -228,7 +228,7 @@ 3.3.0 7.6.0 0.7.0 - 2.8.2 + 3.1.8 \ No newline at end of file diff --git a/spring-boot-modules/spring-caching-2/pom.xml b/spring-boot-modules/spring-caching-2/pom.xml index 2239256630..ee28ac5ed5 100644 --- a/spring-boot-modules/spring-caching-2/pom.xml +++ b/spring-boot-modules/spring-caching-2/pom.xml @@ -47,6 +47,7 @@ com.github.ben-manes.caffeine caffeine + ${caffeine.version} it.ozimov @@ -64,6 +65,7 @@ 0.7.3 + 3.1.8 \ No newline at end of file diff --git a/spring-boot-modules/spring-caching/pom.xml b/spring-boot-modules/spring-caching/pom.xml index c27ccf3348..f3d9488b89 100644 --- a/spring-boot-modules/spring-caching/pom.xml +++ b/spring-boot-modules/spring-caching/pom.xml @@ -51,6 +51,7 @@ com.github.ben-manes.caffeine caffeine + ${caffeine.version} com.h2database @@ -78,6 +79,7 @@ 3.5.2 + 3.1.8 \ No newline at end of file From c7e2dc2a6ec7a54633ec4f4c988a7d970e656e56 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:06:28 +0200 Subject: [PATCH 138/283] JAVA-27248 Align module names, folder names and artifact id - Week 44 - 2023 (conti-1) (#15147) Co-authored-by: timis1 --- .../core-java-conditionals/pom.xml | 2 +- core-java-modules/core-java-os-2/pom.xml | 4 ++-- di-modules/avaje/pom.xml | 17 ++++++++++------- spring-6-rsocket/pom.xml | 4 ++-- .../spring-boot-security-2/pom.xml | 2 +- .../spring-boot-ssl-bundles/pom.xml | 10 ++++++---- .../spring-reactive-2/pom.xml | 4 ++-- .../spring-reactive-3/pom.xml | 4 ++-- .../spring-reactive-data-couchbase/pom.xml | 2 +- .../spring-reactive-data/pom.xml | 2 +- 10 files changed, 28 insertions(+), 23 deletions(-) diff --git a/core-java-modules/core-java-conditionals/pom.xml b/core-java-modules/core-java-conditionals/pom.xml index 811f183e99..f2ad7df749 100644 --- a/core-java-modules/core-java-conditionals/pom.xml +++ b/core-java-modules/core-java-conditionals/pom.xml @@ -5,7 +5,7 @@ 4.0.0 core-java-conditionals 0.1.0-SNAPSHOT - core-java-compiler + core-java-conditionals jar diff --git a/core-java-modules/core-java-os-2/pom.xml b/core-java-modules/core-java-os-2/pom.xml index 53fdafa7d4..11b0585ae7 100644 --- a/core-java-modules/core-java-os-2/pom.xml +++ b/core-java-modules/core-java-os-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 - core-java-os - core-java-os + core-java-os-2 + core-java-os-2 jar diff --git a/di-modules/avaje/pom.xml b/di-modules/avaje/pom.xml index 49162c518e..03d3902d5f 100644 --- a/di-modules/avaje/pom.xml +++ b/di-modules/avaje/pom.xml @@ -3,14 +3,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - inject-intro + avaje 0.0.1-SNAPSHOT - avaje-inject-intro - - 11 - 11 - 9.5 - + avaje + Avaje Inject Intro + io.avaje @@ -34,4 +31,10 @@ true + + + 11 + 11 + 9.5 + \ No newline at end of file diff --git a/spring-6-rsocket/pom.xml b/spring-6-rsocket/pom.xml index 5d15a605ae..0f9e63bc7e 100644 --- a/spring-6-rsocket/pom.xml +++ b/spring-6-rsocket/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.bealdung - rsocket + spring-6-rsocket 0.0.1-SNAPSHOT - rsocket + spring-6-rsocket com.baeldung diff --git a/spring-boot-modules/spring-boot-security-2/pom.xml b/spring-boot-modules/spring-boot-security-2/pom.xml index db094f33a6..dd8cab81de 100644 --- a/spring-boot-modules/spring-boot-security-2/pom.xml +++ b/spring-boot-modules/spring-boot-security-2/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-security-2 - spring-boot-security-1 + spring-boot-security-2 jar Spring Boot Security Auto-Configuration diff --git a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml index 4802e9ec58..770d8c2f01 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml +++ b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml @@ -3,16 +3,18 @@ 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-boot-ssl-bundles + spring-boot-ssl-bundles + Module for showing usage of SSL Bundles + jar + com.baeldung parent-boot-3 0.0.1-SNAPSHOT ../../parent-boot-3 - springbootsslbundles - spring-boot-ssl-bundles - jar - Module for showing usage of SSL Bundles + org.springframework.boot diff --git a/spring-reactive-modules/spring-reactive-2/pom.xml b/spring-reactive-modules/spring-reactive-2/pom.xml index 13970851cd..90c5300cc8 100644 --- a/spring-reactive-modules/spring-reactive-2/pom.xml +++ b/spring-reactive-modules/spring-reactive-2/pom.xml @@ -5,9 +5,9 @@ 4.0.0 spring-reactive-2 0.0.1-SNAPSHOT - spring-5-reactive-2 + spring-reactive-2 jar - spring 5 sample project about new features + spring sample project about new features com.baeldung.spring.reactive diff --git a/spring-reactive-modules/spring-reactive-3/pom.xml b/spring-reactive-modules/spring-reactive-3/pom.xml index 96f23f1339..bf2cdbbf2d 100644 --- a/spring-reactive-modules/spring-reactive-3/pom.xml +++ b/spring-reactive-modules/spring-reactive-3/pom.xml @@ -5,9 +5,9 @@ 4.0.0 spring-reactive-3 0.0.1-SNAPSHOT - spring-5-reactive-3 + spring-reactive-3 jar - spring 5 sample project about new features + spring sample project about new features com.baeldung.spring.reactive diff --git a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml index 52b10f39d9..a7481d8aca 100644 --- a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml +++ b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-reactive-data-couchbase - spring-data-couchbase + spring-reactive-data-couchbase jar diff --git a/spring-reactive-modules/spring-reactive-data/pom.xml b/spring-reactive-modules/spring-reactive-data/pom.xml index 03ea440b4f..a598315d5d 100644 --- a/spring-reactive-modules/spring-reactive-data/pom.xml +++ b/spring-reactive-modules/spring-reactive-data/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-reactive-data - spring-reactive-data-2 + spring-reactive-data jar From 7b6ba0e030db93e6faa5b84fe2fdd02a901a5f80 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Wed, 8 Nov 2023 15:54:10 +0530 Subject: [PATCH 139/283] JAVA-26729:Changes made for upgrade commons-validator to latest version (#15159) --- core-java-modules/core-java-datetime-string/pom.xml | 2 +- .../java/com/baeldung/formatinstant/FormatInstantUnitTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-datetime-string/pom.xml b/core-java-modules/core-java-datetime-string/pom.xml index a33114852c..292a38a5af 100644 --- a/core-java-modules/core-java-datetime-string/pom.xml +++ b/core-java-modules/core-java-datetime-string/pom.xml @@ -64,7 +64,7 @@ - 1.6 + 1.7 2.12.5 RELEASE 1.9 diff --git a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java index ef273e4b81..1466fece46 100644 --- a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java +++ b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/formatinstant/FormatInstantUnitTest.java @@ -6,6 +6,7 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.UnsupportedTemporalTypeException; +import java.util.TimeZone; import org.joda.time.format.DateTimeFormat; import org.junit.Test; @@ -17,7 +18,7 @@ public class FormatInstantUnitTest { @Test public void givenInstant_whenUsingDateTimeFormatter_thenFormat() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT) - .withZone(ZoneId.systemDefault()); + .withZone(TimeZone.getTimeZone("UTC").toZoneId()); Instant instant = Instant.parse("2022-02-15T18:35:24.00Z"); String formattedInstant = formatter.format(instant); From 33fceb65a61e7f2f94586809d97911bc066031cb Mon Sep 17 00:00:00 2001 From: Michael Olayemi Date: Wed, 8 Nov 2023 14:16:19 +0100 Subject: [PATCH 140/283] Using CriteriaDefinition Utility in Hibernate (#15128) * Using CriteriaDefinition Utility in Hibernate * Using CriteriaDefinition Utility in Hibernate * Using CriteriaDefinition Utility in Hibernate * Using CriteriaDefinition Utility in Hibernate * Using CriteriaDefinition Utility in Hibernate --- persistence-modules/hibernate-queries/pom.xml | 2 +- .../criteria/util/HibernateUtil.java | 7 + .../CriteriaDefinitionApplicationView.java | 126 ++++++++++++++++++ .../LocalDateStringJavaDescriptor.java | 11 ++ ...nateCriteriaDefinitionIntegrationTest.java | 77 +++++++++++ 5 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java create mode 100644 persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaDefinitionIntegrationTest.java diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index bb60c7b83a..76f230a72d 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -99,7 +99,7 @@ 8.0.32 2.6.0 2.1.214 - 6.1.7.Final + 6.3.1.Final 1.17.6 diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java index ff9ccb017b..f561a33f08 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java @@ -16,4 +16,11 @@ public class HibernateUtil { return session; } + public static SessionFactory getHibernateSessionFactory() { + + final SessionFactory sessionFactory = new Configuration().configure("criteria.cfg.xml").buildSessionFactory(); + + return sessionFactory; + } + } diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java new file mode 100644 index 0000000000..9f32aa06e3 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/CriteriaDefinitionApplicationView.java @@ -0,0 +1,126 @@ +package com.baeldung.hibernate.criteria.view; + +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.criteria.CriteriaDefinition; +import org.hibernate.query.criteria.JpaRoot; + +import com.baeldung.hibernate.criteria.model.Item; +import com.baeldung.hibernate.criteria.util.HibernateUtil; + +public class CriteriaDefinitionApplicationView { + + public CriteriaDefinitionApplicationView() { + + } + + public String[] greaterThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot message = from(Item.class); + where(gt(message.get("itemPrice"), 1000)); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String greaterThanItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + greaterThanItems[i] = items.get(i).getItemName(); + } + + session.close(); + + return greaterThanItems; + } + + public String[] lessThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot message = from(Item.class); + where(lt(message.get("itemPrice"), 1000)); + } + }; + + List items = session.createSelectionQuery(query).list(); + final String lessThanItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + lessThanItems[i] = items.get(i).getItemName(); + } + + session.close(); + + return lessThanItems; + } + + public String[] likeCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(like(item.get("itemName"), "%chair%")); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String likeItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + likeItems[i] = items.get(i).getItemName(); + } + session.close(); + return likeItems; + } + + public String[] likeCaseCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(like(lower(item.get("itemName")), "%chair%")); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String likeItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + likeItems[i] = items.get(i).getItemName(); + } + session.close(); + return likeItems; + } + + public String[] betweenCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final SessionFactory sessionFactory = HibernateUtil.getHibernateSessionFactory(); + + CriteriaDefinition query = new CriteriaDefinition<>(sessionFactory, Item.class) { + { + JpaRoot item = from(Item.class); + where(between(item.get("itemPrice"), 100, 200)); + } + }; + + List items = session.createSelectionQuery(query).list(); + + final String betweenItems[] = new String[items.size()]; + for (int i = 0; i < items.size(); i++) { + betweenItems[i] = items.get(i).getItemName(); + } + session.close(); + return betweenItems; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java index 58d8e8628a..e9c7548c7d 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/customtypes/LocalDateStringJavaDescriptor.java @@ -4,8 +4,13 @@ package com.baeldung.hibernate.customtypes; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import org.hibernate.dialect.Dialect; +import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; +import org.hibernate.type.BasicType; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; +import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; +import org.hibernate.type.spi.TypeConfiguration; import io.hypersistence.utils.hibernate.type.array.internal.AbstractArrayTypeDescriptor; @@ -49,4 +54,10 @@ public class LocalDateStringJavaDescriptor extends AbstractArrayTypeDescriptor expectedLikeList = session.createQuery("From Item where itemName like '%chair%'").list(); + final String expectedLikeItems[] = new String[expectedLikeList.size()]; + for (int i = 0; i < expectedLikeList.size(); i++) { + expectedLikeItems[i] = expectedLikeList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedLikeItems, criteriaDefinition.likeCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingCaseSensitiveLikeCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedChairCaseList = session.createQuery("From Item where itemName like '%Chair%'").list(); + final String expectedChairCaseItems[] = new String[expectedChairCaseList.size()]; + for (int i = 0; i < expectedChairCaseList.size(); i++) { + expectedChairCaseItems[i] = expectedChairCaseList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedChairCaseItems, criteriaDefinition.likeCaseCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingGreaterThanCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedGreaterThanList = session.createQuery("From Item where itemPrice>1000").list(); + final String expectedGreaterThanItems[] = new String[expectedGreaterThanList.size()]; + for (int i = 0; i < expectedGreaterThanList.size(); i++) { + expectedGreaterThanItems[i] = expectedGreaterThanList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedGreaterThanItems, criteriaDefinition.greaterThanCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingLessThanCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedLessList = session.createQuery("From Item where itemPrice<1000").list(); + final String expectedLessThanItems[] = new String[expectedLessList.size()]; + for (int i = 0; i < expectedLessList.size(); i++) { + expectedLessThanItems[i] = expectedLessList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedLessThanItems, criteriaDefinition.lessThanCriteria()); + } + + @Test + public void givenHibernateSession_whenExecutingBetweenCriteriaQuery_thenExpectMatchingItems() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedBetweenList = session.createQuery("From Item where itemPrice between 100 and 200").list(); + final String expectedPriceBetweenItems[] = new String[expectedBetweenList.size()]; + for (int i = 0; i < expectedBetweenList.size(); i++) { + expectedPriceBetweenItems[i] = expectedBetweenList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedPriceBetweenItems, criteriaDefinition.betweenCriteria()); + } + + +} From 7e81d666c9a10ca2bd3128f73c538f1832b46854 Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Thu, 9 Nov 2023 00:08:33 +0200 Subject: [PATCH 141/283] This commit related to BAEL-7103 (#15160) This commit aims to add a test class named "ConvertingHashSetToArrayUnitTest" that provides test methods to convert HashSet to an array. --- .../ConvertingHashSetToArrayUnitTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java diff --git a/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java b/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java new file mode 100644 index 0000000000..420c1d25e6 --- /dev/null +++ b/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.toarraymethod; + +import org.junit.Test; + +import java.util.HashSet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ConvertingHashSetToArrayUnitTest { + + @Test + public void givenStringHashSet_whenConvertedToArray_thenArrayContainsStringElements() { + HashSet stringSet = new HashSet<>(); + stringSet.add("Apple"); + stringSet.add("Banana"); + stringSet.add("Cherry"); + + // Convert the HashSet of Strings to an array of Strings + String[] stringArray = stringSet.toArray(new String[0]); + + // Test that the array is of the correct length + assertEquals(3, stringArray.length); + + for (String str : stringArray) { + assertTrue(stringSet.contains(str)); + } + } + + @Test + public void givenIntegerHashSet_whenConvertedToArray_thenArrayContainsIntegerElements() { + HashSet integerSet = new HashSet<>(); + integerSet.add(5); + integerSet.add(10); + integerSet.add(15); + + // Convert the HashSet of Integers to an array of Integers + Integer[] integerArray = integerSet.toArray(new Integer[0]); + + // Test that the array is of the correct length + assertEquals(3, integerArray.length); + + for (Integer num : integerArray) { + assertTrue(integerSet.contains(num)); + } + + assertTrue(integerSet.contains(5)); + assertTrue(integerSet.contains(10)); + assertTrue(integerSet.contains(15)); + } +} From 5b596e0c49cea6914ba563d15d116303c40670c2 Mon Sep 17 00:00:00 2001 From: Alexander Molochko Date: Wed, 8 Nov 2023 18:05:37 -0700 Subject: [PATCH 142/283] BAEL-7012: Splitting Streams in Kafka (#15029) * BAEL-7012: Splitting Streams in Kafka * Move sources to the spring-kafka module * Move sources to the spring-kafka-2 module --- spring-kafka-2/pom.xml | 2 + .../kafka/kafkasplitting/IotSensorData.java | 31 ++++++++++ .../kafkasplitting/KafkaConsumerConfig.java | 43 +++++++++++++ .../KafkaIotConsumerService.java | 28 +++++++++ .../kafkasplitting/KafkaStreamsConfig.java | 62 +++++++++++++++++++ .../SpringBootKafkaStreamsSplittingApp.java | 12 ++++ .../src/main/resources/application.properties | 4 ++ 7 files changed, 182 insertions(+) create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java diff --git a/spring-kafka-2/pom.xml b/spring-kafka-2/pom.xml index 0bca20447d..fdf7da7438 100644 --- a/spring-kafka-2/pom.xml +++ b/spring-kafka-2/pom.xml @@ -65,6 +65,8 @@ 1.16.2 + 3.0.12 + 3.6.0 1.16.2 diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java new file mode 100644 index 0000000000..350f6911f3 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/IotSensorData.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +public class IotSensorData { + private String sensorType; + private String value; + private String sensorId; + + public String getSensorType() { + return sensorType; + } + + public void setSensorType(String sensorType) { + this.sensorType = sensorType; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getSensorId() { + return sensorId; + } + + public void setSensorId(String sensorId) { + this.sensorId = sensorId; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java new file mode 100644 index 0000000000..70640cb582 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaConsumerConfig.java @@ -0,0 +1,43 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.config.KafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; +import org.springframework.kafka.support.serializer.JsonDeserializer; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +class KafkaConsumerConfig { + + @Value("${spring.kafka.consumer.group-id}") + private String groupId; + @Value("${spring.kafka.bootstrap-servers}") + private String bootstrapServers; + + @Bean + public ConsumerFactory consumerFactory() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class); + + return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(IotSensorData.class)); + } + + @Bean + KafkaListenerContainerFactory> kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java new file mode 100644 index 0000000000..bbd0c549ab --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaIotConsumerService.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Service; + +@Service +public class KafkaIotConsumerService { + + @KafkaListener(topics = "iot_sensor_data") + public void consumeIotData(IotSensorData item) { + System.out.println("Consumed Message in original \"iot_sensor_data\" topic :" + item.getSensorType()); + } + + @KafkaListener(topics = "iot_sensor_data_temp") + public void consumeIotTemperatureData(IotSensorData item) { + System.out.println("Consumed Temparature data :" + item.getValue()); + } + + @KafkaListener(topics = "iot_sensor_data_hum") + public void consumeIotHumidityData(IotSensorData item) { + System.out.println("Consumed Humidity data :" + item.getValue()); + } + + @KafkaListener(topics = "iot_sensor_data_move") + public void consumeIotMovementData(IotSensorData item) { + System.out.println("Consumed Movement data :" + item.getValue()); + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java new file mode 100644 index 0000000000..c4eb1501fd --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/KafkaStreamsConfig.java @@ -0,0 +1,62 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.apache.kafka.common.serialization.Serde; +import org.apache.kafka.common.serialization.Serdes; +import org.apache.kafka.streams.StreamsBuilder; +import org.apache.kafka.streams.kstream.Branched; +import org.apache.kafka.streams.kstream.Consumed; +import org.apache.kafka.streams.kstream.KStream; +import org.apache.kafka.streams.processor.TopicNameExtractor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.annotation.EnableKafkaStreams; +import org.springframework.kafka.support.KafkaStreamBrancher; +import org.springframework.kafka.support.serializer.JsonDeserializer; +import org.springframework.kafka.support.serializer.JsonSerializer; + +@Configuration +@EnableKafka +@EnableKafkaStreams +class KafkaStreamsConfig { + @Value("${kafka.topics.iot}") + private String iotTopicName; + + @Bean + public Serde iotSerde() { + return Serdes.serdeFrom(new JsonSerializer<>(), new JsonDeserializer<>(IotSensorData.class)); + } + + @Bean + public KStream iotStream(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + stream.split() + .branch((key, value) -> value.getSensorType() != null, + Branched.withConsumer(ks -> ks.to((key, value, recordContext) -> String.format("%s_%s", iotTopicName, value.getSensorType())))) + .noDefaultBranch(); + return stream; + } + + @Bean + public KStream iotBrancher(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + + new KafkaStreamBrancher() + .branch((key, value) -> "temp".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_temp")) + .branch((key, value) -> "move".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_move")) + .branch((key, value) -> "hum".equals(value.getSensorType()), (ks) -> ks.to(iotTopicName + "_hum")) + .defaultBranch(ks -> ks.to(String.format("%s_unknown", iotTopicName))) + .onTopOf(stream); + + return stream; + } + + @Bean + public KStream iotTopicExtractor(StreamsBuilder streamsBuilder) { + KStream stream = streamsBuilder.stream(iotTopicName, Consumed.with(Serdes.String(), iotSerde())); + TopicNameExtractor sensorTopicExtractor = (key, value, recordContext) -> String.format("%s_%s", iotTopicName, value.getSensorType()); + stream.to(sensorTopicExtractor); + return stream; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java new file mode 100644 index 0000000000..6101eeb13d --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/kafkasplitting/SpringBootKafkaStreamsSplittingApp.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.kafka.kafkasplitting; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootKafkaStreamsSplittingApp { + public static void main(String[] args) { + SpringApplication.run(SpringBootKafkaStreamsSplittingApp.class, args); + } + +} diff --git a/spring-kafka-2/src/main/resources/application.properties b/spring-kafka-2/src/main/resources/application.properties index ed844cadf8..9111491b58 100644 --- a/spring-kafka-2/src/main/resources/application.properties +++ b/spring-kafka-2/src/main/resources/application.properties @@ -19,4 +19,8 @@ kafka.backoff.max_failure=5 # multiple listeners properties multiple-listeners.books.topic.name=books +spring.kafka.streams.application-id=baeldung-streams +spring.kafka.consumer.group-id=baeldung-group +spring.kafka.streams.properties[default.key.serde]=org.apache.kafka.common.serialization.Serdes$StringSerde +kafka.topics.iot=iot_sensor_data From f33372e091a921a22e616f50e088820693130c79 Mon Sep 17 00:00:00 2001 From: hmdrz Date: Thu, 9 Nov 2023 11:21:54 +0330 Subject: [PATCH 143/283] #BAEL-7157: add one extra method --- .../test/java/com/baeldung/testsuite/ClassOneUnitTest.java | 4 ++++ .../com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java index 4ce092796e..cfb77c8d41 100644 --- a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/ClassOneUnitTest.java @@ -10,4 +10,8 @@ public class ClassOneUnitTest { Assertions.assertTrue(true); } + @Test + public void whenFalse_thenFalse() { + Assertions.assertFalse(false); + } } diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java index bb63fcda63..be5b3380c7 100644 --- a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/subpackage/ClassTwoUnitTest.java @@ -8,4 +8,9 @@ public class ClassTwoUnitTest { public void whenTrue_thenTrue() { Assertions.assertTrue(true); } + + @Test + public void whenFalse_thenFalse() { + Assertions.assertFalse(false); + } } From b6d28c44461e31609295637e87de8e7b463652fb Mon Sep 17 00:00:00 2001 From: hmdrz Date: Thu, 9 Nov 2023 11:22:14 +0330 Subject: [PATCH 144/283] #BAEL-7157: add main test suite --- .../testsuite/suites/JUnitSelectMethodsSuite.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java new file mode 100644 index 0000000000..e0d17dc0e4 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/testsuite/suites/JUnitSelectMethodsSuite.java @@ -0,0 +1,14 @@ +package com.baeldung.testsuite.suites; + +import com.baeldung.testsuite.ClassOneUnitTest; +import org.junit.platform.suite.api.SelectMethod; +import org.junit.platform.suite.api.Suite; +import org.junit.platform.suite.api.SuiteDisplayName; + +@Suite +@SuiteDisplayName("My Test Suite") +@SelectMethod(type = ClassOneUnitTest.class, name = "whenFalse_thenFalse") +@SelectMethod("com.baeldung.testsuite.subpackage.ClassTwoUnitTest#whenFalse_thenFalse") +public class JUnitSelectMethodsSuite { + // runs ClassOneUnitTest and ClassTwoUnitTest +} \ No newline at end of file From 75a64be865bd573134dce88a48582e44ebca7e1a Mon Sep 17 00:00:00 2001 From: hmdrz Date: Thu, 9 Nov 2023 11:22:48 +0330 Subject: [PATCH 145/283] #BAEL-7157: upgrade dependency version and add extra dependencies --- testing-modules/junit-5-advanced/pom.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 3ae62eac2e..411f189638 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -45,7 +45,18 @@ ${junit-platform.version} test - + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + + + org.junit.platform + junit-platform-commons + ${junit-platform.version} + test + @@ -70,7 +81,7 @@ 1.49 3.24.2 - 1.9.2 + 1.10.1 3.0.0 From 781b7fde457d67c1549ec8f12d90c0dde15b6c05 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Thu, 9 Nov 2023 15:27:46 +0530 Subject: [PATCH 146/283] JAVA-27244: Changes made removing comment from modules that are added already (#15161) --- pom.xml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index a16fabebc5..ffd39b7ea2 100644 --- a/pom.xml +++ b/pom.xml @@ -362,7 +362,7 @@ web-modules/java-lite persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq spring-ejb-modules/ejb-beans @@ -533,7 +533,7 @@ web-modules/java-lite persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq spring-ejb-modules/ejb-beans @@ -854,7 +854,7 @@ libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io - libraries-data-2 + libraries-data-2 libraries-data-io libraries-files libraries-http @@ -929,7 +929,7 @@ gcp-firebase spring-di-4 spring-kafka-2 - + libraries-llms spring-pulsar @@ -1039,14 +1039,6 @@ core-java-modules gcp-firebase - - - - - - - - spring-aop spring-aop-2 custom-pmd @@ -1138,7 +1130,7 @@ libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io - libraries-data-2 + libraries-data-2 libraries-data-io libraries-files libraries-http @@ -1212,7 +1204,7 @@ spring-actuator spring-di-4 spring-kafka-2 - + libraries-llms spring-pulsar From 4145926d9421d1652383606066a2ee84cb398652 Mon Sep 17 00:00:00 2001 From: gaepi Date: Thu, 9 Nov 2023 11:55:32 +0100 Subject: [PATCH 147/283] JAVA-27245 - renamed modules. --- .../spring-cloud-bootstrap/README.md | 2 +- .../spring-cloud-bootstrap/pom.xml | 4 ++-- .../{svc-book => zipkin-log-svc-book}/pom.xml | 4 ++-- .../bootstrap/svcbook/BookServiceApplication.java | 0 .../cloud/bootstrap/svcbook/CookieConfig.java | 0 .../spring/cloud/bootstrap/svcbook/DataLoader.java | 0 .../cloud/bootstrap/svcbook/SecurityConfig.java | 0 .../cloud/bootstrap/svcbook/SessionConfig.java | 0 .../spring/cloud/bootstrap/svcbook/book/Book.java | 0 .../bootstrap/svcbook/book/BookController.java | 0 .../svcbook/book/BookNotFoundException.java | 0 .../bootstrap/svcbook/book/BookRepository.java | 0 .../cloud/bootstrap/svcbook/book/BookService.java | 0 .../src/main/resources/bootstrap.properties | 0 .../src/main/resources/logback.xml | 0 .../java/com/baeldung/SpringContextLiveTest.java | 0 .../src/test/resources/bootstrap.properties | 0 .../{svc-rating => zipkin-log-svc-rating}/pom.xml | 4 ++-- .../cloud/bootstrap/svcrating/CookieConfig.java | 0 .../cloud/bootstrap/svcrating/DataLoader.java | 0 .../svcrating/RatingServiceApplication.java | 0 .../cloud/bootstrap/svcrating/SecurityConfig.java | 0 .../cloud/bootstrap/svcrating/SessionConfig.java | 0 .../cloud/bootstrap/svcrating/rating/Rating.java | 0 .../svcrating/rating/RatingCacheRepository.java | 0 .../svcrating/rating/RatingController.java | 0 .../svcrating/rating/RatingNotFoundException.java | 0 .../svcrating/rating/RatingRepository.java | 0 .../bootstrap/svcrating/rating/RatingService.java | 0 .../src/main/resources/bootstrap.properties | 0 .../src/main/resources/logback.xml | 0 .../java/com/baeldung/SpringContextLiveTest.java | 0 .../src/test/resources/bootstrap.properties | 0 .../kubernetes-minikube/demo-backend/Dockerfile | 5 ----- .../kubernetes-minikube/demo-frontend/Dockerfile | 5 ----- .../.gitignore | 0 .../minikube-demo-backend/Dockerfile | 5 +++++ .../pom.xml | 4 ++-- .../backend/KubernetesBackendApplication.java | 0 .../src/main/resources/application.properties | 0 .../src/main/resources/logback.xml | 0 .../test/java/com/baeldung/SpringContextTest.java | 0 .../.gitignore | 0 .../minikube-demo-frontend/Dockerfile | 5 +++++ .../pom.xml | 4 ++-- .../frontend/KubernetesFrontendApplication.java | 2 +- .../src/main/resources/application.properties | 0 .../src/main/resources/logback.xml | 0 .../test/java/com/baeldung/SpringContextTest.java | 0 .../object-configurations/backend-deployment.yaml | 14 +++++++------- .../object-configurations/frontend-deployment.yaml | 14 +++++++------- .../kubernetes-minikube/pom.xml | 4 ++-- 52 files changed, 38 insertions(+), 38 deletions(-) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/pom.xml (96%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/resources/bootstrap.properties (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/main/resources/logback.xml (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/test/java/com/baeldung/SpringContextLiveTest.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-book => zipkin-log-svc-book}/src/test/resources/bootstrap.properties (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/pom.xml (97%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/resources/bootstrap.properties (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/main/resources/logback.xml (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/test/java/com/baeldung/SpringContextLiveTest.java (100%) rename spring-cloud-modules/spring-cloud-bootstrap/{svc-rating => zipkin-log-svc-rating}/src/test/resources/bootstrap.properties (100%) delete mode 100644 spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile delete mode 100644 spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-backend}/.gitignore (100%) create mode 100644 spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-backend}/pom.xml (91%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-backend}/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-backend}/src/main/resources/application.properties (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-backend}/src/main/resources/logback.xml (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-backend}/src/test/java/com/baeldung/SpringContextTest.java (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-frontend}/.gitignore (100%) create mode 100644 spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-backend => minikube-demo-frontend}/pom.xml (91%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-frontend}/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java (95%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-frontend}/src/main/resources/application.properties (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-frontend}/src/main/resources/logback.xml (100%) rename spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/{demo-frontend => minikube-demo-frontend}/src/test/java/com/baeldung/SpringContextTest.java (100%) diff --git a/spring-cloud-modules/spring-cloud-bootstrap/README.md b/spring-cloud-modules/spring-cloud-bootstrap/README.md index 252058be1f..661dd7c647 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/README.md +++ b/spring-cloud-modules/spring-cloud-bootstrap/README.md @@ -21,4 +21,4 @@ This module contains articles about bootstrapping Spring Cloud applications that - git commit -m "First commit" - start the config server - start the discovery server - - start all the other servers in any order (gateway, svc-book, svc-rating, zipkin) + - start all the other servers in any order (gateway, zipkin-log-svc-book, zipkin-log-svc-rating, zipkin) diff --git a/spring-cloud-modules/spring-cloud-bootstrap/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/pom.xml index f4d4073ef1..73b07c826f 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/pom.xml @@ -19,8 +19,8 @@ discovery gateway gateway-2 - svc-book - svc-rating + zipkin-log-svc-book + zipkin-log-svc-rating customer-service order-service diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml similarity index 96% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml index c973968a70..2a6196b92b 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.spring.cloud - svc-book + zipkin-log-svc-book 1.0.0-SNAPSHOT - svc-book + zipkin-log-svc-book com.baeldung diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/CookieConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/DataLoader.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/java/com/baeldung/SpringContextLiveTest.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-book/src/test/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml similarity index 97% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml index 29ebb4c4bc..54572eeea2 100644 --- a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/pom.xml +++ b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.spring.cloud - svc-rating + zipkin-log-svc-rating 1.0.0-SNAPSHOT - svc-rating + zipkin-log-svc-rating com.baeldung diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/CookieConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/DataLoader.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingCacheRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/java/com/baeldung/SpringContextLiveTest.java diff --git a/spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties b/spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/resources/bootstrap.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties rename to spring-cloud-modules/spring-cloud-bootstrap/zipkin-log-svc-rating/src/test/resources/bootstrap.properties diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile deleted file mode 100644 index a0a9d57662..0000000000 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM openjdk:8-jdk-alpine -VOLUME /tmp -COPY target/demo-backend-1.0-SNAPSHOT.jar app.jar -ENV JAVA_OPTS="" -ENTRYPOINT exec java -jar /app.jar --debug \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile deleted file mode 100644 index 69adb03a17..0000000000 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM openjdk:8-jdk-alpine -VOLUME /tmp -COPY target/demo-frontend-1.0-SNAPSHOT.jar app.jar -ENV JAVA_OPTS="" -ENTRYPOINT exec java -jar /app.jar \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/.gitignore b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/.gitignore similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/.gitignore rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/.gitignore diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile new file mode 100644 index 0000000000..fad9c11a73 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:8-jdk-alpine +VOLUME /tmp +COPY target/minikube-demo-backend-1.0-SNAPSHOT.jar app.jar +ENV JAVA_OPTS="" +ENTRYPOINT exec java -jar /app.jar --debug \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/pom.xml similarity index 91% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/pom.xml index 85eb944b27..c08c6a5a9d 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/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 - demo-frontend - demo-frontend + minikube-demo-backend + minikube-demo-backend com.baeldung.spring.cloud diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplication.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/application.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/application.properties rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/application.properties diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/src/test/java/com/baeldung/SpringContextTest.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-backend/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/.gitignore b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/.gitignore similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/.gitignore rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/.gitignore diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile new file mode 100644 index 0000000000..207114b1b5 --- /dev/null +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:8-jdk-alpine +VOLUME /tmp +COPY target/minikube-demo-frontend-1.0-SNAPSHOT.jar app.jar +ENV JAVA_OPTS="" +ENTRYPOINT exec java -jar /app.jar \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/pom.xml similarity index 91% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/pom.xml index 2b3f849145..8140807606 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-backend/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/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 - demo-backend - demo-backend + minikube-demo-frontend + minikube-demo-frontend com.baeldung.spring.cloud diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java similarity index 95% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java index 635a79e8bb..d76fcdfd5d 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplication.java @@ -22,7 +22,7 @@ public class KubernetesFrontendApplication { RestTemplate restTemplate = new RestTemplate(); String resourceUrl - = "http://demo-backend:8080"; + = "http://minikube-demo-backend:8080"; ResponseEntity response = restTemplate.getForEntity(resourceUrl, String.class); return "Message from backend is: " + response.getBody(); diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/application.properties b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/application.properties similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/application.properties rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/application.properties diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/logback.xml similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/main/resources/logback.xml rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/main/resources/logback.xml diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/demo-frontend/src/test/java/com/baeldung/SpringContextTest.java rename to spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/minikube-demo-frontend/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml index a7e26a6ec5..bcfa80cd7f 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/backend-deployment.yaml @@ -1,10 +1,10 @@ kind: Service apiVersion: v1 metadata: - name: demo-backend + name: minikube-demo-backend spec: selector: - app: demo-backend + app: minikube-demo-backend tier: backend ports: - protocol: TCP @@ -14,22 +14,22 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: demo-backend + name: dminikube-demo-backend spec: selector: matchLabels: - app: demo-backend + app: minikube-demo-backend tier: backend replicas: 3 template: metadata: labels: - app: demo-backend + app: minikube-demo-backend tier: backend spec: containers: - - name: demo-backend - image: demo-backend:latest + - name: minikube-demo-backend + image: minikube-demo-backend:latest imagePullPolicy: Never ports: - containerPort: 8080 diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml index bf44dce21c..f96c7a1a9c 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/object-configurations/frontend-deployment.yaml @@ -1,10 +1,10 @@ kind: Service apiVersion: v1 metadata: - name: demo-frontend + name: minikube-demo-frontend spec: selector: - app: demo-frontend + app: minikube-demo-frontend ports: - protocol: TCP port: 8081 @@ -14,20 +14,20 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: demo-frontend + name: minikube-demo-frontend spec: selector: matchLabels: - app: demo-frontend + app: minikube-demo-frontend replicas: 3 template: metadata: labels: - app: demo-frontend + app: minikube-demo-frontend spec: containers: - - name: demo-frontend - image: demo-frontend:latest + - name: minikube-demo-frontend + image: minikube-demo-frontend:latest imagePullPolicy: Never ports: - containerPort: 8081 diff --git a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml index b778ee1b57..1c7456d007 100644 --- a/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml +++ b/spring-cloud-modules/spring-cloud-kubernetes/kubernetes-minikube/pom.xml @@ -14,8 +14,8 @@ - demo-backend - demo-frontend + minikube-demo-backend + minikube-demo-frontend \ No newline at end of file From d1685c42bd9f2692f16dd5f86f837d4c9714f051 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Thu, 9 Nov 2023 16:47:34 +0530 Subject: [PATCH 148/283] JAVA-26001_D_M: Fix formatting of POMs for modules D to M (#14958) --- google-auto-project/pom.xml | 1 - json-modules/json-2/pom.xml | 4 ++-- .../jacoco-coverage-services-example/pom.xml | 7 +++---- maven-modules/jacoco-coverage-aggregation/pom.xml | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/google-auto-project/pom.xml b/google-auto-project/pom.xml index 034fea5aad..175e0c20c6 100644 --- a/google-auto-project/pom.xml +++ b/google-auto-project/pom.xml @@ -8,7 +8,6 @@ google-auto-project pom - com.baeldung parent-modules diff --git a/json-modules/json-2/pom.xml b/json-modules/json-2/pom.xml index 6cca576fb1..b9a75e8aff 100644 --- a/json-modules/json-2/pom.xml +++ b/json-modules/json-2/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 json-2 0.0.1-SNAPSHOT diff --git a/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml b/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml index 2c06694b46..223689f8ff 100644 --- a/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml +++ b/maven-modules/jacoco-coverage-aggregation/jacoco-coverage-services-example/pom.xml @@ -13,8 +13,7 @@ jacoco-coverage-aggregation 1.0 - - + org.springframework @@ -28,7 +27,7 @@ test - + @@ -43,7 +42,7 @@ - + 5.9.2 6.0.11 diff --git a/maven-modules/jacoco-coverage-aggregation/pom.xml b/maven-modules/jacoco-coverage-aggregation/pom.xml index 70243973e8..6d1aab3c3d 100644 --- a/maven-modules/jacoco-coverage-aggregation/pom.xml +++ b/maven-modules/jacoco-coverage-aggregation/pom.xml @@ -21,7 +21,7 @@ jacoco-coverage-controllers-example jacoco-coverage-aggregate-report - + From 3fbd2eaab9561c4fa34d3b982c349e66c24de632 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Thu, 9 Nov 2023 16:48:02 +0530 Subject: [PATCH 149/283] JAVA-26001_Q_Z: Fix formatting of POMs for modules Q to Z (#14960) --- pom.xml | 4 +- spring-6-rsocket/pom.xml | 7 +- spring-aop-2/pom.xml | 94 +++++++++---------- .../spring-boot-3-testcontainers/pom.xml | 5 +- .../spring-boot-graalvm-docker/pom.xml | 61 ++++++------ .../spring-boot-jasypt/pom.xml | 3 +- .../spring-boot-ssl-bundles/pom.xml | 4 +- .../spring-boot-telegram/pom.xml | 4 +- .../spring-5-reactive/pom.xml | 0 .../spring-reactive-data-couchbase/pom.xml | 4 +- testing-modules/junit-5-basics-2/pom.xml | 9 +- 11 files changed, 100 insertions(+), 95 deletions(-) create mode 100644 spring-reactive-modules/spring-5-reactive/pom.xml diff --git a/pom.xml b/pom.xml index ffd39b7ea2..bb5a0c9e7b 100644 --- a/pom.xml +++ b/pom.xml @@ -344,7 +344,7 @@ core-java-modules/core-java-security core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 - + core-java-modules/core-java-streams-2 @@ -517,7 +517,7 @@ core-java-modules/core-java-security core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 - + core-java-modules/core-java-streams-2 diff --git a/spring-6-rsocket/pom.xml b/spring-6-rsocket/pom.xml index 0f9e63bc7e..7f88df01e2 100644 --- a/spring-6-rsocket/pom.xml +++ b/spring-6-rsocket/pom.xml @@ -1,7 +1,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 com.bealdung spring-6-rsocket @@ -16,7 +16,6 @@ - org.springframework.boot spring-boot-starter-rsocket @@ -66,9 +65,11 @@ + 3.1.3 1.4.11 2.0.9 + diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index 206e1d7d7c..f1257369e0 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -74,54 +74,54 @@ - - compile-time-weaving + + compile-time-weaving - - - org.springframework - spring-aspects - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest - - - - - org.codehaus.mojo - aspectj-maven-plugin - ${aspectj-plugin.version} - - ${java.version} - ${java.version} - ${java.version} - ignore - UTF-8 - - - org.springframework - spring-aspects - - - - - - - compile - - - - - - - + + + org.springframework + spring-aspects + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj-plugin.version} + + ${java.version} + ${java.version} + ${java.version} + ignore + UTF-8 + + + org.springframework + spring-aspects + + + + + + + compile + + + + + + + load-time-weaving diff --git a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml index 173fb8795c..d24da58742 100644 --- a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml +++ b/spring-boot-modules/spring-boot-3-testcontainers/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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-3-testcontainers 0.0.1-SNAPSHOT @@ -16,7 +16,6 @@ - org.springframework.boot spring-boot-starter diff --git a/spring-boot-modules/spring-boot-graalvm-docker/pom.xml b/spring-boot-modules/spring-boot-graalvm-docker/pom.xml index a3a1b148c2..253e8fceb6 100644 --- a/spring-boot-modules/spring-boot-graalvm-docker/pom.xml +++ b/spring-boot-modules/spring-boot-graalvm-docker/pom.xml @@ -1,41 +1,44 @@ - + 4.0.0 - - - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 - - com.baeldung spring-boot-graalvm-docker 1.0.0 spring-boot-graalvm-docker Spring Boot GrralVM with Docker + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + - - - org.graalvm.buildtools - native-maven-plugin - - - org.springframework.boot - spring-boot-maven-plugin - - + + + org.graalvm.buildtools + native-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-boot-modules/spring-boot-jasypt/pom.xml b/spring-boot-modules/spring-boot-jasypt/pom.xml index 70bbe35319..0f9ad72b64 100644 --- a/spring-boot-modules/spring-boot-jasypt/pom.xml +++ b/spring-boot-modules/spring-boot-jasypt/pom.xml @@ -27,7 +27,7 @@ com.github.ulisesbocchio - jasypt-spring-boot-starter + jasypt-spring-boot-starter ${jasypt.version} @@ -49,4 +49,5 @@ 3.0.5 + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml b/spring-boot-modules/spring-boot-ssl-bundles/pom.xml index 770d8c2f01..1f4e58f21f 100644 --- a/spring-boot-modules/spring-boot-ssl-bundles/pom.xml +++ b/spring-boot-modules/spring-boot-ssl-bundles/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 spring-boot-ssl-bundles spring-boot-ssl-bundles diff --git a/spring-boot-modules/spring-boot-telegram/pom.xml b/spring-boot-modules/spring-boot-telegram/pom.xml index 67fdf197f8..9077e90400 100644 --- a/spring-boot-modules/spring-boot-telegram/pom.xml +++ b/spring-boot-modules/spring-boot-telegram/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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baelding spring-boot-telegram diff --git a/spring-reactive-modules/spring-5-reactive/pom.xml b/spring-reactive-modules/spring-5-reactive/pom.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml index a7481d8aca..2ac8ad19ac 100644 --- a/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml +++ b/spring-reactive-modules/spring-reactive-data-couchbase/pom.xml @@ -1,7 +1,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-reactive-data-couchbase spring-reactive-data-couchbase diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml index 85b6c707fb..b430161380 100644 --- a/testing-modules/junit-5-basics-2/pom.xml +++ b/testing-modules/junit-5-basics-2/pom.xml @@ -1,16 +1,16 @@ + 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-basics-2 + com.baeldung parent-modules 1.0.0-SNAPSHOT - junit-5-basics-2 - commons-cli @@ -30,6 +30,7 @@ test + From bf5328c3970a508bbbb47257e5ea222363b27fa8 Mon Sep 17 00:00:00 2001 From: timis1 Date: Thu, 9 Nov 2023 14:39:49 +0200 Subject: [PATCH 150/283] JAVA-27237 Review log statements for projects | Week 44 | Manually Created (conti-1) --- .../src/main/resources/logback.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml index d944288ca4..1533b49c06 100644 --- a/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml +++ b/spring-cloud-modules/spring-cloud-netflix-sidecar/spring-cloud-netflix-sidecar-demo/src/main/resources/logback.xml @@ -8,7 +8,9 @@ - + + + From 4cf46ce71908be7608b8a707feaca7e49f0213d3 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Thu, 9 Nov 2023 19:19:22 +0530 Subject: [PATCH 151/283] JAVA-27190 Upgrade hibernate validator version --- .../custom-validations-opeanpi-codegen/pom.xml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index b57a014a8f..573b132467 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -27,15 +27,10 @@ test - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.validation - validation-api - ${validation-api.version} - org.openapitools openapi-generator @@ -97,8 +92,7 @@ 3.0.0 2.17.1 1.7.0 - 6.0.10.Final - 2.0.1.Final + 8.0.1.Final 3.3.4 2.10.0.pr3 5.1.0 From 52197768be4b9d9bf325a46eee5de4fde180984a Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Thu, 9 Nov 2023 19:23:42 +0530 Subject: [PATCH 152/283] JAVA-27190 Remove code overriding parent-boot-version of hibernate-validator --- .../custom-validations-opeanpi-codegen/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index 573b132467..95d3239b96 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -26,11 +26,6 @@ spring-boot-starter-test test - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - org.openapitools openapi-generator @@ -92,7 +87,6 @@ 3.0.0 2.17.1 1.7.0 - 8.0.1.Final 3.3.4 2.10.0.pr3 5.1.0 From 499ed4bbbd64a3e778a908f1a218df18cb974479 Mon Sep 17 00:00:00 2001 From: Paul Greer Date: Thu, 9 Nov 2023 21:52:12 +0000 Subject: [PATCH 153/283] BAEL-6943: Difference between String and StringBuffer in Java (#14815) * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Delete core-java-modules/core-java-lang-6/src/main/java/com/baeldung/intposneg directory * Delete core-java-modules/core-java-lang-6/src/test/java/com/baeldung/intposneg directory * Add files via upload * Delete core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/stringtoint/intposneg directory * Add files via upload * Add files via upload * Delete core-java-modules/core-java-numbers-conversions/src/main/java/com/baeldung/intposneg directory * Delete core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/intposneg directory * Add files via upload * Add files via upload * Delete core-java-modules/core-java-lang-6/src/main/java/com/baeldung/diffstringstringbuffer directory * Delete core-java-modules/core-java-lang-6/src/test/java/com/baeldung/diffstringstringbuffer directory * Delete core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer directory * Delete core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer directory * Add files via upload * Add files via upload --- .../diffstringstringbuffer/MemoryAddress.java | 33 +++++++++++++++++++ .../StringBufferUnitTest.java | 18 ++++++++++ .../StringUnitTest.java | 29 ++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java create mode 100644 core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java create mode 100644 core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java diff --git a/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java new file mode 100644 index 0000000000..42a4d9d4b4 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/diffstringstringbuffer/MemoryAddress.java @@ -0,0 +1,33 @@ +package com.baeldung.diffstringstringbuffer; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +public class MemoryAddress { + public long getMemoryAddress(Object object) { + Object[] arrayOfObject = new Object[]{object}; + Unsafe unsafe = null; + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + unsafe = (Unsafe) field.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + assert unsafe != null; + long arrayBaseOffset = unsafe.arrayBaseOffset(Object[].class); + int addressSize = unsafe.addressSize(); + long objectAddress; + if (addressSize == 4) { + objectAddress = unsafe.getInt(arrayOfObject, arrayBaseOffset); + } else { + if (addressSize == 8) { + objectAddress = unsafe.getLong(arrayOfObject, arrayBaseOffset); + } else { + throw new Error("Error: Size not supported: " + addressSize); + } + } + return objectAddress; + } +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java new file mode 100644 index 0000000000..adbe69b65e --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringBufferUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.diffstringstringbuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class StringBufferUnitTest { + @Test + void whenStringBufferVariableIsReassigned_thenVariableRetainsOriginalMemoryAddress() { + MemoryAddress memoryAddress = new MemoryAddress(); + StringBuffer stringBuffer = new StringBuffer("DownTown"); + long address1 = memoryAddress.getMemoryAddress(stringBuffer); + stringBuffer.insert(0, "Coder"); + assertEquals(stringBuffer.toString(), "CoderDownTown"); + long address2 = memoryAddress.getMemoryAddress(stringBuffer); + assertEquals(address1, address2); + } +} diff --git a/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java new file mode 100644 index 0000000000..bf1fcfeaf1 --- /dev/null +++ b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/diffstringstringbuffer/StringUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.diffstringstringbuffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class StringUnitTest { + @Test + void whenStringVariableIsReassigned_thenVariableGetsNewMemoryAddress() { + MemoryAddress memoryAddress = new MemoryAddress(); + String s1 = "DownTown"; + long address1 = memoryAddress.getMemoryAddress(s1); + s1 = "Coder"; + long address2 = memoryAddress.getMemoryAddress(s1); + assertNotEquals(address1, address2); + } + + @Test + void whenStringsAreIncludedInAStringBuffer_thenThoseStringsRemainImmutable() { + String s1 = "TopCat"; + StringBuffer stringBuffer = new StringBuffer("DownTown"); + stringBuffer.append(s1); + stringBuffer.reverse(); + assertNotEquals(s1, "taCpoT"); + stringBuffer.delete(0, 3); + assertEquals(s1, "TopCat"); + } +} From 0b0db24ebb0e028008722d698716e9d0a17452b8 Mon Sep 17 00:00:00 2001 From: psevestre Date: Thu, 9 Nov 2023 18:56:11 -0300 Subject: [PATCH 154/283] [BAEL-7044] Shared Memory Between Two JVMs (#15162) * [BAEL-4849] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Article code * [BAEL-4968] Remove extra comments * [BAEL-5258] Article Code * [BAEL-2765] PKCE Support for Secret Clients * [BAEL-5698] Article code * [BAEL-5698] Article code * [BAEL-5905] Initial code * [BAEL-5905] Article code * [BAEL-5905] Relocate article code to new module * [BAEL-6275] PostgreSQL NOTIFY/LISTEN * [BAEL-6275] Minor correction * BAEL-6138 * [BAEL-6138] WIP - LiveTest * [BAEL-6138] Tutorial Code * [BAEL-6138] Tutorial Code * [BAEL-6694] Article Code * [BAEL-7044] Tutorial code --------- Co-authored-by: Philippe Sevestre --- .../core-java-sun/shared-mem-test1.bat | 8 ++ .../core-java-sun/shared-mem-test2.bat | 10 ++ .../com/baeldung/sharedmem/ConsumerApp.java | 94 ++++++++++++++ .../sharedmem/ConsumerAppWithSpinLock.java | 119 ++++++++++++++++++ .../com/baeldung/sharedmem/ProducerApp.java | 89 +++++++++++++ .../sharedmem/ProducerAppWithSpinLock.java | 117 +++++++++++++++++ .../java/com/baeldung/sharedmem/SpinLock.java | 43 +++++++ 7 files changed, 480 insertions(+) create mode 100644 core-java-modules/core-java-sun/shared-mem-test1.bat create mode 100644 core-java-modules/core-java-sun/shared-mem-test2.bat create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java create mode 100644 core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java diff --git a/core-java-modules/core-java-sun/shared-mem-test1.bat b/core-java-modules/core-java-sun/shared-mem-test1.bat new file mode 100644 index 0000000000..148c51eb36 --- /dev/null +++ b/core-java-modules/core-java-sun/shared-mem-test1.bat @@ -0,0 +1,8 @@ +@rem This bat file starts the consumer and producer (more or less) at the same time +cd target\classes +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ProducerApp c:\lixo\sharedmem.bin 65536 +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ConsumerApp c:\lixo\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ProducerApp c:\lixo\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ConsumerApp c:\lixo\sharedmem.bin 65536 +cd .. +cd .. diff --git a/core-java-modules/core-java-sun/shared-mem-test2.bat b/core-java-modules/core-java-sun/shared-mem-test2.bat new file mode 100644 index 0000000000..7a7f8f7caa --- /dev/null +++ b/core-java-modules/core-java-sun/shared-mem-test2.bat @@ -0,0 +1,10 @@ +@rem This bat file starts the consumer and producer (more or less) at the same time +del target\sharedmem.bin +echo "" > target\sharedmem.bin +cd target\classes +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ProducerAppWithSpinLock ..\sharedmem.bin 65536 +rem start java --add-opens java.base/java.nio=ALL-UNNAMED com.baeldung.sharedmem.ConsumerAppWithSpinLock ..\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ProducerAppWithSpinLock ..\sharedmem.bin 65536 +start %JAVA_HOME%\bin\java com.baeldung.sharedmem.ConsumerAppWithSpinLock ..\sharedmem.bin 65536 +cd .. +cd .. diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java new file mode 100644 index 0000000000..1fbc02bee9 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerApp.java @@ -0,0 +1,94 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Random; + +public class ConsumerApp { + + public static void main(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + System.out.println("Starting consumer iterations..."); + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + + long matchCount = 0; + long mismatchCount = 0; + byte[] expectedHash = new byte[hashLen]; + + while (System.currentTimeMillis() - start < 30_000) { + + for (int i = 0; i < capacity - hashLen; i++) { + byte value = shm.get(i); + digest.update(value); + } + + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.get(expectedHash); + + if (Arrays.equals(hash, expectedHash)) { + matchCount++; + } else { + mismatchCount++; + } + + iterations++; + } + + System.out.printf("%d iterations run. matches=%d, mismatches=%d\n", iterations, matchCount, mismatchCount); + System.out.println("Press to exit"); + System.console() + .readLine(); + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel) Files.newByteChannel( + new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if (addr == null) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java new file mode 100644 index 0000000000..fa91edda40 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ConsumerAppWithSpinLock.java @@ -0,0 +1,119 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Random; + +public class ConsumerAppWithSpinLock { + + public static void main(String[] args) { + try { + // Small wait to ensure the Producer gets the first round. Otherwise the hash will be invalid + Thread.sleep(1000); + run(args); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + System.console() + .printf("Press to continue"); + System.console() + .readLine(); + } + } + + private static void run(String args[]) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + long addr = getBufferAddress(shm); + + System.out.printf("Buffer address: 0x%08x\n", addr); + + Random rnd = new Random(); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + System.out.println("Starting consumer iterations..."); + + long matchCount = 0; + long mismatchCount = 0; + byte[] expectedHash = new byte[hashLen]; + SpinLock lock = new SpinLock(addr); + + while (System.currentTimeMillis() - start < 30_000) { + + if (!lock.tryLock(5_000)) { + throw new RuntimeException("Unable to acquire lock"); + } + + try { + for (int i = 4; i < capacity - hashLen; i++) { + byte value = shm.get(i); + digest.update(value); + } + + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.get(expectedHash); + + if (Arrays.equals(hash, expectedHash)) { + matchCount++; + } else { + mismatchCount++; + } + + iterations++; + } finally { + lock.unlock(); + } + } + + System.out.printf("%d iteractions run. matches=%d, mismatches=%d\n", iterations, matchCount, mismatchCount); + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel) Files.newByteChannel( + new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if (addr == null) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java new file mode 100644 index 0000000000..ab7ca4d859 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerApp.java @@ -0,0 +1,89 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.EnumSet; +import java.util.Random; + +public class ProducerApp { + + + public static void main(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + + System.out.println("Starting producer iterations..."); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + Random rnd = new Random(); + + while(System.currentTimeMillis() - start < 30000) { + + for (int i = 0; i < capacity - hashLen; i++) { + byte value = (byte) (rnd.nextInt(256) & 0x00ff); + digest.update(value); + shm.put(i, value); + } + + // Write hash at the end + byte[] hash = digest.digest(); + shm.position(capacity - hashLen); + shm.put(hash); + iterations++; + } + + System.out.printf("%d iterations run\n", iterations); + System.out.println("Press to exit"); + System.console().readLine(); + + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if ( addr == null ) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } + catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel)Files.newByteChannel(new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + } + catch( IOException ioe) { + throw new RuntimeException(ioe); + } + } + +} diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java new file mode 100644 index 0000000000..619955eb2d --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/ProducerAppWithSpinLock.java @@ -0,0 +1,117 @@ +package com.baeldung.sharedmem; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.security.MessageDigest; +import java.util.EnumSet; +import java.util.Random; + +public class ProducerAppWithSpinLock { + + public static void main(String[] args) { + try { + run(args); + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + System.console() + .printf("Press to continue"); + System.console() + .readLine(); + } + } + + + public static void run(String[] args) throws Exception { + + MessageDigest digest = MessageDigest.getInstance("SHA1"); + digest.digest(new byte[256]); + byte[] dummy = digest.digest(); + int hashLen = dummy.length; + + + long size = Long.parseLong(args[1]); + MappedByteBuffer shm = createSharedMemory(args[0], size + hashLen); + + // Cleanup lock area + shm.putInt(0,0); + + long addr = getBufferAddress(shm); + System.out.printf("Buffer address: 0x%08x\n",addr); + Random rnd = new Random(); + + long start = System.currentTimeMillis(); + long iterations = 0; + int capacity = shm.capacity(); + System.out.println("Starting producer iterations..."); + SpinLock lock = new SpinLock(addr); + while(System.currentTimeMillis() - start < 30000) { + + if(!lock.tryLock(5000)) { + throw new RuntimeException("Unable to acquire lock"); + } + + try { + // Skip the first 4 bytes, as they're used by the lock + for (int i = 4; i < capacity - hashLen; i++) { + byte value = (byte) (rnd.nextInt(256) & 0x00ff); + digest.update(value); + shm.put(i, value); + } + + // Write hash at the end + byte[] hash = digest.digest(); + shm.position(capacity-hashLen); + shm.put(hash); + iterations++; + } + finally { + lock.unlock(); + } + } + + System.out.printf("%d iterations run\n", iterations); + + } + + private static long getBufferAddress(MappedByteBuffer shm) { + try { + Class cls = shm.getClass(); + Method maddr = cls.getMethod("address"); + maddr.setAccessible(true); + Long addr = (Long) maddr.invoke(shm); + if ( addr == null ) { + throw new RuntimeException("Unable to retrieve buffer's address"); + } + return addr; + } + catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private static MappedByteBuffer createSharedMemory(String path, long size) { + + try (FileChannel fc = (FileChannel)Files.newByteChannel(new File(path).toPath(), + EnumSet.of( + StandardOpenOption.CREATE, + StandardOpenOption.SPARSE, + StandardOpenOption.WRITE, + StandardOpenOption.READ))) { + + return fc.map(FileChannel.MapMode.READ_WRITE, 0, size); + + } + catch( IOException ioe) { + throw new RuntimeException(ioe); + } + + } + +} diff --git a/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java new file mode 100644 index 0000000000..145ac1e121 --- /dev/null +++ b/core-java-modules/core-java-sun/src/main/java/com/baeldung/sharedmem/SpinLock.java @@ -0,0 +1,43 @@ +package com.baeldung.sharedmem; + +//import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +public class SpinLock { + private static final Unsafe unsafe; + + static { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe) f.get(null); + } + catch(NoSuchFieldException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private final long addr; + + public SpinLock(long addr) { + this.addr = addr; + } + + public boolean tryLock(long maxWait) { + long deadline = System.currentTimeMillis() + maxWait; + while(System.currentTimeMillis() < deadline ) { + if ( unsafe.compareAndSwapInt(null,addr,0,1)) { + return true; + } + } + return false; + } + + public void unlock() { + unsafe.putInt(addr,0); + } + +} From 63679af8caa320ea547baa97a1d0c1e94fe69773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan=20Cardo=C5=9F?= <106325528+sodrac@users.noreply.github.com> Date: Fri, 10 Nov 2023 00:01:10 +0200 Subject: [PATCH 155/283] BAEL-6874 update test code for article (#15164) * BAEL-6819 convert from int to Long in Java * BAEL-6819 update package name * BAEL-6874 test code for article * BAEL-6874 rename test class * BAEL-6874 update test code for article * BAEL-6874 update test code for article --- .../GenericNumbersComparatorUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java index 0fcc0f3453..0b0295c2db 100644 --- a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/genericnumberscomparator/GenericNumbersComparatorUnitTest.java @@ -78,7 +78,7 @@ class GenericNumbersComparatorUnitTest { assertEquals(true, isEqual.test(5, 5.0)); } - private boolean someCondition = true; + private boolean someCondition; Function dynamicFunction = someCondition ? Number::doubleValue : Number::intValue; Comparator dynamicComparator = (num1, num2) -> ((Comparable) dynamicFunction.apply(num1)).compareTo(dynamicFunction.apply(num2)); From 1f609d3aafe8149885b06db927912d10e01a0362 Mon Sep 17 00:00:00 2001 From: Dmytro Budym <46810751+dbudim@users.noreply.github.com> Date: Fri, 10 Nov 2023 04:08:28 +0100 Subject: [PATCH 156/283] =?UTF-8?q?Code=20examples=20for=20article:=20Swit?= =?UTF-8?q?ching=20Between=20Frames=20Using=20Selenium=20We=E2=80=A6=20(#1?= =?UTF-8?q?4973)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Code examples for article: Switching Between Frames Using Selenium WebDriver in Java * continuation indent 2 * moved to selenium-2 package --- .../selenium/iframe/IframeManualTest.java | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java diff --git a/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java b/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java new file mode 100644 index 0000000000..bc617a4777 --- /dev/null +++ b/testing-modules/selenium-2/src/test/java/com/baeldung/selenium/iframe/IframeManualTest.java @@ -0,0 +1,120 @@ +package com.baeldung.selenium.iframe; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.time.Duration; + + +public class IframeManualTest { + + private WebDriver driver; + private static final int TIMEOUT = 10; + + @BeforeMethod + public void init() { + WebDriverManager.chromedriver().setup(); + driver = new ChromeDriver(); + } + + @Test + public void whenSwitchToFrameUsingWebElement_thenSwitched() { + openDemoPage(); + WebElement iframeElement = driver.findElement(By.cssSelector("#myFrame2")); + + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(iframeElement)); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToFrameUsingName_thenSwitched() { + openDemoPage(); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frameName2")); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToFrameUsingId_thenSwitched() { + openDemoPage(); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("myFrame2")); + waitForTextInFrame(); + } + + @Test + public void whenSwitchToInnerFrameFromOuter_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + waitForLinkInNestedFrame(); + } + + @Test + public void whenSwitchToParentFrame_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + driver.switchTo().parentFrame(); + waitForTextInParentFrame(); + } + + @Test + public void whenSwitchToDefaultContent_thenSwitched() { + openPageWithNestedFrames(); + switchToNestedFrame(); + driver.switchTo().defaultContent(); + waitForElementInDefaultContent(); + } + + @AfterMethod + public void tearDown() { + driver.quit(); + } + + + private void openDemoPage() { + driver.get("https://seleniumbase.io/demo_page"); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#myForm"))); + } + + private void openPageWithNestedFrames() { + driver.get("https://seleniumbase.io/w3schools/iframes"); + new WebDriverWait(driver, Duration.ofSeconds(10)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#runbtn"))); + } + + private void switchToNestedFrame() { + driver.switchTo().frame("iframeResult"); + WebElement innerFrame = driver.findElement(By.cssSelector("[src='./demo_iframe.htm']")); + driver.switchTo().frame(innerFrame); + } + + private void waitForTextInFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector("h4"), "iFrame Text")); + } + + private void waitForLinkInNestedFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("[href='https://seleniumbase.io/w3schools/iframes.html']"))); + } + + private void waitForTextInParentFrame() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.textToBePresentInElementLocated(By.cssSelector("h2"), "HTML Iframes (nested iframes)")); + } + + private void waitForElementInDefaultContent() { + new WebDriverWait(driver, Duration.ofSeconds(TIMEOUT)) + .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#runbtn"))); + } +} From 0ce0a647a112de2828e049762affbede65132b85 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Fri, 10 Nov 2023 04:10:03 -0300 Subject: [PATCH 157/283] MongoDbHashMapIntegrationTest - Changing to LiveTest (#15013) * changing to LiveTest Prevent integration tests from failing after spring boot upgrade. * Update MongoDbHashMapLiveTest.java Including docs. * Update MongoDbHashMapLiveTest.java removing instructions from atlas search. --- ...nTest.java => MongoDbHashMapLiveTest.java} | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) rename persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/{MongoDbHashMapIntegrationTest.java => MongoDbHashMapLiveTest.java} (76%) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java similarity index 76% rename from persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java rename to persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java index bbf425f277..29588df8a9 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/test/java/com/baeldung/boot/hashmap/MongoDbHashMapLiveTest.java @@ -13,21 +13,35 @@ import java.util.Map; import java.util.Set; import org.bson.Document; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; import com.mongodb.BasicDBObject; -@SpringBootTest +/** + * Steps to run locally: + * - Open embedded.properties and include: + * - spring.data.mongodb.uri= + * - spring.data.mongodb.database=sample_mflix + * + * Pre-requisites: + * - Following the steps to import the sample_mflix database + */ @DirtiesContext +@RunWith(SpringRunner.class) @TestPropertySource("/embedded.properties") -class MongoDbHashMapIntegrationTest { +@SpringBootTest(classes = SpringBootHashMapApplication.class) +class MongoDbHashMapLiveTest { + private static final String COLLECTION_NAME = "hashmap-test-collection"; private static final Map MAP = new HashMap<>(); private static final Set> MAP_SET = new HashSet<>(); @@ -52,17 +66,22 @@ class MongoDbHashMapIntegrationTest { MAP_SET.add(MAP); MAP_SET.add(otherMap); } + + @AfterEach + void destroy() { + mongo.dropCollection(COLLECTION_NAME); + } @Test void whenUsingMap_thenInsertSucceeds() { - Map saved = mongo.insert(MAP, "map-collection"); + Map saved = mongo.insert(MAP, COLLECTION_NAME); assertHasMongoId(saved); } @Test void whenMapSet_thenInsertSucceeds() { - Collection> saved = mongo.insert(MAP_SET, "map-set"); + Collection> saved = mongo.insert(MAP_SET, COLLECTION_NAME); saved.forEach(this::assertHasMongoId); assertEquals(2, saved.size()); @@ -72,7 +91,7 @@ class MongoDbHashMapIntegrationTest { void givenMap_whenDocumentConstructed_thenInsertSucceeds() { Document document = new Document(MAP); - Document saved = mongo.insert(document, "doc-collection"); + Document saved = mongo.insert(document, COLLECTION_NAME); assertHasMongoId(saved); } @@ -81,7 +100,7 @@ class MongoDbHashMapIntegrationTest { void givenMap_whenBasicDbObjectConstructed_thenInsertSucceeds() { BasicDBObject dbObject = new BasicDBObject(MAP); - BasicDBObject saved = mongo.insert(dbObject, "db-collection"); + BasicDBObject saved = mongo.insert(dbObject, COLLECTION_NAME); assertHasMongoId(saved); } @@ -114,7 +133,7 @@ class MongoDbHashMapIntegrationTest { set.add(document); }, Set::addAll); - Collection saved = mongo.insert(docs, "custom-set"); + Collection saved = mongo.insert(docs, COLLECTION_NAME); saved.forEach(this::assertHasMongoId); } } From ac0fa6ff7883a610297aa7eb5561536a5e0e079f Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 18:46:51 +0800 Subject: [PATCH 158/283] Update README.md [skip ci] --- core-java-modules/core-java-date-operations-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 9d16d1f71c..48b68189fa 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -11,4 +11,5 @@ This module contains articles about date operations in Java. - [Getting Yesterday’s Date in Java](https://www.baeldung.com/java-find-yesterdays-date) - [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end) - [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch) +- [Get First Date of Current Month in Java](https://www.baeldung.com/java-current-month-start-date) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) From 732c2255b294a38182581f016c31d524fa43f8eb Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:22:40 +0800 Subject: [PATCH 159/283] Update README.md [skip ci] --- spring-boot-modules/spring-boot-mvc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-mvc/README.md b/spring-boot-modules/spring-boot-mvc/README.md index f45feb6169..9257d6eba1 100644 --- a/spring-boot-modules/spring-boot-mvc/README.md +++ b/spring-boot-modules/spring-boot-mvc/README.md @@ -10,4 +10,5 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Using Spring ResponseEntity to Manipulate the HTTP Response](https://www.baeldung.com/spring-response-entity) - [The @ServletComponentScan Annotation in Spring Boot](https://www.baeldung.com/spring-servletcomponentscan) - [Guide to Internationalization in Spring Boot](https://www.baeldung.com/spring-boot-internationalization) +- [Localized Validation Messages in REST](https://www.baeldung.com/rest-localized-validation-messages) - More articles: [[next -->]](/spring-boot-modules/spring-boot-mvc-2) From 77c7186351207bedb51336cce9d47cb06a93c693 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:27:58 +0800 Subject: [PATCH 160/283] Update README.md [skip ci] --- spring-boot-modules/spring-boot-3-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-3-2/README.md b/spring-boot-modules/spring-boot-3-2/README.md index c176de2310..27f9281725 100644 --- a/spring-boot-modules/spring-boot-3-2/README.md +++ b/spring-boot-modules/spring-boot-3-2/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Spring Boot 3.1’s ConnectionDetails Abstraction](https://www.baeldung.com/spring-boot-3-1-connectiondetails-abstraction) +- [@ConditionalOnThreading Annotation Spring](https://www.baeldung.com/spring-conditionalonthreading) From a2ad229e4e901972a6b8d7ca0b94b9f1837c4b3c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 19:37:26 +0800 Subject: [PATCH 161/283] Update README.md [skip ci] --- core-java-modules/core-java-collections-maps-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 5599187cd8..84cc94ad3c 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) - [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) +- [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair) From 9109481ecbcfcb4afc6b970debb02d3d2b5dbc9f Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:51:11 +0000 Subject: [PATCH 162/283] =?UTF-8?q?[JAVA-26045]=20Upgraded=20spring-boot-t?= =?UTF-8?q?esting=20module=20to=20spring-boot=203=20ver=E2=80=A6=20(#14990?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-boot-modules/spring-boot-testing/pom.xml | 13 +++++++++---- .../boot/configurationproperties/MailServer.java | 10 +++++----- .../configuration/RedisProperties.java | 2 +- .../java/com/baeldung/boot/testing/Employee.java | 12 ++++++------ .../src/main/resources/application.properties | 4 ++-- .../exclude/ExcludeAutoConfig1IntegrationTest.java | 2 +- .../exclude/ExcludeAutoConfig2IntegrationTest.java | 2 +- .../exclude/ExcludeAutoConfig3IntegrationTest.java | 2 +- .../exclude/ExcludeAutoConfig4IntegrationTest.java | 2 +- .../boot/autoconfig/AutoConfigIntegrationTest.java | 2 +- .../PropertyValidationUnitTest.java | 4 ++-- .../boot/embeddedRedis/TestRedisConfiguration.java | 4 ++-- .../src/test/resources/application.properties | 4 ++-- 13 files changed, 34 insertions(+), 29 deletions(-) diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 257260fc3f..23277d11f3 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -9,9 +9,10 @@ This is simple boot application for demonstrating testing features. - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -67,6 +68,11 @@ ${embedded-redis.version} test + + io.rest-assured + rest-assured + test + @@ -122,7 +128,6 @@ 2.4-M1-groovy-4.0 3.0.0 0.7.2 - 2.5.0 2.17.1 diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java index e23b30759b..3f5ea64d24 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java @@ -2,11 +2,11 @@ package com.baeldung.boot.configurationproperties; import java.util.Map; -import javax.validation.Valid; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java index 76f2e1bbfe..4e06548d79 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/embeddedRedis/configuration/RedisProperties.java @@ -8,7 +8,7 @@ public class RedisProperties { private final int redisPort; private final String redisHost; - public RedisProperties(@Value("${spring.redis.port}") final int redisPort, @Value("${spring.redis.host}") final String redisHost) { + public RedisProperties(@Value("${spring.data.redis.port}") final int redisPort, @Value("${spring.data.redis.host}") final String redisHost) { this.redisPort = redisPort; this.redisHost = redisHost; } diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java index 2921ecc609..cf68c45793 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java +++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/testing/Employee.java @@ -1,11 +1,11 @@ package com.baeldung.boot.testing; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.validation.constraints.Size; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; import java.util.Date; @Entity diff --git a/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties index 70cae370a4..e3fe989efd 100644 --- a/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing/src/main/resources/application.properties @@ -1,6 +1,6 @@ # embedded redis -spring.redis.host= localhost -spring.redis.port= 6379 +spring.data.redis.host= localhost +spring.data.redis.port= 6379 # security spring.security.user.name=john diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java index 2ca0c74901..a8a322df44 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig1IntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java index c0bd6570a1..6a9e157827 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig2IntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java index 1642d4b932..9d4d9759d6 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig3IntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java index 1aa453348b..f28929fbef 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/autoconfig/exclude/ExcludeAutoConfig4IntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java index 44a02c0c80..447d174fb5 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/autoconfig/AutoConfigIntegrationTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.test.context.junit4.SpringRunner; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java index 939471dd67..5e70bcb45f 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java @@ -2,8 +2,8 @@ package com.baeldung.boot.configurationproperties; import static org.junit.jupiter.api.Assertions.assertEquals; -import javax.validation.Validation; -import javax.validation.Validator; +import jakarta.validation.Validation; +import jakarta.validation.Validator; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java index c265d99c9b..10e5d56857 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java +++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/embeddedRedis/TestRedisConfiguration.java @@ -4,8 +4,8 @@ import com.baeldung.boot.embeddedRedis.configuration.RedisProperties; import org.springframework.boot.test.context.TestConfiguration; import redis.embedded.RedisServer; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; @TestConfiguration public class TestRedisConfiguration { diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties index 1810c7b1eb..bc31991329 100644 --- a/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing/src/test/resources/application.properties @@ -1,6 +1,6 @@ #embedded redis -spring.redis.host= localhost -spring.redis.port= 6370 +spring.data.redis.host= localhost +spring.data.redis.port= 6370 # security spring.security.user.name=john spring.security.user.password=123 From 277001771c776c3f5c97d421339edf127ae4383e Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:06:56 +0800 Subject: [PATCH 163/283] Update README.md [skip ci] --- core-java-modules/core-java-jndi/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-jndi/README.md b/core-java-modules/core-java-jndi/README.md index 9c6f489841..cdb1b34ca9 100644 --- a/core-java-modules/core-java-jndi/README.md +++ b/core-java-modules/core-java-jndi/README.md @@ -4,3 +4,4 @@ - [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi) - [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth) - [Testing LDAP Connections With Java](https://www.baeldung.com/java-test-ldap-connections) +- [JNDI – What Is java:comp/env?](https://www.baeldung.com/java-jndi-comp-env) From c7883a6d5cd680bcc39cb23cfc924bb23a7ad03e Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:10:20 +0800 Subject: [PATCH 164/283] Update README.md [skip ci] --- core-java-modules/core-java-documentation/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-documentation/README.md b/core-java-modules/core-java-documentation/README.md index 972e76c165..9fa48dc09e 100644 --- a/core-java-modules/core-java-documentation/README.md +++ b/core-java-modules/core-java-documentation/README.md @@ -4,3 +4,4 @@ - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [Code Snippets in Java API Documentation](https://www.baeldung.com/java-doc-code-snippets) +- [How to Document Generic Type Parameters in Javadoc](https://www.baeldung.com/java-javadoc-generic-type-parameters) From 2e330d6f34016e25e451e97df3cc190a6c52e565 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:12:41 +0800 Subject: [PATCH 165/283] Update README.md [skip ci] --- core-java-modules/core-java-records/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-records/README.md b/core-java-modules/core-java-records/README.md index 86d3579c76..7b4df6f15c 100644 --- a/core-java-modules/core-java-records/README.md +++ b/core-java-modules/core-java-records/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Overriding hashCode() And equals() For Records](https://www.baeldung.com/java-override-hashcode-equals-records) +- [Optional as a Record Parameter in Java](https://www.baeldung.com/java-record-optional-param) From 4c87707c9057af9dc58a4443065a245c743c44e6 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Fri, 10 Nov 2023 21:16:16 +0800 Subject: [PATCH 166/283] Update README.md [skip ci] --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 6c4fab384b..28e2dccd39 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) +- [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) From 47c755435251a26f72cdf64ed8d04b5c84aa3954 Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 10 Nov 2023 14:30:22 +0100 Subject: [PATCH 167/283] feat: override spring bean --- .../com/baeldung/overridebean/Endpoint.java | 19 ++++++++++ .../com/baeldung/overridebean/Service.java | 5 +++ .../baeldung/overridebean/ServiceImpl.java | 8 ++++ .../overridebean/basic/Application.java | 14 +++++++ .../baeldung/overridebean/basic/Config.java | 16 ++++++++ .../overridebean/conditional/Application.java | 14 +++++++ .../conditional/ConditionalConfig.java | 18 +++++++++ .../overridebean/profile/Application.java | 14 +++++++ .../overridebean/profile/ProfileConfig.java | 18 +++++++++ .../src/main/resources/application.properties | 1 + .../conditional/ConditionIntegrationTest.java | 29 +++++++++++++++ .../conditional/ConditionalStub.java | 10 +++++ .../conditional/ConditionalTestConfig.java | 17 +++++++++ .../mockbean/MockBeanIntegrationTest.java | 37 +++++++++++++++++++ ...OverrideBeanDefinitionIntegrationTest.java | 31 ++++++++++++++++ .../OverrideBeanDefinitionServiceStub.java | 10 +++++ .../OverrideBeanDefinitionTestConfig.java | 15 ++++++++ .../primary/PrimaryIntegrationTest.java | 31 ++++++++++++++++ .../primary/PrimaryServiceStub.java | 10 +++++ .../primary/PrimaryTestConfig.java | 17 +++++++++ .../profile/ProfileIntegrationTest.java | 29 +++++++++++++++ .../profile/ProfileServiceStub.java | 10 +++++ .../profile/ProfileTestConfig.java | 15 ++++++++ 23 files changed, 388 insertions(+) create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java new file mode 100644 index 0000000000..e199d1f25b --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java @@ -0,0 +1,19 @@ +package com.baeldung.overridebean; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class Endpoint { + + private final Service service; + + public Endpoint(Service service) { + this.service = service; + } + + @GetMapping("/hello") + public String helloWorldEndpoint() { + return service.helloWorld(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java new file mode 100644 index 0000000000..0872fcc372 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java @@ -0,0 +1,5 @@ +package com.baeldung.overridebean; + +public interface Service { + String helloWorld(); +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java new file mode 100644 index 0000000000..4d4b5582e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java @@ -0,0 +1,8 @@ +package com.baeldung.overridebean; + +public class ServiceImpl implements Service { + + public String helloWorld() { + return "hello world"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java new file mode 100644 index 0000000000..6f9acde3d8 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.basic; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java new file mode 100644 index 0000000000..67d999958d --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java @@ -0,0 +1,16 @@ +package com.baeldung.overridebean.basic; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +public class Config { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java new file mode 100644 index 0000000000..9c4cdbf8ec --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java new file mode 100644 index 0000000000..e18689e042 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +public class ConditionalConfig { + + @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "false") + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java new file mode 100644 index 0000000000..d3298b2eb4 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java new file mode 100644 index 0000000000..64cdfff8a5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +@Profile("prod") +public class ProfileConfig { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties index b628a708bd..0982b7bac0 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties @@ -1,2 +1,3 @@ keycloak.enabled=true spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8180/auth/realms/baeldung-api +service.stub=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java new file mode 100644 index 0000000000..5f6b1d128f --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.overridebean.conditional; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; + +@SpringBootTest(classes = { Application.class, ConditionalConfig.class, Endpoint.class, ConditionalTestConfig.class }, properties = "service.stub=true") +@AutoConfigureMockMvc +class ConditionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConditionalConfig_whenServiceStubIsTrue_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello conditional stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java new file mode 100644 index 0000000000..6b3e447108 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.conditional; + +import com.baeldung.overridebean.Service; + +public class ConditionalStub implements Service { + + public String helloWorld() { + return "hello conditional stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java new file mode 100644 index 0000000000..c48c4e2266 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ConditionalTestConfig { + + @ConditionalOnProperty(name = "service.stub", havingValue = "true") + @Bean + public Service helloWorld() { + return new ConditionalStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java new file mode 100644 index 0000000000..6a7be1cbda --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -0,0 +1,37 @@ +package com.baeldung.overridebean.mockbean; + +import static org.hamcrest.Matchers.containsString; +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.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.basic.Application; + +@SpringBootTest(classes = { Application.class, Endpoint.class }) +@AutoConfigureMockMvc +class MockBeanIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private Service serviceExample; + + @Test + void givenServiceMockBean_whenGetHelloEndpoint_thenMockOk() throws Exception { + when(serviceExample.helloWorld()).thenReturn("hello mock bean"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello mock bean"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java new file mode 100644 index 0000000000..0f3753ef34 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.basic.Config; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, OverrideBeanDefinitionTestConfig.class }, properties = "spring.main.allow-bean-definition-overriding=true") +@AutoConfigureMockMvc +class OverrideBeanDefinitionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenNoProfile_whenAllowBeanDefinitionOverriding_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello no profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java new file mode 100644 index 0000000000..d06b43cf24 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import com.baeldung.overridebean.Service; + +public class OverrideBeanDefinitionServiceStub implements Service { + + public String helloWorld() { + return "hello no profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java new file mode 100644 index 0000000000..5c35304296 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class OverrideBeanDefinitionTestConfig { + + @Bean + public Service helloWorld() { + return new OverrideBeanDefinitionServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java new file mode 100644 index 0000000000..2bddfd4637 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.primary; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.basic.Config; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, PrimaryTestConfig.class }) +@AutoConfigureMockMvc +class PrimaryIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenTestConfiguration_whenPrimaryBeanIsDefined_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello primary stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java new file mode 100644 index 0000000000..1d3d887f99 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.primary; + +import com.baeldung.overridebean.Service; + +public class PrimaryServiceStub implements Service { + + public String helloWorld() { + return "hello primary stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java new file mode 100644 index 0000000000..3765377b41 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.primary; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class PrimaryTestConfig { + + @Primary + @Bean("service.stub") + public Service helloWorld() { + return new PrimaryServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java new file mode 100644 index 0000000000..deabfea9e5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +class ProfileIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConfigurationWithProfile_whenNoProductionProfileIsActive_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java new file mode 100644 index 0000000000..ef1f2e7a22 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.profile; + +import com.baeldung.overridebean.Service; + +public class ProfileServiceStub implements Service { + + public String helloWorld() { + return "hello profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java new file mode 100644 index 0000000000..edd33162e0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ProfileTestConfig { + + @Bean + public Service helloWorld() { + return new ProfileServiceStub(); + } +} From 1e13611b4de219f646c491eeb382e5a04bfac856 Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 10 Nov 2023 15:09:18 +0100 Subject: [PATCH 168/283] Trigger Jenkins From 7c1065b494a05299addb9f0ada8fdba786ac91e4 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Fri, 10 Nov 2023 14:15:28 +0000 Subject: [PATCH 169/283] [JAVA-26439] Moved code related to "Guide to Stream.reduce()" to ebook module (#15170) --- .../streamreduce/application/Application.java | 62 ------------------- .../streamreduce/entities/Rating.java | 39 ------------ .../streamreduce/entities/Review.java | 28 --------- .../baeldung/streamreduce/entities/User.java | 30 --------- .../streamreduce/utilities/NumberUtils.java | 52 ---------------- .../streams/reduce/entities/User.java | 7 ++- .../reduce}/StreamReduceManualTest.java | 15 +++-- 7 files changed, 15 insertions(+), 218 deletions(-) delete mode 100644 core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java delete mode 100644 core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java delete mode 100644 core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java delete mode 100644 core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java delete mode 100644 core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java rename core-java-modules/{core-java-8/src/test/java/com/baeldung/streamreduce/tests => core-java-streams-simple/src/test/java/com/baeldung/streams/reduce}/StreamReduceManualTest.java (95%) diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java deleted file mode 100644 index 00fc45ccae..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/application/Application.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.baeldung.streamreduce.application; - -import com.baeldung.streamreduce.entities.User; -import com.baeldung.streamreduce.utilities.NumberUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class Application { - - public static void main(String[] args) { - List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); - int result1 = numbers.stream().reduce(0, (a, b) -> a + b); - System.out.println(result1); - - int result2 = numbers.stream().reduce(0, Integer::sum); - System.out.println(result2); - - List letters = Arrays.asList("a", "b", "c", "d", "e"); - String result3 = letters.stream().reduce("", (a, b) -> a + b); - System.out.println(result3); - - String result4 = letters.stream().reduce("", String::concat); - System.out.println(result4); - - String result5 = letters.stream().reduce("", (a, b) -> a.toUpperCase() + b.toUpperCase()); - System.out.println(result5); - - List users = Arrays.asList(new User("John", 30), new User("Julie", 35)); - int result6 = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - System.out.println(result6); - - String result7 = letters.parallelStream().reduce("", String::concat); - System.out.println(result7); - - int result8 = users.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - System.out.println(result8); - - List userList = new ArrayList<>(); - for (int i = 0; i <= 1000000; i++) { - userList.add(new User("John" + i, i)); - } - - long t1 = System.currentTimeMillis(); - int result9 = userList.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - long t2 = System.currentTimeMillis(); - System.out.println(result9); - System.out.println("Sequential stream time: " + (t2 - t1) + "ms"); - - long t3 = System.currentTimeMillis(); - int result10 = userList.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); - long t4 = System.currentTimeMillis(); - System.out.println(result10); - System.out.println("Parallel stream time: " + (t4 - t3) + "ms"); - - int result11 = NumberUtils.divideListElements(numbers, 1); - System.out.println(result11); - - int result12 = NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 0); - System.out.println(result12); - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java deleted file mode 100644 index c4d0276256..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Rating.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.streamreduce.entities; - -import java.util.ArrayList; -import java.util.List; - -public class Rating { - - double points; - List reviews = new ArrayList<>(); - - public Rating() {} - - public void add(Review review) { - reviews.add(review); - computeRating(); - } - - private double computeRating() { - double totalPoints = reviews.stream().map(Review::getPoints).reduce(0, Integer::sum); - this.points = totalPoints / reviews.size(); - return this.points; - } - - public static Rating average(Rating r1, Rating r2) { - Rating combined = new Rating(); - combined.reviews = new ArrayList<>(r1.reviews); - combined.reviews.addAll(r2.reviews); - combined.computeRating(); - return combined; - } - - public double getPoints() { - return points; - } - - public List getReviews() { - return reviews; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java deleted file mode 100644 index 03cde8a9c8..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/Review.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.streamreduce.entities; - -public class Review { - - int points; - String review; - - public Review(int points, String review) { - this.points = points; - this.review = review; - } - - public int getPoints() { - return points; - } - - public void setPoints(int points) { - this.points = points; - } - - public String getReview() { - return review; - } - - public void setReview(String review) { - this.review = review; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java deleted file mode 100644 index 20c12d7920..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/entities/User.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.streamreduce.entities; - -public class User { - - private final String name; - private final int age; - private final Rating rating = new Rating(); - - public User(String name, int age) { - this.name = name; - this.age = age; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public Rating getRating() { - return rating; - } - - @Override - public String toString() { - return "User{" + "name=" + name + ", age=" + age + '}'; - } -} diff --git a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java b/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java deleted file mode 100644 index a2325cc701..0000000000 --- a/core-java-modules/core-java-8/src/main/java/com/baeldung/streamreduce/utilities/NumberUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.baeldung.streamreduce.utilities; - -import java.util.List; -import java.util.function.BiFunction; -import java.util.logging.Level; -import java.util.logging.Logger; - -public abstract class NumberUtils { - - private static final Logger LOGGER = Logger.getLogger(NumberUtils.class.getName()); - - public static int divideListElements(List values, Integer divider) { - return values.stream() - .reduce(0, (a, b) -> { - try { - return a / divider + b / divider; - } catch (ArithmeticException e) { - LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); - } - return 0; - }); - } - - public static int divideListElementsWithExtractedTryCatchBlock(List values, int divider) { - return values.stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider)); - } - - public static int divideListElementsWithApplyFunctionMethod(List values, int divider) { - BiFunction division = (a, b) -> a / b; - return values.stream().reduce(0, (a, b) -> applyFunction(division, a, divider) + applyFunction(division, b, divider)); - } - - private static int divide(int value, int factor) { - int result = 0; - try { - result = value / factor; - } catch (ArithmeticException e) { - LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); - } - return result; - } - - private static int applyFunction(BiFunction function, int a, int b) { - try { - return function.apply(a, b); - } - catch(Exception e) { - LOGGER.log(Level.INFO, "Exception occurred!"); - } - return 0; - } -} diff --git a/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java b/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java index 610bd93b22..07c627005a 100644 --- a/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java +++ b/core-java-modules/core-java-streams-simple/src/main/java/com/baeldung/streams/reduce/entities/User.java @@ -4,6 +4,7 @@ public class User { private final String name; private final int age; + private final Rating rating = new Rating(); public User(String name, int age) { this.name = name; @@ -17,7 +18,11 @@ public class User { public int getAge() { return age; } - + + public Rating getRating() { + return rating; + } + @Override public String toString() { return "User{" + "name=" + name + ", age=" + age + '}'; diff --git a/core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java similarity index 95% rename from core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java rename to core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java index 602bdd069e..2931384c94 100644 --- a/core-java-modules/core-java-8/src/test/java/com/baeldung/streamreduce/tests/StreamReduceManualTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/reduce/StreamReduceManualTest.java @@ -1,15 +1,18 @@ -package com.baeldung.streamreduce.tests; +package com.baeldung.streams.reduce; + +import static org.assertj.core.api.Assertions.assertThat; -import com.baeldung.streamreduce.entities.Rating; -import com.baeldung.streamreduce.entities.Review; -import com.baeldung.streamreduce.entities.User; -import com.baeldung.streamreduce.utilities.NumberUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; + import org.junit.Test; +import com.baeldung.streams.reduce.entities.Rating; +import com.baeldung.streams.reduce.entities.Review; +import com.baeldung.streams.reduce.entities.User; +import com.baeldung.streams.reduce.utilities.NumberUtils; + public class StreamReduceManualTest { @Test From cd9ab90fc857627079b9f57c7fc894fdd63f8669 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Fri, 10 Nov 2023 20:51:43 +0530 Subject: [PATCH 170/283] BAEL-7091 Moved to new module --- testing-modules/hamcrest/pom.xml | 12 ------------ testing-modules/testing-assertions/pom.xml | 12 ++++++++++++ .../assertnestedmap/AssertNestedMapUnitTest.java | 4 ++-- .../assertnestedmap/matchers/NestedMapMatcher.java | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) rename testing-modules/{hamcrest/src/test/java/com/baeldung/hamcrest => testing-assertions/src/test/java/com/baeldung}/assertnestedmap/AssertNestedMapUnitTest.java (95%) rename testing-modules/{hamcrest/src/test/java/com/baeldung/hamcrest => testing-assertions/src/test/java/com/baeldung}/assertnestedmap/matchers/NestedMapMatcher.java (94%) diff --git a/testing-modules/hamcrest/pom.xml b/testing-modules/hamcrest/pom.xml index b5a8277deb..df8c543edb 100644 --- a/testing-modules/hamcrest/pom.xml +++ b/testing-modules/hamcrest/pom.xml @@ -6,18 +6,6 @@ hamcrest 0.0.1-SNAPSHOT hamcrest - - - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - - - jar diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 1da53bd77e..1f2b4e335d 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -4,6 +4,18 @@ 4.0.0 testing-assertions 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + com.baeldung diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java similarity index 95% rename from testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java rename to testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index b5b4d652a0..7c48a5eb4a 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -1,11 +1,11 @@ -package com.baeldung.hamcrest.assertnestedmap; +package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; import java.util.Map; -import static com.baeldung.hamcrest.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; +import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java similarity index 94% rename from testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java rename to testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java index 760edebb35..961130bb20 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java @@ -1,4 +1,4 @@ -package com.baeldung.hamcrest.assertnestedmap.matchers; +package com.baeldung.assertnestedmap.matchers; import org.hamcrest.Description; From 75828dbf491f828d41ba87e40461e0f566f38d62 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 07:29:30 +0800 Subject: [PATCH 171/283] Update README.md [skip ci] --- core-java-modules/core-java-collections-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 1939e5ca3f..4869158d2b 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -8,4 +8,5 @@ - [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods) - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) +- [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) From 373a0cc89552d42db973e41bf75166643e360c0b Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 07:33:19 +0800 Subject: [PATCH 172/283] Update README.md [skip ci] --- reactor-core/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/reactor-core/README.md b/reactor-core/README.md index dccf1fa85c..96355ad703 100644 --- a/reactor-core/README.md +++ b/reactor-core/README.md @@ -13,3 +13,4 @@ This module contains articles about Reactor Core. - [Handling Exceptions in Project Reactor](https://www.baeldung.com/reactor-exceptions) - [Difference Between Flux.create and Flux.generate](https://www.baeldung.com/java-flux-create-generate) - [Difference Between Flux and Mono](https://www.baeldung.com/java-reactor-flux-vs-mono) +- [Working With MathFlux](https://www.baeldung.com/java-reactor-mathflux) From bb31624bb418edc1de9b99e67e25466d09a2b5f9 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 07:43:24 +0800 Subject: [PATCH 173/283] Update README.md [skip ci] --- core-java-modules/core-java-collections-maps-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 84cc94ad3c..2e1531050e 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -2,3 +2,4 @@ - [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) - [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) - [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair) +- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file) From 2c26effb6418f05b56dab0fc8c4a3d08714f2ea0 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 07:49:53 +0800 Subject: [PATCH 174/283] Update README.md [skip ci] --- core-java-modules/core-java-8-datetime-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index ac1e1ca81f..462a4be6f1 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -6,4 +6,5 @@ - [How Many Days Are There in a Particular Month of a Given Year?](https://www.baeldung.com/days-particular-month-given-year) - [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins) +- [Round the Date in Java](https://www.baeldung.com/java-round-the-date) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) From d6638d328fd53d2ea1caddf767adbe461bf89416 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 07:57:45 +0800 Subject: [PATCH 175/283] Update README.md [skip ci] --- jersey/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jersey/README.md b/jersey/README.md index aa5a6a3b28..24e39f02a2 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -12,3 +12,4 @@ This module contains articles about Jersey. - [Add a Header to a Jersey SSE Client Request](https://www.baeldung.com/jersey-sse-client-request-headers) - [Exception Handling With Jersey](https://www.baeldung.com/java-exception-handling-jersey) - [@FormDataParam vs. @FormParam in Jersey](https://www.baeldung.com/jersey-formdataparam-vs-formparam) +- [Add a List as Query Parameter in Jersey](https://www.baeldung.com/java-jersey-list-query-param) From 4e5f7adc81c748340b02d24f351b24fb15284b9f Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 08:10:55 +0800 Subject: [PATCH 176/283] Update README.md [skip ci] --- core-java-modules/core-java-string-apis-2/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-string-apis-2/README.md b/core-java-modules/core-java-string-apis-2/README.md index 38bfb70ef1..57106b7151 100644 --- a/core-java-modules/core-java-string-apis-2/README.md +++ b/core-java-modules/core-java-string-apis-2/README.md @@ -6,4 +6,5 @@ This module contains articles about string APIs. - [Retain Only Digits and Decimal Separator in String](https://www.baeldung.com/java-string-retain-digits-decimal) - [Difference Between null and Empty String in Java](https://www.baeldung.com/java-string-null-vs-empty) - [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) -- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) \ No newline at end of file +- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) +- [Compare StringBuilder Objects in Java](https://www.baeldung.com/java-stringbuilder-objects-comparison) From 3d8d1ad9044b88604fbb961290816ec675ce588d Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 08:16:39 +0800 Subject: [PATCH 177/283] Update README.md [skip ci] --- core-java-modules/core-java-streams-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 629d52f0a9..82a13a1eb6 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -5,3 +5,4 @@ - [Streams vs. Loops in Java](https://www.baeldung.com/java-streams-vs-loops) - [Partition a Stream in Java](https://www.baeldung.com/java-partition-stream) - [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams) +- [Modifying Objects Within Stream While Iterating](https://www.baeldung.com/java-stream-modify-objects-during-iteration) From c523d5b2019d1b7116c2182ff52da50c7825c486 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 08:21:22 +0800 Subject: [PATCH 178/283] Update README.md [skip ci] --- core-java-modules/core-java-streams-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 82a13a1eb6..64bc4e6b7a 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -6,3 +6,4 @@ - [Partition a Stream in Java](https://www.baeldung.com/java-partition-stream) - [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams) - [Modifying Objects Within Stream While Iterating](https://www.baeldung.com/java-stream-modify-objects-during-iteration) +- [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) From 12fa2a39612a2c840d6262190e6e29767775ed2a Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 08:27:08 +0800 Subject: [PATCH 179/283] Update README.md [skip ci] --- core-java-modules/core-java-date-operations-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 48b68189fa..d8c321deab 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -12,4 +12,5 @@ This module contains articles about date operations in Java. - [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end) - [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch) - [Get First Date of Current Month in Java](https://www.baeldung.com/java-current-month-start-date) +- [Time Conversions Using TimeUnit](https://www.baeldung.com/java-timeunit-conversion) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) From a6bed1817696343168204da250d308b200be4279 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 11 Nov 2023 08:31:26 +0800 Subject: [PATCH 180/283] Update README.md [skip ci] --- core-java-modules/core-java-string-apis-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-apis-2/README.md b/core-java-modules/core-java-string-apis-2/README.md index 57106b7151..c0b313d3b3 100644 --- a/core-java-modules/core-java-string-apis-2/README.md +++ b/core-java-modules/core-java-string-apis-2/README.md @@ -8,3 +8,4 @@ This module contains articles about string APIs. - [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) - [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) - [Compare StringBuilder Objects in Java](https://www.baeldung.com/java-stringbuilder-objects-comparison) +- [Finding the N-th Occurrence of a Substring in a String in Java](https://www.baeldung.com/java-locate-nth-match-substring) From 87018d44aedd2f215c1598aec8c782c01d38adbb Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sat, 11 Nov 2023 06:55:11 +0200 Subject: [PATCH 181/283] [JAVA-26715] Upgraded pdfbox to latest version --- pdf-2/pom.xml | 2 +- .../pdfinfo/PdfInfoITextUnitTest.java | 22 ++++++++++--------- .../pdfinfo/PdfInfoPdfBoxUnitTest.java | 22 ++++++++++--------- pdf/pom.xml | 2 +- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/pdf-2/pom.xml b/pdf-2/pom.xml index ccbb5c9693..2079ff70e5 100644 --- a/pdf-2/pom.xml +++ b/pdf-2/pom.xml @@ -51,7 +51,7 @@ 5.5.13.3 7.2.3 3.0.1 - 3.0.0-RC1 + 3.0.0 \ No newline at end of file diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java index 422858d659..f54405a533 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.io.IOException; import java.util.Map; -public class PdfInfoITextUnitTest { +import org.junit.jupiter.api.Test; + +class PdfInfoITextUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { Map info = PdfInfoIText.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.get("Producer")); - Assert.assertEquals("Writer", info.get("Creator")); + assertEquals("LibreOffice 4.2", info.get("Producer")); + assertEquals("Writer", info.get("Creator")); } } diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java index 0fcbc7ee3c..5c4e5fc30d 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; -public class PdfInfoPdfBoxUnitTest { +class PdfInfoPdfBoxUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { PDDocumentInformation info = PdfInfoPdfBox.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.getProducer()); - Assert.assertEquals("Writer", info.getCreator()); + assertEquals("LibreOffice 4.2", info.getProducer()); + assertEquals("Writer", info.getCreator()); } } diff --git a/pdf/pom.xml b/pdf/pom.xml index cead1b2ded..0fe90b6eb5 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -104,7 +104,7 @@ - 2.0.25 + 3.0.0 2.0.1 5.5.13.3 5.5.10 From 4062f3a1193017941523176517a90b94fcd1f707 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 11 Nov 2023 11:50:24 +0530 Subject: [PATCH 182/283] backlink updated --- spring-5-webflux-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 1b01f519a4..a0fafd903e 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -6,4 +6,4 @@ This module contains articles about Spring 5 WebFlux - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) -- [Using zipWhen() with Mono](https://www.baeldung.com/java-mono-zipwhen) +- [Using zipWhen() With Mono](https://www.baeldung.com/java-mono-zipwhen) From 173dd4bac3d78e7897274cd1a8625cad251846ff Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Sat, 11 Nov 2023 11:52:02 +0530 Subject: [PATCH 183/283] backlink updated --- persistence-modules/spring-data-jpa-query/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-data-jpa-query/README.md b/persistence-modules/spring-data-jpa-query/README.md index 27443c2026..27e7087592 100644 --- a/persistence-modules/spring-data-jpa-query/README.md +++ b/persistence-modules/spring-data-jpa-query/README.md @@ -5,7 +5,7 @@ This module contains articles about querying data using Spring Data JPA ### Relevant Articles: - [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query) - [Customizing the Result of JPA Queries with Aggregation Functions](https://www.baeldung.com/jpa-queries-custom-result-with-aggregation-functions) -- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results) +- [Limiting Query Results With JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results) - [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting) - [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example) - [JPA Join Types](https://www.baeldung.com/jpa-join-types) From b87609265da2f584dddb8eddfb830650c635655a Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sat, 11 Nov 2023 08:29:09 +0200 Subject: [PATCH 184/283] [JAVA-26709] Upgraded modelmapper to latest version --- .../pom.xml | 2 +- .../modelmapper/UsersListMappingUnitTest.java | 39 +++++++------------ libraries-6/pom.xml | 14 ++++--- parent-java/pom.xml | 2 +- performance-tests/pom.xml | 2 +- .../spring-boot-libraries/pom.xml | 2 +- spring-boot-rest/pom.xml | 2 +- 7 files changed, 28 insertions(+), 35 deletions(-) diff --git a/core-java-modules/core-java-collections-conversions-2/pom.xml b/core-java-modules/core-java-collections-conversions-2/pom.xml index 7b7533fc39..da6b6a564a 100644 --- a/core-java-modules/core-java-collections-conversions-2/pom.xml +++ b/core-java-modules/core-java-collections-conversions-2/pom.xml @@ -44,6 +44,6 @@ 0.10.3 11 - 3.1.1 + 3.2.0 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java index a8a72b12f7..c71f655044 100644 --- a/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java +++ b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java @@ -1,8 +1,9 @@ package com.baeldung.modelmapper; import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.modelmapper.ModelMapper; import org.modelmapper.TypeMap; import org.modelmapper.TypeToken; @@ -10,11 +11,10 @@ import org.modelmapper.TypeToken; import java.util.ArrayList; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasProperty; -import static org.junit.Assert.assertThat; - /** * This class has test methods of mapping Integer to Character list, @@ -22,12 +22,12 @@ import static org.junit.Assert.assertThat; * * @author Sasa Milenkovic */ -public class UsersListMappingUnitTest { +class UsersListMappingUnitTest { private ModelMapper modelMapper; private List users; - @Before + @BeforeEach public void init() { modelMapper = new ModelMapper(); @@ -35,18 +35,16 @@ public class UsersListMappingUnitTest { TypeMap typeMap = modelMapper.createTypeMap(UserList.class, UserListDTO.class); typeMap.addMappings(mapper -> mapper.using(new UsersListConverter()) - .map(UserList::getUsers, UserListDTO::setUsernames)); + .map(UserList::getUsers, UserListDTO::setUsernames)); - users = new ArrayList(); + users = new ArrayList<>(); users.add(new User("b100", "user1", "user1@baeldung.com", "111-222", "USER")); users.add(new User("b101", "user2", "user2@baeldung.com", "111-333", "USER")); users.add(new User("b102", "user3", "user3@baeldung.com", "111-444", "ADMIN")); - } @Test - public void whenInteger_thenMapToCharacter() { - + void whenInteger_thenMapToCharacter() { List integers = new ArrayList(); integers.add(1); @@ -57,36 +55,27 @@ public class UsersListMappingUnitTest { }.getType()); assertThat(characters, hasItems('1', '2', '3')); - } @Test - public void givenUsersList_whenUseGenericType_thenMapToUserDTO() { - + void givenUsersList_whenUseGenericType_thenMapToUserDTO() { // Mapping lists using custom (generic) type mapping - List userDtoList = MapperUtil.mapList(users, UserDTO.class); - assertThat(userDtoList, Matchers.hasItem( - Matchers.both(hasProperty("userId", equalTo("b100"))) - .and(hasProperty("email", equalTo("user1@baeldung.com"))) - .and(hasProperty("username", equalTo("user1"))))); - - + assertThat(userDtoList, Matchers. hasItem(Matchers.both(hasProperty("userId", equalTo("b100"))) + .and(hasProperty("email", equalTo("user1@baeldung.com"))) + .and(hasProperty("username", equalTo("user1"))))); } @Test - public void givenUsersList_whenUseConverter_thenMapToUsernames() { - + void givenUsersList_whenUseConverter_thenMapToUsernames() { // Mapping lists using property mapping and converter - UserList userList = new UserList(); userList.setUsers(users); UserListDTO dtos = new UserListDTO(); modelMapper.map(userList, dtos); assertThat(dtos.getUsernames(), hasItems("user1", "user2", "user3")); - } } \ No newline at end of file diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml index 139edab34f..9fa44d3a32 100644 --- a/libraries-6/pom.xml +++ b/libraries-6/pom.xml @@ -108,7 +108,7 @@ org.agrona agrona - 1.17.1 + ${agrona.version} @@ -126,7 +126,7 @@ org.codehaus.mojo exec-maven-plugin - 1.6.0 + ${exec-maven-plugin.version} generate-sources @@ -154,14 +154,14 @@ uk.co.real-logic sbe-tool - 1.27.0 + ${sbe-tool.version} org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + ${build-helper-maven-plugin.version} add-source @@ -204,7 +204,11 @@ 3.0 1.8.1 8.12.9 - 2.4.4 + 3.2.0 + 1.17.1 + 1.6.0 + 1.27.0 + 3.0.0 \ No newline at end of file diff --git a/parent-java/pom.xml b/parent-java/pom.xml index b08925e040..03cafac55b 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -40,7 +40,7 @@ - 2.3.7 + 3.2.0 \ No newline at end of file diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index 542a505b16..9f57a1a90c 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -152,7 +152,7 @@ 1.5.4 6.5.2 1.5.2.Final - 3.1.0 + 3.2.0 1.6.1.CR2 1.8 diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml index b7b8ad17ad..ed9a414a60 100644 --- a/spring-boot-modules/spring-boot-libraries/pom.xml +++ b/spring-boot-modules/spring-boot-libraries/pom.xml @@ -219,7 +219,7 @@ 5.0.2 5.2.4 2.2.4 - 2.3.2 + 3.2.0 0.23.0 2.1.0 1.5-beta1 diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index db646899ad..71916900a4 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -162,7 +162,7 @@ com.baeldung.SpringBootRestApplication 1.4.11.1 - 3.1.0 + 3.2.0 3.3.0 2.3.7 From 62b0d3def765c37d9082415d5411980dff8d3493 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 11 Nov 2023 12:17:46 +0530 Subject: [PATCH 185/283] JAVA-27185 Upgrade hibernate validator in spring-cloud-gateway-2 --- spring-cloud-modules/spring-cloud-gateway-2/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-modules/spring-cloud-gateway-2/pom.xml b/spring-cloud-modules/spring-cloud-gateway-2/pom.xml index 22182e8c78..4228c72d37 100644 --- a/spring-cloud-modules/spring-cloud-gateway-2/pom.xml +++ b/spring-cloud-modules/spring-cloud-gateway-2/pom.xml @@ -57,7 +57,7 @@ test - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -116,7 +116,7 @@ - 6.0.2.Final + 8.0.1.Final 0.7.2 9.19 From df9e040b765b8ac8e59e911d8ef170b1b8269682 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 11 Nov 2023 12:59:42 +0530 Subject: [PATCH 186/283] JAVA-27186 Upgrade hibernate validator version in spring-cloud-gateway --- spring-cloud-modules/spring-cloud-gateway/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-modules/spring-cloud-gateway/pom.xml b/spring-cloud-modules/spring-cloud-gateway/pom.xml index 76072a59ac..0287ab7588 100644 --- a/spring-cloud-modules/spring-cloud-gateway/pom.xml +++ b/spring-cloud-modules/spring-cloud-gateway/pom.xml @@ -62,7 +62,7 @@ test - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -185,7 +185,7 @@ - 6.0.2.Final + 8.0.1.Final 0.7.2 9.19 From 3435cd06509844c366a0d06a811bb967fc52ab2e Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 11 Nov 2023 13:43:35 +0530 Subject: [PATCH 187/283] JAVA-27187 Upgrade hibernate validator version in spring-core-2 --- spring-core-2/pom.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index 2d11cc2124..f27b16acc3 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -88,9 +88,8 @@ - org.hibernate + org.hibernate.validator hibernate-validator - ${hibernate.version} @@ -160,8 +159,6 @@ com.baeldung.sample.App 1.3.2 - - 5.2.5.Final 3.6 2.1.0 From 3d5b1cff86e129f3cd33b934967d30e0b5cefc53 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 11 Nov 2023 14:11:32 +0530 Subject: [PATCH 188/283] JAVA-27188 Upgrade hibernate-validator version in spring-exceptions --- spring-exceptions/pom.xml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index 49c44f88f2..e0071a4206 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -72,7 +72,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -108,11 +108,6 @@ ${org.springframework.version} test - - javax.el - el-api - ${javax.el.version} - org.apache.derby derby @@ -171,8 +166,7 @@ 7.0.73 10.13.1.1 - 5.3.3.Final - 2.2 + 8.0.1.Final 2.3.0 4.4.5 From 8fff0f323cb8b949b31ef47177c1e1035d4a03bc Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Sat, 11 Nov 2023 10:53:34 +0000 Subject: [PATCH 189/283] [JAVA-20077] Sorted modules in alphabetical order (#15168) * [JAVA-20077] Sorted modules in alphabetical order * [JAVA-2007] --- pom.xml | 680 ++++++++++++++++++++++++++------------------------------ 1 file changed, 310 insertions(+), 370 deletions(-) diff --git a/pom.xml b/pom.xml index bb5a0c9e7b..47c566023d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,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 com.baeldung parent-modules @@ -690,35 +690,157 @@ - parent-boot-3 - lombok-modules - osgi - spring-katharsis - logging-modules - spring-boot-modules - apache-httpclient - apache-httpclient4 + akka-modules + algorithms-modules + antlr + apache-cxf-modules apache-httpclient-2 - spring-mobile - microservices-modules - spring-ejb-modules - spring-di - spring-di-2 - spring-jinq - vavr-modules - java-websocket + apache-httpclient4 + apache-httpclient + apache-kafka-2 + apache-kafka + apache-libraries-2 + apache-libraries + apache-olingo + apache-poi-2 + apache-poi-3 + apache-poi + apache-thrift + apache-tika + apache-velocity + asciidoctor + asm + atomikos + atomix + aws-modules azure - netflix-modules - spf4j - spring-jersey - jersey - jaxb - + bazel + checker-framework + core-groovy-modules + core-java-modules + custom-pmd + data-structures + deeplearning4j + di-modules + disruptor + docker-modules + dozer + drools + dubbo + + gcp-firebase + geotools + google-auto-project + google-cloud + gradle-modules/gradle/maven-to-gradle + graphql-modules + grpc + guava-modules + hazelcast + httpclient-simple + hystrix + image-compressing + image-processing + jackson-modules + jackson-simple + java-blockchain + java-jdi + + java-rmi + java-spi + java-websocket javafx - spring-batch + javax-sound + javaxval-2 + javaxval + jaxb + jersey + jetbrains + jgit + jhipster-6 + jib + jmeter + jmh + jsf + json-modules + jsoup + jws + ksqldb + kubernetes-modules + language-interop + libraries-2 + libraries-3 + libraries-4 + libraries-5 + libraries-6 + libraries-ai + libraries-apache-commons-2 + libraries-apache-commons-collections + libraries-apache-commons-io + libraries-apache-commons + libraries-concurrency + libraries-data-2 + libraries-data-db + libraries-data-io + libraries-data + libraries-files + libraries-http-2 + libraries-http + libraries-io + libraries-llms + libraries-primitive + libraries-rpc + libraries-security + libraries-server-2 + libraries-server + libraries-testing + libraries-transform + libraries + lightrun + logging-modules + lombok-modules + lucene + mapstruct + maven-modules + mesos-marathon + messaging-modules + metrics + microservices-modules + mustache + mybatis + netflix-modules + optaplanner + orika + osgi + parent-boot-3 + patterns-modules + pdf-2 + pdf + performance-tests + persistence-modules + persistence-modules/spring-data-neo4j + protobuffer + quarkus-modules + reactive-systems + reactor-core + rsocket + rule-engines-modules + rxjava-modules + saas-modules + security-modules + server-modules + spf4j + spring-5-webflux-2 + spring-5-webflux + spring-5 + spring-activiti + spring-actuator + spring-aop-2 + spring-aop spring-batch-2 + spring-batch + spring-boot-modules spring-boot-rest - spring-drools spring-cloud-modules/spring-cloud-azure spring-cloud-modules/spring-cloud-circuit-breaker spring-cloud-modules/spring-cloud-contract @@ -728,210 +850,58 @@ spring-cloud-modules/spring-cloud-security spring-cloud-modules/spring-cloud-stream-starters spring-cloud-modules/spring-cloud-zuul-eureka-integration - - spring-exceptions - spring-jenkins-pipeline - spring-core - spring-core-4 - spring-integration - spring-remoting-modules - libraries-security - libraries-data-db - - performance-tests - security-modules - libraries-server-2 - orika - patterns-modules - json-modules - libraries-data - saas-modules - server-modules - apache-cxf-modules - - spring-aop - jmeter - spring-aop-2 - - algorithms-modules - apache-libraries - apache-libraries-2 - apache-poi - apache-velocity - di-modules - asciidoctor - aws-modules - - checker-framework - core-groovy-modules - - core-java-modules - custom-pmd - data-structures - jackson-modules - jmh - deeplearning4j - docker-modules - drools - guava-modules - kubernetes-modules - libraries-concurrency - jhipster-6 - libraries-testing - maven-modules - optaplanner - persistence-modules - quarkus-modules - spring-reactive-modules - spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules - testing-modules/mockito-simple - - rule-engines-modules - - reactive-systems - rxjava-modules - - lightrun - tablesaw - image-compressing - geotools - - jws - - - - akka-modules - httpclient-simple - antlr - apache-kafka - apache-kafka-2 - apache-olingo - - apache-poi-2 - apache-poi-3 - apache-thrift - apache-tika - - asm - atomikos - atomix - - bazel - google-auto-project - disruptor - dozer - dubbo - - google-cloud - graphql-modules - grpc - hazelcast - hystrix - jackson-simple - java-blockchain - java-jdi - java-rmi - java-spi - javax-sound - javaxval - javaxval-2 - jetbrains - jgit - jib - - jsoup - ksqldb - jsf - - libraries - libraries-2 - libraries-4 - libraries-5 - libraries-6 - - libraries-apache-commons - libraries-apache-commons-2 - libraries-apache-commons-collections - libraries-apache-commons-io - libraries-data-2 - libraries-data-io - libraries-files - libraries-http - libraries-http-2 - libraries-io - libraries-ai - libraries-primitive - libraries-rpc - libraries-server - libraries-transform - - lucene - mapstruct - mesos-marathon - metrics - mustache - mybatis - pdf - pdf-2 - protobuffer - reactor-core - rsocket - - - spring-5 - spring-5-webflux - spring-5-webflux-2 - spring-6-rsocket - spring-activiti - spring-actuator spring-core-2 spring-core-3 + spring-core-4 + spring-core spring-credhub - spring-di-3 spring-cucumber - + spring-di-2 + spring-di-3 + spring-di-4 + spring-di + spring-drools + spring-ejb-modules + spring-exceptions + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-kafka-2 spring-kafka - + spring-katharsis + spring-mobile spring-native - spring-soap - spring-security-modules spring-protobuf + spring-pulsar spring-quartz - + spring-reactive-modules + spring-remoting-modules spring-scheduling - - spring-state-machine + spring-security-modules spring-shell + spring-soap spring-spel + spring-state-machine spring-static-resources + spring-swagger-codegen/custom-validations-opeanpi-codegen spring-threads spring-vault - spring-websockets spring-web-modules + spring-websockets static-analysis + tablesaw tensorflow-java - vertx-modules - xstream - webrtc - - messaging-modules - + testing-modules + testing-modules/mockito-simple vaadin - libraries-3 + vavr-modules + vertx-modules web-modules - xml + webrtc xml-2 - image-processing - language-interop - gradle-modules/gradle/maven-to-gradle - persistence-modules/spring-data-neo4j - gcp-firebase - spring-di-4 - spring-kafka-2 - - libraries-llms - spring-pulsar + xml + xstream @@ -965,248 +935,218 @@ - parent-boot-3 - lombok-modules - osgi - spring-katharsis - logging-modules - spring-boot-modules - apache-httpclient - apache-httpclient4 - apache-httpclient-2 - spring-mobile - microservices-modules - spring-ejb-modules - spring-di - spring-di-2 - spring-jinq - vavr-modules - java-websocket - azure - netflix-modules - spf4j - spring-jersey - jersey - jaxb - - javafx - spring-batch - spring-batch-2 - spring-boot-rest - spring-drools - spring-cloud-modules/spring-cloud-azure - spring-cloud-modules/spring-cloud-circuit-breaker - spring-cloud-modules/spring-cloud-eureka - spring-cloud-modules/spring-cloud-contract - spring-cloud-modules/spring-cloud-data-flow - spring-cloud-modules/spring-cloud-netflix-feign - spring-cloud-modules/spring-cloud-stream-starters - spring-cloud-modules/spring-cloud-security - spring-cloud-modules/spring-cloud-zuul-eureka-integration - - spring-exceptions - spring-jenkins-pipeline - spring-core - spring-core-4 - spring-integration - spring-remoting-modules - libraries-security - libraries-data-db - - performance-tests - security-modules - libraries-server-2 - orika - patterns-modules - json-modules - libraries-data - saas-modules - server-modules - apache-cxf-modules - - algorithms-modules - apache-libraries - apache-libraries-2 - apache-poi - apache-velocity - di-modules - asciidoctor - aws-modules - - checker-framework - - core-groovy-modules - - core-java-modules - gcp-firebase - spring-aop - spring-aop-2 - custom-pmd - data-structures - jackson-modules - jmh - deeplearning4j - jmeter - docker-modules - drools - guava-modules - kubernetes-modules - libraries-concurrency - jhipster-6 - libraries-testing - maven-modules - optaplanner - persistence-modules - quarkus-modules - spring-reactive-modules - spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules - testing-modules/mockito-simple - - rule-engines-modules - - reactive-systems - rxjava-modules - - lightrun - tablesaw - image-compressing - geotools - - jws - - - akka-modules + algorithms-modules antlr - apache-kafka + apache-cxf-modules + apache-httpclient-2 + apache-httpclient4 + apache-httpclient apache-kafka-2 + apache-kafka + apache-libraries-2 + apache-libraries apache-olingo - apache-poi-2 apache-poi-3 + apache-poi apache-thrift apache-tika - + apache-velocity + asciidoctor asm atomikos atomix - + aws-modules + azure bazel - google-auto-project + checker-framework + core-groovy-modules + core-java-modules + custom-pmd + data-structures + deeplearning4j + di-modules disruptor + docker-modules dozer - + drools dubbo + gcp-firebase + geotools + google-auto-project google-cloud + gradle-modules/gradle/maven-to-gradle graphql-modules grpc + guava-modules hazelcast httpclient-simple hystrix + image-compressing + image-processing + jackson-modules jackson-simple java-blockchain java-jdi + java-rmi java-spi + java-websocket + javafx javax-sound - javaxval javaxval-2 + javaxval + jaxb + jersey jetbrains jgit + jhipster-6 jib - - jsoup + jmeter + jmh jsf + json-modules + jsoup + jws ksqldb - - libraries + kubernetes-modules + language-interop libraries-2 + libraries-3 libraries-4 libraries-5 libraries-6 - libraries-apache-commons + libraries-ai libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io + libraries-apache-commons + libraries-concurrency libraries-data-2 + libraries-data-db libraries-data-io + libraries-data libraries-files - libraries-http libraries-http-2 + libraries-http libraries-io - libraries-ai + libraries-llms libraries-primitive libraries-rpc + libraries-security + libraries-server-2 libraries-server + libraries-testing libraries-transform - + libraries + lightrun + logging-modules + lombok-modules lucene mapstruct + maven-modules mesos-marathon + messaging-modules metrics + microservices-modules mustache mybatis - pdf + netflix-modules + optaplanner + orika + osgi + parent-boot-3 + patterns-modules pdf-2 + pdf + performance-tests + persistence-modules + persistence-modules/spring-data-neo4j protobuffer + quarkus-modules + reactive-systems reactor-core rsocket - - - - spring-5 - spring-5-webflux + rule-engines-modules + rxjava-modules + saas-modules + security-modules + server-modules + spf4j spring-5-webflux-2 + spring-5-webflux + spring-5 spring-activiti + spring-actuator + spring-aop-2 + spring-aop + spring-batch-2 + spring-batch + spring-boot-modules + spring-boot-rest + spring-cloud-modules/spring-cloud-azure + spring-cloud-modules/spring-cloud-circuit-breaker + spring-cloud-modules/spring-cloud-contract + spring-cloud-modules/spring-cloud-data-flow + spring-cloud-modules/spring-cloud-eureka + spring-cloud-modules/spring-cloud-netflix-feign + spring-cloud-modules/spring-cloud-security + spring-cloud-modules/spring-cloud-stream-starters + spring-cloud-modules/spring-cloud-zuul-eureka-integration spring-core-2 spring-core-3 + spring-core-4 + spring-core spring-credhub - spring-di-3 spring-cucumber - + spring-di-2 + spring-di-3 + spring-di-4 + spring-di + spring-drools + spring-ejb-modules + spring-exceptions + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-kafka-2 spring-kafka - + spring-katharsis + spring-mobile spring-native - spring-soap - spring-security-modules spring-protobuf + spring-pulsar spring-quartz - + spring-reactive-modules + spring-remoting-modules spring-scheduling - - spring-state-machine + spring-security-modules spring-shell + spring-soap spring-spel + spring-state-machine spring-static-resources + spring-swagger-codegen/custom-validations-opeanpi-codegen spring-threads spring-vault - spring-websockets spring-web-modules + spring-websockets static-analysis + tablesaw tensorflow-java - vertx-modules - xstream - webrtc - - messaging-modules - + testing-modules + testing-modules/mockito-simple vaadin - libraries-3 + vavr-modules + vertx-modules web-modules - xml + webrtc xml-2 - image-processing - language-interop - gradle-modules/gradle/maven-to-gradle - persistence-modules/spring-data-neo4j - spring-actuator - spring-di-4 - spring-kafka-2 - - libraries-llms - spring-pulsar + xml + xstream From 3f850f7d00d6bb52046edb1b502062ae18c816cd Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Sat, 11 Nov 2023 12:05:30 +0100 Subject: [PATCH 190/283] JAVA-26728 | update sshj lib (#15144) * JAVA-26728 | update sshj lib * JAVA-26728 | added compression --- libraries-io/pom.xml | 2 +- .../io/remote/SftpFileTransferLiveTest.java | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries-io/pom.xml b/libraries-io/pom.xml index 08ad0afc3f..7464b9a507 100644 --- a/libraries-io/pom.xml +++ b/libraries-io/pom.xml @@ -56,7 +56,7 @@ 0.1.55 - 0.27.0 + 0.37.0 2.4 2.9.0 5.8 diff --git a/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java b/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java index 5846128082..81c6cb556c 100644 --- a/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java +++ b/libraries-io/src/test/java/com/baeldung/java/io/remote/SftpFileTransferLiveTest.java @@ -20,14 +20,14 @@ import net.schmizz.sshj.transport.verification.PromiscuousVerifier; public class SftpFileTransferLiveTest { - private String remoteHost = "HOST_NAME_HERE"; - private String username = "USERNAME_HERE"; - private String password = "PASSWORD_HERE"; - private String localFile = "src/main/resources/input.txt"; - private String remoteFile = "welcome.txt"; - private String localDir = "src/main/resources/"; - private String remoteDir = "remote_sftp_test/"; - private String knownHostsFileLoc = "/Users/USERNAME/known_hosts_sample"; + private final String remoteHost = "HOST_NAME_HERE"; + private final String username = "USERNAME_HERE"; + private final String password = "PASSWORD_HERE"; + private final String localFile = "src/main/resources/input.txt"; + private final String remoteFile = "welcome.txt"; + private final String localDir = "src/main/resources/"; + private final String remoteDir = "remote_sftp_test/"; + private final String knownHostsFileLoc = "/Users/USERNAME/known_hosts_sample"; @Test public void whenUploadFileUsingJsch_thenSuccess() throws JSchException, SftpException { @@ -100,6 +100,7 @@ public class SftpFileTransferLiveTest { client.addHostKeyVerifier(new PromiscuousVerifier()); client.connect(remoteHost); client.authPassword(username, password); + client.useCompression(); return client; } From 47f7b926e60709efe74245b33a37a3cb0c2f7db0 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 07:32:39 +0200 Subject: [PATCH 191/283] [JAVA-26774] Upgraded mapstruct library to latest version --- core-java-modules/core-java-lang-6/pom.xml | 3 +-- jhipster-6/bookstore-monolith/pom.xml | 2 +- jhipster-modules/jhipster-microservice/car-app/pom.xml | 2 +- jhipster-modules/jhipster-microservice/dealer-app/pom.xml | 2 +- jhipster-modules/jhipster-microservice/gateway-app/pom.xml | 2 +- jhipster-modules/jhipster-monolithic/pom.xml | 2 +- jhipster-modules/jhipster-uaa/gateway/pom.xml | 2 +- jhipster-modules/jhipster-uaa/quotes/pom.xml | 2 +- jhipster-modules/jhipster-uaa/uaa/pom.xml | 2 +- mapstruct/pom.xml | 2 +- performance-tests/pom.xml | 2 +- persistence-modules/spring-data-jpa-enterprise/pom.xml | 4 ++-- spring-boot-modules/spring-boot-3-2/pom.xml | 2 +- spring-boot-modules/spring-boot-3/pom.xml | 4 ++-- 14 files changed, 16 insertions(+), 17 deletions(-) diff --git a/core-java-modules/core-java-lang-6/pom.xml b/core-java-modules/core-java-lang-6/pom.xml index 6561c4fdcc..54035c1eb0 100644 --- a/core-java-modules/core-java-lang-6/pom.xml +++ b/core-java-modules/core-java-lang-6/pom.xml @@ -29,7 +29,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5.1 17 17 @@ -50,7 +49,7 @@ 17 17 UTF-8 - 1.5.5.Final + 1.6.0.Beta1 \ No newline at end of file diff --git a/jhipster-6/bookstore-monolith/pom.xml b/jhipster-6/bookstore-monolith/pom.xml index a35abb9c19..26a1ff6214 100644 --- a/jhipster-6/bookstore-monolith/pom.xml +++ b/jhipster-6/bookstore-monolith/pom.xml @@ -1159,7 +1159,7 @@ 5.1.5.RELEASE 2.0.1.Final 2.3.2 - 1.3.0.Final + 1.6.0.Beta1 3.1.0 diff --git a/jhipster-modules/jhipster-microservice/car-app/pom.xml b/jhipster-modules/jhipster-microservice/car-app/pom.xml index f345688939..3789dc35c1 100644 --- a/jhipster-modules/jhipster-microservice/car-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/car-app/pom.xml @@ -36,7 +36,7 @@ 3.6.2 4.8 jdt_apt - 1.1.0.Final + 1.6.0.Beta1 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml index 056bd60f33..5d588e8dcb 100644 --- a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml @@ -35,7 +35,7 @@ 3.6.2 4.8 jdt_apt - 1.1.0.Final + 1.6.0.Beta1 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml index b90f22f009..26c621bb57 100644 --- a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml @@ -39,7 +39,7 @@ 4.8 1.3.0 jdt_apt - 1.1.0.Final + 1.6.0.Beta1 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-monolithic/pom.xml b/jhipster-modules/jhipster-monolithic/pom.xml index fbcee8f1ff..a8b93b5514 100644 --- a/jhipster-modules/jhipster-monolithic/pom.xml +++ b/jhipster-modules/jhipster-monolithic/pom.xml @@ -904,7 +904,7 @@ 3.6.2 4.8 jdt_apt - 1.1.0.Final + 1.6.0.Beta1 1.4.1 3.0.1 2.10 diff --git a/jhipster-modules/jhipster-uaa/gateway/pom.xml b/jhipster-modules/jhipster-uaa/gateway/pom.xml index 13652575cd..b1982a6f93 100644 --- a/jhipster-modules/jhipster-uaa/gateway/pom.xml +++ b/jhipster-modules/jhipster-uaa/gateway/pom.xml @@ -1048,7 +1048,7 @@ 3.5.5 3.6 2.0.1.Final - 1.2.0.Final + 1.6.0.Beta1 3.1.0 diff --git a/jhipster-modules/jhipster-uaa/quotes/pom.xml b/jhipster-modules/jhipster-uaa/quotes/pom.xml index 2a3c550071..11033af395 100644 --- a/jhipster-modules/jhipster-uaa/quotes/pom.xml +++ b/jhipster-modules/jhipster-uaa/quotes/pom.xml @@ -868,7 +868,7 @@ 3.5.5 3.6 2.0.1.Final - 1.2.0.Final + 1.6.0.Beta1 3.1.0 diff --git a/jhipster-modules/jhipster-uaa/uaa/pom.xml b/jhipster-modules/jhipster-uaa/uaa/pom.xml index 42802b6040..47a5c81c1e 100644 --- a/jhipster-modules/jhipster-uaa/uaa/pom.xml +++ b/jhipster-modules/jhipster-uaa/uaa/pom.xml @@ -869,7 +869,7 @@ 3.5.5 3.6 2.0.1.Final - 1.2.0.Final + 1.6.0.Beta1 3.1.0 diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index 7c279acb7b..5332bcaeb3 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -73,7 +73,7 @@ - 1.5.5.Final + 1.6.0.Beta1 4.3.4.RELEASE 0.2.0 diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index 9f57a1a90c..d22a9cf3ac 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -151,7 +151,7 @@ 1.5.4 6.5.2 - 1.5.2.Final + 1.6.0.Beta1 3.2.0 1.6.1.CR2 diff --git a/persistence-modules/spring-data-jpa-enterprise/pom.xml b/persistence-modules/spring-data-jpa-enterprise/pom.xml index 6bd89032fa..d998849ffb 100644 --- a/persistence-modules/spring-data-jpa-enterprise/pom.xml +++ b/persistence-modules/spring-data-jpa-enterprise/pom.xml @@ -45,7 +45,7 @@ org.mapstruct - mapstruct-jdk8 + mapstruct ${mapstruct.version} provided @@ -97,7 +97,7 @@ - 1.3.1.Final + 1.6.0.Beta1 1.19.1 diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml index 276659c609..9b5b7ea254 100644 --- a/spring-boot-modules/spring-boot-3-2/pom.xml +++ b/spring-boot-modules/spring-boot-3-2/pom.xml @@ -280,7 +280,7 @@ - 1.5.2.Final + 1.6.0.Beta1 2.0.0 3.0.0-M7 5.14.0 diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index bb8c5dd53c..a1a5eab563 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -206,8 +206,8 @@ - 19 - 1.5.2.Final + 17 + 1.6.0.Beta1 2.2.0 3.0.0-M7 com.baeldung.sample.TodoApplication From 6db881bfa2df6776a67b7de0873c07bed1402aed Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 07:53:55 +0200 Subject: [PATCH 192/283] [JAVA-26774] Revert mapstruct upgrade on jhipster modules --- jhipster-6/bookstore-monolith/pom.xml | 2 +- jhipster-modules/jhipster-microservice/car-app/pom.xml | 2 +- jhipster-modules/jhipster-microservice/dealer-app/pom.xml | 2 +- jhipster-modules/jhipster-microservice/gateway-app/pom.xml | 2 +- jhipster-modules/jhipster-monolithic/pom.xml | 2 +- jhipster-modules/jhipster-uaa/gateway/pom.xml | 2 +- jhipster-modules/jhipster-uaa/quotes/pom.xml | 2 +- jhipster-modules/jhipster-uaa/uaa/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jhipster-6/bookstore-monolith/pom.xml b/jhipster-6/bookstore-monolith/pom.xml index 26a1ff6214..a35abb9c19 100644 --- a/jhipster-6/bookstore-monolith/pom.xml +++ b/jhipster-6/bookstore-monolith/pom.xml @@ -1159,7 +1159,7 @@ 5.1.5.RELEASE 2.0.1.Final 2.3.2 - 1.6.0.Beta1 + 1.3.0.Final 3.1.0 diff --git a/jhipster-modules/jhipster-microservice/car-app/pom.xml b/jhipster-modules/jhipster-microservice/car-app/pom.xml index 3789dc35c1..f345688939 100644 --- a/jhipster-modules/jhipster-microservice/car-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/car-app/pom.xml @@ -36,7 +36,7 @@ 3.6.2 4.8 jdt_apt - 1.6.0.Beta1 + 1.1.0.Final 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml index 5d588e8dcb..056bd60f33 100644 --- a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml @@ -35,7 +35,7 @@ 3.6.2 4.8 jdt_apt - 1.6.0.Beta1 + 1.1.0.Final 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml index 26c621bb57..b90f22f009 100644 --- a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml @@ -39,7 +39,7 @@ 4.8 1.3.0 jdt_apt - 1.6.0.Beta1 + 1.1.0.Final 2.10 1.4.1 3.0.1 diff --git a/jhipster-modules/jhipster-monolithic/pom.xml b/jhipster-modules/jhipster-monolithic/pom.xml index a8b93b5514..fbcee8f1ff 100644 --- a/jhipster-modules/jhipster-monolithic/pom.xml +++ b/jhipster-modules/jhipster-monolithic/pom.xml @@ -904,7 +904,7 @@ 3.6.2 4.8 jdt_apt - 1.6.0.Beta1 + 1.1.0.Final 1.4.1 3.0.1 2.10 diff --git a/jhipster-modules/jhipster-uaa/gateway/pom.xml b/jhipster-modules/jhipster-uaa/gateway/pom.xml index b1982a6f93..13652575cd 100644 --- a/jhipster-modules/jhipster-uaa/gateway/pom.xml +++ b/jhipster-modules/jhipster-uaa/gateway/pom.xml @@ -1048,7 +1048,7 @@ 3.5.5 3.6 2.0.1.Final - 1.6.0.Beta1 + 1.2.0.Final 3.1.0 diff --git a/jhipster-modules/jhipster-uaa/quotes/pom.xml b/jhipster-modules/jhipster-uaa/quotes/pom.xml index 11033af395..2a3c550071 100644 --- a/jhipster-modules/jhipster-uaa/quotes/pom.xml +++ b/jhipster-modules/jhipster-uaa/quotes/pom.xml @@ -868,7 +868,7 @@ 3.5.5 3.6 2.0.1.Final - 1.6.0.Beta1 + 1.2.0.Final 3.1.0 diff --git a/jhipster-modules/jhipster-uaa/uaa/pom.xml b/jhipster-modules/jhipster-uaa/uaa/pom.xml index 47a5c81c1e..42802b6040 100644 --- a/jhipster-modules/jhipster-uaa/uaa/pom.xml +++ b/jhipster-modules/jhipster-uaa/uaa/pom.xml @@ -869,7 +869,7 @@ 3.5.5 3.6 2.0.1.Final - 1.6.0.Beta1 + 1.2.0.Final 3.1.0 From 7dbd9cf9f60aa62ce088a7196d606f6c2e4c870c Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 08:00:42 +0200 Subject: [PATCH 193/283] [JAVA-26774] --- spring-boot-modules/spring-boot-3/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index a1a5eab563..ae9e9d7308 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -206,7 +206,7 @@ - 17 + 19 1.6.0.Beta1 2.2.0 3.0.0-M7 From 46dbc56913f2b3dc7f90b1d12e540a20edcb3ebf Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 12 Nov 2023 11:51:29 +0530 Subject: [PATCH 194/283] JAVA-27189 Upgrade hibernate validator version in spring-static-resources --- spring-static-resources/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index f682eafdbe..f635583e62 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -117,7 +117,7 @@ ${jackson.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -194,7 +194,7 @@ 1.8.9 - 6.0.10.Final + 8.0.1.Final 4.1.0 2.10 1 From c5cbb3f0d98d88531bda791ee49463c4411129f0 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 08:52:18 +0200 Subject: [PATCH 195/283] [JAVA-26763] Upgraded powermock to latest version --- spring-web-modules/spring-mvc-velocity/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web-modules/spring-mvc-velocity/pom.xml b/spring-web-modules/spring-mvc-velocity/pom.xml index 676fa09dac..cc92e8c6a5 100644 --- a/spring-web-modules/spring-mvc-velocity/pom.xml +++ b/spring-web-modules/spring-mvc-velocity/pom.xml @@ -64,7 +64,7 @@ org.powermock - powermock-api-mockito + powermock-api-mockito2 ${powermock.version} test @@ -106,7 +106,7 @@ - 1.6.6 + 2.0.9 4.4.5 4.5.2 1.7 From 21f73644b4b55c9508d588f0613690390ed404e7 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 12 Nov 2023 13:24:22 +0530 Subject: [PATCH 196/283] JAVA-27191 Upgrade hibernate validator version in spring-mvc-basics-2 --- spring-web-modules/spring-mvc-basics-2/pom.xml | 4 ++-- .../com/baeldung/spring/controller/CustomerController.java | 2 +- .../com/baeldung/spring/controller/EmployeeController.java | 2 +- .../java/com/baeldung/spring/controller/MailController.java | 2 +- .../src/main/java/com/baeldung/spring/domain/Employee.java | 4 ++-- .../main/java/com/baeldung/spring/domain/MailObject.java | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spring-web-modules/spring-mvc-basics-2/pom.xml b/spring-web-modules/spring-mvc-basics-2/pom.xml index 28eb3a16f2..613e42dee3 100644 --- a/spring-web-modules/spring-mvc-basics-2/pom.xml +++ b/spring-web-modules/spring-mvc-basics-2/pom.xml @@ -42,7 +42,7 @@ ${jstl.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -148,7 +148,7 @@ - 6.0.10.Final + 8.0.1.Final enter-location-of-server 3.0.11.RELEASE 2.4.12 diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java index 8ecfce58e3..e1d2a8e37f 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/CustomerController.java @@ -1,6 +1,6 @@ package com.baeldung.spring.controller; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java index 6543a98af1..5299d8289b 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/EmployeeController.java @@ -3,7 +3,7 @@ package com.baeldung.spring.controller; import java.util.HashMap; import java.util.Map; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java index b6e19a4c39..f4088b8bb3 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/controller/MailController.java @@ -8,7 +8,7 @@ import java.util.Set; import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java index 900770b873..a0641b0a32 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/Employee.java @@ -1,7 +1,7 @@ package com.baeldung.spring.domain; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class Employee { diff --git a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java index d425ca9a26..23807926ca 100644 --- a/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java +++ b/spring-web-modules/spring-mvc-basics-2/src/main/java/com/baeldung/spring/domain/MailObject.java @@ -1,8 +1,8 @@ package com.baeldung.spring.domain; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; /** * Created by Olga on 7/20/2016. From 57b035bade3b2481ec793d1ca7bd85f012f86dee Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 12 Nov 2023 14:01:38 +0530 Subject: [PATCH 197/283] JAVA-27192 Upgrade hibernate validator in spring-mvc-crash --- spring-web-modules/spring-mvc-crash/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-mvc-crash/pom.xml b/spring-web-modules/spring-mvc-crash/pom.xml index f3faa18816..9bfcfb488e 100644 --- a/spring-web-modules/spring-mvc-crash/pom.xml +++ b/spring-web-modules/spring-mvc-crash/pom.xml @@ -147,7 +147,7 @@ 4.4.5 4.5.2 - 6.0.10.Final + 8.0.1.Final 3.0.1-b08 2.8.0 From e6316d25d3f8be6060ea15aae0fc2c7196240db0 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sun, 12 Nov 2023 14:30:03 +0530 Subject: [PATCH 198/283] JAVA-27193 Upgrade hibernate validator version in spring-mvc-forms-jsp --- spring-web-modules/spring-mvc-forms-jsp/pom.xml | 4 ++-- .../controller/CustomerController.java | 2 +- .../controller/EmployeeController.java | 2 +- .../springmvcforms/controller/UserController.java | 2 +- .../com/baeldung/springmvcforms/domain/Employee.java | 4 ++-- .../com/baeldung/springmvcforms/domain/User.java | 12 ++++++------ 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/spring-web-modules/spring-mvc-forms-jsp/pom.xml b/spring-web-modules/spring-mvc-forms-jsp/pom.xml index 3ad815e95f..5096c6e23d 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/pom.xml +++ b/spring-web-modules/spring-mvc-forms-jsp/pom.xml @@ -48,7 +48,7 @@ ${mysql-connector-java.version} - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -102,7 +102,7 @@ - 6.0.10.Final + 8.0.1.Final 5.2.5.Final 6.0.6 1.3.2 diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java index 586c2467fe..81dd700551 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/CustomerController.java @@ -1,6 +1,6 @@ package com.baeldung.springmvcforms.controller; -import javax.validation.Valid; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java index 478b3532fe..9c0b3a7086 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/EmployeeController.java @@ -7,7 +7,7 @@ import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.HashMap; import java.util.Map; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java index f5553cf2b7..80f56645a9 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/controller/UserController.java @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java index 23cb72b3dc..ae174e2020 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/Employee.java @@ -1,7 +1,7 @@ package com.baeldung.springmvcforms.domain; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class Employee { diff --git a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java index 9e0e7c99be..db055763a4 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java +++ b/spring-web-modules/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/domain/User.java @@ -1,11 +1,11 @@ package com.baeldung.springmvcforms.domain; -import javax.validation.constraints.Digits; -import javax.validation.constraints.Email; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Digits; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; public class User { From ec251f847b550c513d6431ea34de0599e298c239 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 16:35:46 +0200 Subject: [PATCH 199/283] [JAVA-26739] Upgraded json-path to latest version --- core-java-modules/core-java-optional/pom.xml | 4 +- .../java9additions/Java9OptionalUnitTest.java | 170 +++++++++--------- ethereum/pom.xml | 2 +- jackson-modules/jackson-annotations/pom.xml | 4 +- json-modules/json-path/pom.xml | 4 +- .../spring-mvc-basics-5/pom.xml | 2 +- spring-web-modules/spring-mvc-java/pom.xml | 2 +- video-tutorials/jackson-annotations/pom.xml | 2 +- 8 files changed, 94 insertions(+), 96 deletions(-) diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index eeefed867e..68800f67fc 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -47,14 +47,14 @@ io.rest-assured json-path - ${rest-assured.version} + ${json-path.version} test 5.4.0.Final - 3.1.1 + 5.3.2 \ No newline at end of file diff --git a/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java b/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java index ee04432e44..e7daac4b8c 100644 --- a/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java +++ b/core-java-modules/core-java-optional/src/test/java/com/baeldung/java9additions/Java9OptionalUnitTest.java @@ -8,88 +8,88 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -// Uncomment code when code base is compatible with Java 9 -//public class Java9OptionalUnitTest { -// -// @Test -// public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { -// //given -// Optional value = Optional.of("a"); -// -// //when -// List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); -// -// //then -// assertThat(collect).hasSameElementsAs(List.of("A")); -// } -// -// @Test -// public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { -// //given -// Optional value = Optional.empty(); -// -// //when -// List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); -// -// //then -// assertThat(collect).isEmpty(); -// } -// -// @Test -// public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { -// //given -// Optional value = Optional.of("properValue"); -// AtomicInteger successCounter = new AtomicInteger(0); -// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); -// -// //when -// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); -// -// //then -// assertThat(successCounter.get()).isEqualTo(1); -// assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); -// } -// -// @Test -// public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { -// //given -// Optional value = Optional.empty(); -// AtomicInteger successCounter = new AtomicInteger(0); -// AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); -// -// //when -// value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); -// -// //then -// assertThat(successCounter.get()).isEqualTo(0); -// assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); -// } -// -// @Test -// public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { -// //given -// String expected = "properValue"; -// Optional value = Optional.of(expected); -// Optional defaultValue = Optional.of("default"); -// -// //when -// Optional result = value.or(() -> defaultValue); -// -// //then -// assertThat(result.get()).isEqualTo(expected); -// } -// -// @Test -// public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { -// //given -// String defaultString = "default"; -// Optional value = Optional.empty(); -// Optional defaultValue = Optional.of(defaultString); -// -// //when -// Optional result = value.or(() -> defaultValue); -// -// //then -// assertThat(result.get()).isEqualTo(defaultString); -// } -//} \ No newline at end of file + +public class Java9OptionalUnitTest { + + @Test + public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { + //given + Optional value = Optional.of("a"); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).hasSameElementsAs(List.of("A")); + } + + @Test + public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { + //given + Optional value = Optional.empty(); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).isEmpty(); + } + + @Test + public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.of("properValue"); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(1); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); + } + + @Test + public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.empty(); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(0); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); + } + + @Test + public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { + //given + String expected = "properValue"; + Optional value = Optional.of(expected); + Optional defaultValue = Optional.of("default"); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(expected); + } + + @Test + public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { + //given + String defaultString = "default"; + Optional value = Optional.empty(); + Optional defaultValue = Optional.of(defaultString); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(defaultString); + } +} \ No newline at end of file diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 8dc25427d9..a94f74c115 100644 --- a/ethereum/pom.xml +++ b/ethereum/pom.xml @@ -192,7 +192,7 @@ 1.5.0-RELEASE 3.3.1 1.5.6.RELEASE - 2.4.0 + 2.8.0 2.0.4.RELEASE 3.1 diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml index e2d5e1e607..59d7d3d197 100644 --- a/jackson-modules/jackson-annotations/pom.xml +++ b/jackson-modules/jackson-annotations/pom.xml @@ -21,7 +21,7 @@ io.rest-assured json-path - ${rest-assured.version} + ${json-path.version} test @@ -59,7 +59,7 @@ 2.1.214 - 3.1.1 + 5.3.2 2.5.0 diff --git a/json-modules/json-path/pom.xml b/json-modules/json-path/pom.xml index 88b81dfc68..763a275290 100644 --- a/json-modules/json-path/pom.xml +++ b/json-modules/json-path/pom.xml @@ -13,7 +13,6 @@ - com.jayway.jsonpath json-path @@ -22,8 +21,7 @@ - - 2.4.0 + 2.8.0 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics-5/pom.xml b/spring-web-modules/spring-mvc-basics-5/pom.xml index e0d603e303..1c8c87a2ef 100644 --- a/spring-web-modules/spring-mvc-basics-5/pom.xml +++ b/spring-web-modules/spring-mvc-basics-5/pom.xml @@ -82,7 +82,7 @@ 1.3.2 - 2.7.0 + 2.8.0 2.3.5 2.0.0 3.0.0 diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index 8098f07282..717c3b76b8 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -237,7 +237,7 @@ 4.0.1 2.3.3 2.32 - 2.4.0 + 2.8.0 com.baeldung.SpringMVCApplication diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index eaec50c1f7..f6a2e6928a 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -120,7 +120,7 @@ 3.0.1 3.0.0 2.2.6 - 3.0.1 + 5.3.2 \ No newline at end of file From fc91dd633712953b632249dda9d78f1ef9a75c3c Mon Sep 17 00:00:00 2001 From: gaepi Date: Sun, 12 Nov 2023 16:01:21 +0100 Subject: [PATCH 200/283] JAVA-27462 | removing spring security deprecations. --- .../src/main/java/com/baeldung/keycloak/SecurityConfig.java | 4 +++- .../com/baeldung/keycloaksoap/KeycloakSecurityConfig.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) 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 eb7767480f..5b9ce9677a 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 @@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -53,7 +54,8 @@ class SecurityConfig { .hasRole("USER") .anyRequest() .authenticated(); - http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + http.oauth2ResourceServer((oauth2) -> oauth2 + .jwt(Customizer.withDefaults())); return http.build(); } diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java index e55d307e33..70b306eaee 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -3,6 +3,7 @@ package com.baeldung.keycloaksoap; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -21,7 +22,8 @@ public class KeycloakSecurityConfig { .disable() .authorizeHttpRequests(auth -> auth.anyRequest() .authenticated()) - .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); + .oauth2ResourceServer((oauth2) -> oauth2 + .jwt(Customizer.withDefaults())); return http.build(); } } From b0a0d8c2475932c6eab0d46ae20294ccfe956e3d Mon Sep 17 00:00:00 2001 From: gaepi Date: Sun, 12 Nov 2023 16:13:39 +0100 Subject: [PATCH 201/283] JAVA-27461 | removing spring security deprecations. --- .../com/baeldung/keycloaksoap/KeycloakSecurityConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java index 70b306eaee..77ffc6a5b4 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.web.SecurityFilterChain; @@ -18,8 +19,7 @@ public class KeycloakSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.csrf() - .disable() + http.csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth.anyRequest() .authenticated()) .oauth2ResourceServer((oauth2) -> oauth2 From aed73f72f5458591646d6bc48747c037ab1f43d9 Mon Sep 17 00:00:00 2001 From: gaepi Date: Sun, 12 Nov 2023 16:13:53 +0100 Subject: [PATCH 202/283] JAVA-27461 | removing spring security deprecations. --- .../java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java index 77ffc6a5b4..ff1cf0cb42 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloaksoap/KeycloakSecurityConfig.java @@ -8,7 +8,6 @@ import org.springframework.security.config.annotation.method.configuration.Enabl import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer; import org.springframework.security.web.SecurityFilterChain; @Configuration From e6cb1a2e43c3c84dbfc1799dda2bb0052f47b2aa Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 17:34:55 +0200 Subject: [PATCH 203/283] [JAVA-26714] Upgraded commons-codec to latest version --- algorithms-modules/pom.xml | 2 +- apache-httpclient4/pom.xml | 2 +- aws-modules/aws-miscellaneous/pom.xml | 2 +- aws-modules/aws-s3/pom.xml | 2 +- core-java-modules/core-java-networking-2/pom.xml | 2 +- core-java-modules/core-java-numbers-6/pom.xml | 2 +- core-java-modules/core-java-security-2/pom.xml | 2 +- core-java-modules/core-java-security-3/pom.xml | 2 +- core-java-modules/core-java-string-operations-2/pom.xml | 2 +- httpclient-simple/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/algorithms-modules/pom.xml b/algorithms-modules/pom.xml index 342662ce9c..fda8eea0e7 100644 --- a/algorithms-modules/pom.xml +++ b/algorithms-modules/pom.xml @@ -28,7 +28,7 @@ - 1.11 + 1.16.0 3.6.1 2.7 1.0.1 diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index f4c213687e..8b2fd76f0e 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -234,7 +234,7 @@ - 1.10 + 1.16.0 4.1.5 2.5.1 diff --git a/aws-modules/aws-miscellaneous/pom.xml b/aws-modules/aws-miscellaneous/pom.xml index 5fdd7fa04d..b6326b6eb1 100644 --- a/aws-modules/aws-miscellaneous/pom.xml +++ b/aws-modules/aws-miscellaneous/pom.xml @@ -75,7 +75,7 @@ 2.10.1 1.21.1 - 1.10.L001 + 1.16.0 0.9.4.0006L 3.1.1 diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index e2bc04964a..6cbdadabae 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -62,7 +62,7 @@ 2.20.52 - 1.10.L001 + 1.16.0 0.9.4.0006L diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 34f16a9938..388e439e37 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -56,7 +56,7 @@ 2.4.5 2.3.3 2.0.0-alpha-3 - 1.15 + 1.16.0 \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 7a3b3d4426..66e16c8030 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -42,7 +42,7 @@ - 1.15 + 1.16.0 32.1.2-jre \ No newline at end of file diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 0fc121c070..05cd727638 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -34,7 +34,7 @@ 1.60 - 1.11 + 1.16.0 2.3.1 diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index b979b56658..4633ba02e3 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -44,7 +44,7 @@ 1.70 - 1.15 + 1.16.0 2.3.1 6.0.3 diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml index 383a3b4a40..27071e5427 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -87,7 +87,7 @@ 8.0.1.Final 5.0.0 - 1.14 + 1.16.0 5.3.0 diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index a6049432ce..8cbc1237c2 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -205,7 +205,7 @@ 17 - 1.10 + 1.16.0 2.5.1 From d1675a28f48eaad3e8690fdab14ce4890d408764 Mon Sep 17 00:00:00 2001 From: gaepi Date: Sun, 12 Nov 2023 16:45:31 +0100 Subject: [PATCH 204/283] JAVA-27461 | removing deprecations. --- spring-reactive-modules/spring-5-reactive/pom.xml | 0 .../webflux/functional/EmployeeFunctionalConfig.java | 9 ++++----- 2 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 spring-reactive-modules/spring-5-reactive/pom.xml diff --git a/spring-reactive-modules/spring-5-reactive/pom.xml b/spring-reactive-modules/spring-5-reactive/pom.xml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java index e6f8ba35c2..7775f61467 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java @@ -53,11 +53,10 @@ public class EmployeeFunctionalConfig { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - http.csrf() - .disable() - .authorizeExchange() - .anyExchange() - .permitAll(); + http.csrf(csrf -> csrf.disable()) + .authorizeExchange( + exchanges -> exchanges.anyExchange().permitAll() + ); return http.build(); } } \ No newline at end of file From fe7f89a08fbadbd8e87f518fc82f243b8cc807db Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 17:46:52 +0200 Subject: [PATCH 205/283] [JAVA-26714] Upgraded bouncycastle to latest version --- core-java-modules/core-java-security-2/pom.xml | 4 ++-- core-java-modules/core-java-security-3/pom.xml | 4 ++-- core-java-modules/core-java-security-4/pom.xml | 4 ++-- libraries-security/pom.xml | 6 +++--- .../oauth2-authorization-server/pom.xml | 11 +++++------ 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 05cd727638..b54afc31d8 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -33,7 +33,7 @@ - 1.60 + 1.76 1.16.0 2.3.1 diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index 4633ba02e3..dae570e51d 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -43,7 +43,7 @@ - 1.70 + 1.76 1.16.0 2.3.1 6.0.3 diff --git a/core-java-modules/core-java-security-4/pom.xml b/core-java-modules/core-java-security-4/pom.xml index 2b9809b749..a4700c34ba 100644 --- a/core-java-modules/core-java-security-4/pom.xml +++ b/core-java-modules/core-java-security-4/pom.xml @@ -16,7 +16,7 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} @@ -27,7 +27,7 @@ - 1.70 + 1.76 1.2.6 diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 62c476a82c..969f14ec43 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -40,12 +40,12 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} @@ -122,7 +122,7 @@ 1.2.2 1.2.2 1.9.2 - 1.58 + 1.76 0.1.55 2.5.1 2.4.0.RELEASE diff --git a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml index 7f13e5acea..1ebbb5e10f 100644 --- a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml +++ b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml @@ -21,13 +21,13 @@ org.bouncycastle - bcprov-jdk15on - ${bcprov-jdk15on.version} + bcprov-jdk18on + ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on - ${bcpkix-jdk15on.version} + bcpkix-jdk18on + ${bouncycastle.version} @@ -69,8 +69,7 @@ 9080 9443 7.3 - 1.62 - 1.62 + 1.76 \ No newline at end of file From c0a9532c647bfee5f6a68d6e4550636940cbd4de Mon Sep 17 00:00:00 2001 From: Lucian Snare Date: Sun, 12 Nov 2023 10:59:00 -0500 Subject: [PATCH 206/283] BAEL-6790: Write and Read file with HashMap (#15087) * Add examples for reading and writing a HashMap from a file * Add test for gson --- .../core-java-collections-maps-7/README.md | 4 +- .../core-java-collections-maps-7/pom.xml | 65 ++------- .../map/readandwritefile/Student.java | 51 +++++++ .../ReadAndWriteFileWithHashMapUnitTest.java | 135 ++++++++++++++++++ 4 files changed, 199 insertions(+), 56 deletions(-) create mode 100644 core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java create mode 100644 core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 2e1531050e..a62bdda7af 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -1,5 +1,7 @@ -## Relevant Articles +## Relevant Articles: - [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) +- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/how-to-write-and-read-a-file-with-a-java-hashmap/) - [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) - [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair) - [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file) +- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6) \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-7/pom.xml b/core-java-modules/core-java-collections-maps-7/pom.xml index cefee201cc..a7acded9cf 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -1,11 +1,15 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-maps-7 core-java-collections-maps-7 jar + + 2.10.1 + 1.5 + core-java-modules @@ -13,72 +17,24 @@ 0.0.1-SNAPSHOT - - 5.2.5.RELEASE - com.fasterxml.jackson.core jackson-databind - 2.12.4 - - - org.openjdk.jmh - jmh-core - 1.36 + ${jackson.version} com.google.code.gson gson - 2.8.9 - - - org.json - json - 20230227 - - - junit - junit - 4.13.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - junit - junit - 4.13.1 - test - - - org.junit.jupiter - junit-jupiter - 5.8.1 - test - - - junit - junit - 4.13.1 - test + ${gson.version} org.apache.commons commons-csv - 1.5 + ${csv.version} + @@ -92,5 +48,4 @@ - diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java new file mode 100644 index 0000000000..b981de6300 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/readandwritefile/Student.java @@ -0,0 +1,51 @@ +package com.baeldung.map.readandwritefile; + +import java.io.Serializable; +import java.util.Objects; + +public class Student implements Serializable { + private static final long serialVersionUID = 1L; + private String firstName; + private String lastName; + + /** Default constructor for JSON serialization */ + public Student() { + + } + + public Student(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Student student = (Student) o; + return Objects.equals(firstName, student.firstName) && Objects.equals(lastName, student.lastName); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java new file mode 100644 index 0000000000..56867d3885 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/readandwritefile/ReadAndWriteFileWithHashMapUnitTest.java @@ -0,0 +1,135 @@ +package com.baeldung.map.readandwritefile; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.junit.After; +import org.junit.Test; +import org.junit.Before; + +public class ReadAndWriteFileWithHashMapUnitTest { + + private static final Map STUDENT_DATA = new HashMap<>(); + + static { + STUDENT_DATA.put(1234, new Student("Henry", "Winter")); + STUDENT_DATA.put(5678, new Student("Richard", "Papen")); + } + + private File file; + + @Before + public void createFile() throws IOException { + file = File.createTempFile("student", ".data"); + } + + @After + public void deleteFile() { + file.delete(); + } + + @Test + public void givenHashMap_whenWrittenAsPropertiesFile_thenReloadedMapIsIdentical() throws IOException { + // Given a map containing student data + Map studentData = new HashMap<>(); + studentData.put("student.firstName", "Henry"); + studentData.put("student.lastName", "Winter"); + + // When converting to a Properties object and writing to a file + Properties props = new Properties(); + props.putAll(studentData); + try (OutputStream output = Files.newOutputStream(file.toPath())) { + props.store(output, null); + } + + // Then the map resulting from loading the Properties file is identical + Properties propsFromFile = new Properties(); + try (InputStream input = Files.newInputStream(file.toPath())) { + propsFromFile.load(input); + } + + Map studentDataFromProps = propsFromFile.stringPropertyNames() + .stream() + .collect(Collectors.toMap(key -> key, props::getProperty)); + assertThat(studentDataFromProps).isEqualTo(studentData); + } + + @Test + public void givenHashMap_whenSerializedToFile_thenDeserializedMapIsIdentical() throws IOException, ClassNotFoundException { + // Given a map containing student data (STUDENT_DATA) + + // When serializing the map to a file + try (FileOutputStream fileOutput = new FileOutputStream(file); ObjectOutputStream objectStream = new ObjectOutputStream(fileOutput)) { + objectStream.writeObject(STUDENT_DATA); + } + + // Then read the file back into a map and check the contents + Map studentsFromFile; + try (FileInputStream fileReader = new FileInputStream(file); ObjectInputStream objectStream = new ObjectInputStream(fileReader)) { + studentsFromFile = (HashMap) objectStream.readObject(); + } + assertThat(studentsFromFile).isEqualTo(STUDENT_DATA); + } + + @Test + public void givenHashMap_whenSerializedToFileWithJackson_thenDeserializedMapIsIdentical() throws IOException { + // Given a map containing student data (STUDENT_DATA) + + // When converting to JSON with Jackson and writing to a file + ObjectMapper mapper = new ObjectMapper(); + try (FileOutputStream fileOutput = new FileOutputStream(file)) { + mapper.writeValue(fileOutput, STUDENT_DATA); + } + + // Then deserialize the file back into a map and check that it's identical + Map mapFromFile; + try (FileInputStream fileInput = new FileInputStream(file)) { + // Create a TypeReference so we can deserialize the parameterized type + TypeReference> mapType = new TypeReference>() { + }; + mapFromFile = mapper.readValue(fileInput, mapType); + } + assertThat(mapFromFile).isEqualTo(STUDENT_DATA); + } + + @Test + public void givenHashMap_whenSerializedToFileWithGson_thenDeserializedMapIsIdentical() throws IOException { + // Given a map containing student data (STUDENT_DATA) + + // When converting to JSON using Gson and writing to a file + Gson gson = new Gson(); + try (FileWriter writer = new FileWriter(file)) { + gson.toJson(STUDENT_DATA, writer); + } + + // Then deserialize the file back into a map and check that it's identical + Map studentsFromFile; + try (FileReader reader = new FileReader(file)) { + Type mapType = new TypeToken>() { + }.getType(); + studentsFromFile = gson.fromJson(reader, mapType); + } + assertThat(studentsFromFile).isEqualTo(STUDENT_DATA); + } +} From 2c7a0d05e2a823cc74889d9e3ced74538f7c0bf0 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:00:46 +0200 Subject: [PATCH 207/283] [JAVA-26714] Clean up of commons-lang3 --- core-java-modules/core-java-collections-4/pom.xml | 1 - core-java-modules/core-java-collections-list-5/pom.xml | 1 - core-java-modules/core-java-date-operations-3/pom.xml | 1 - core-java-modules/core-java-function/pom.xml | 1 - core-java-modules/core-java-functional/pom.xml | 1 - core-java-modules/core-java-lang-5/pom.xml | 1 - core-java-modules/core-java-reflection/pom.xml | 1 - core-java-modules/core-java-string-algorithms-3/pom.xml | 1 - core-java-modules/core-java-string-operations-3/pom.xml | 1 - core-java-modules/core-java-string-operations-4/pom.xml | 7 +++---- 10 files changed, 3 insertions(+), 13 deletions(-) diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index 1a59411ecb..344ec6bc41 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -34,7 +34,6 @@ 2.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-5/pom.xml b/core-java-modules/core-java-collections-list-5/pom.xml index 2b4b0041b3..b8832df357 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -66,7 +66,6 @@ 1.21 2.2 - 3.12.0 2.10.1 2.15.2 20230618 diff --git a/core-java-modules/core-java-date-operations-3/pom.xml b/core-java-modules/core-java-date-operations-3/pom.xml index 9b7be18b85..8e4740785c 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -28,7 +28,6 @@ 2.12.5 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml index e8b538ad24..4110b8f6d9 100644 --- a/core-java-modules/core-java-function/pom.xml +++ b/core-java-modules/core-java-function/pom.xml @@ -51,7 +51,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml index 4b0bf9f730..3b21dd6e8a 100644 --- a/core-java-modules/core-java-functional/pom.xml +++ b/core-java-modules/core-java-functional/pom.xml @@ -35,7 +35,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml index 8e95fc4405..b65f061fc7 100644 --- a/core-java-modules/core-java-lang-5/pom.xml +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -24,7 +24,6 @@ - 3.12.0 0.10.2 diff --git a/core-java-modules/core-java-reflection/pom.xml b/core-java-modules/core-java-reflection/pom.xml index a836ee4a22..f77c791936 100644 --- a/core-java-modules/core-java-reflection/pom.xml +++ b/core-java-modules/core-java-reflection/pom.xml @@ -52,7 +52,6 @@ 1.8 1.8 0.10.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 507e830e8a..c47967a29f 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -61,7 +61,6 @@ 11 11 1.7 - 3.12.0 5.1.1 1.10.0 diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 39167271fa..7795d164a1 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -70,7 +70,6 @@ 11 11 5.3.9 - 3.12.0 3.6.3 6.1.1 2.11.1 diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index 27c2bf91bd..b9591763a0 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -27,12 +27,12 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} + ${commons-lang3.version} org.apache.commons commons-text - ${apache-commons-text.version} + ${commons-text.version} org.assertj @@ -60,8 +60,7 @@ 11 5.8 5.3.13 - 3.12.0 - 1.10.0 + 1.10.0 \ No newline at end of file From 573df300b06ea130e8d4762c71f4072ab0cfd81c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 12 Nov 2023 09:00:56 -0700 Subject: [PATCH 208/283] Fix indentation issues --- .../atomicinteger/Employee.java | 3 +- .../synchronizestatic/none/Employee.java | 3 +- .../reentrantlock/Employee.java | 3 +- .../synchronizedblock/Employee.java | 3 +- .../synchronizedclass/Employee.java | 3 +- .../SychronizeStaticDataUnitTest.java | 38 ++++++++----------- 6 files changed, 21 insertions(+), 32 deletions(-) diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java index 9c3c9b987c..bb7c1c6b4c 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/atomicinteger/Employee.java @@ -13,8 +13,7 @@ public class Employee { String name; String title; - public Employee(int id, String name, String title) - { + public Employee(int id, String name, String title) { incrementCount(); this.id = id; this.name = name; diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java index f050a68be4..ba722e15e9 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/none/Employee.java @@ -10,8 +10,7 @@ public class Employee { String name; String title; - public Employee(int id, String name, String title) - { + public Employee(int id, String name, String title) { incrementCount(); this.id = id; this.name = name; diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java index 2ac0b0d3f2..e74013ad0e 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/reentrantlock/Employee.java @@ -14,8 +14,7 @@ public class Employee { String name; String title; - public Employee(int id, String name, String title) - { + public Employee(int id, String name, String title) { incrementCount(); this.id = id; this.name = name; diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java index 9c078e7abe..4cf04e5b06 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedblock/Employee.java @@ -12,8 +12,7 @@ public class Employee { String name; String title; - public Employee(int id, String name, String title) - { + public Employee(int id, String name, String title) { incrementCount(); this.id = id; this.name = name; diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java index a69b633f3b..627040e88c 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/synchronizestatic/synchronizedclass/Employee.java @@ -10,8 +10,7 @@ public class Employee String name; String title; - public Employee(int id, String name, String title) - { + public Employee(int id, String name, String title) { incrementCount(); this.id = id; this.name = name; diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java index e633005c6f..b4e03673a1 100644 --- a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/synchronizestatic/SychronizeStaticDataUnitTest.java @@ -11,8 +11,7 @@ import java.util.concurrent.Executors; * package. When not synchronized the out will not be sequential; * when it is synchronized the output will be in sequential. */ -public class SychronizeStaticDataUnitTest -{ +public class SychronizeStaticDataUnitTest { private final Executor pool = Executors.newFixedThreadPool(4); private final int numberToTest = 100; @@ -24,10 +23,9 @@ public class SychronizeStaticDataUnitTest for(int i = 0; i < numberToTest; i++) { int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith"); - }); + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.none.Employee(finalI, "John", "Smith"); + }); } } @@ -38,10 +36,9 @@ public class SychronizeStaticDataUnitTest for(int i = 0; i < numberToTest; i++) { int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith"); - }); + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedmethod.Employee(finalI, "John", "Smith"); + }); } } @@ -52,10 +49,9 @@ public class SychronizeStaticDataUnitTest for(int i = 0; i < numberToTest; i++) { int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith"); - }); + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedclass.Employee(finalI, "John", "Smith"); + }); } } @@ -66,10 +62,9 @@ public class SychronizeStaticDataUnitTest for(int i = 0; i < numberToTest; i++) { int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith"); - }); + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.synchronizedblock.Employee(finalI, "John", "Smith"); + }); } } @@ -87,10 +82,9 @@ public class SychronizeStaticDataUnitTest for(int i = 0; i < numberToTest; i++) { int finalI = i; - pool.execute(() -> - { - new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith"); - }); + pool.execute(() -> { + new com.baeldung.concurrent.synchronizestatic.reentrantlock.Employee(finalI, "John", "Smith"); + }); } } } From daea7e1edc1f746e4c1a1a3afc3c6ba5637a7033 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:03:56 +0200 Subject: [PATCH 209/283] [JAVA-26714] Revert typo --- aws-modules/aws-s3/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index 6cbdadabae..e2bc04964a 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -62,7 +62,7 @@ 2.20.52 - 1.16.0 + 1.10.L001 0.9.4.0006L From 39c2f491713a429cd5f9c5b3b45eb62165ed0a0e Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:10:31 +0200 Subject: [PATCH 210/283] [JAVA-26714] Upgraded guava to latest version --- core-java-modules/core-java-numbers-6/pom.xml | 1 - core-java-modules/core-java-streams-5/pom.xml | 1 - docker-modules/docker-caching/multi-module-caching/pom.xml | 2 +- docker-modules/docker-caching/single-module-caching/pom.xml | 2 +- json-modules/json-conversion/pom.xml | 1 - pom.xml | 2 +- spring-web-modules/spring-rest-http-2/pom.xml | 1 - 7 files changed, 3 insertions(+), 7 deletions(-) diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 66e16c8030..34e53056a4 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -43,6 +43,5 @@ 1.16.0 - 32.1.2-jre \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/pom.xml b/core-java-modules/core-java-streams-5/pom.xml index d7baf84d30..e217271f4c 100644 --- a/core-java-modules/core-java-streams-5/pom.xml +++ b/core-java-modules/core-java-streams-5/pom.xml @@ -77,7 +77,6 @@ 12 12 0.10.2 - 32.1.2-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index 60f14a17e5..bebfb85e8a 100644 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/pom.xml @@ -27,7 +27,7 @@ UTF-8 1.8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml index 0e5174b7ca..bb44c21e10 100644 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ b/docker-modules/docker-caching/single-module-caching/pom.xml @@ -49,7 +49,7 @@ 8 8 UTF-8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/json-modules/json-conversion/pom.xml b/json-modules/json-conversion/pom.xml index 638216f4c5..9eebac16b4 100644 --- a/json-modules/json-conversion/pom.xml +++ b/json-modules/json-conversion/pom.xml @@ -38,7 +38,6 @@ 2.10.1 - 32.1.2-jre diff --git a/pom.xml b/pom.xml index 47c566023d..7099dd8cbc 100644 --- a/pom.xml +++ b/pom.xml @@ -1236,7 +1236,7 @@ 3.21.0 1.18.28 2.1.214 - 32.1.2-jre + 32.1.3-jre 3.3.0 diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index 88294c7811..bcacdbbdb1 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -53,7 +53,6 @@ 2.9.2 1.6.1 1.7.0 - 31.0.1-jre \ No newline at end of file From ffe2c5780ebad433ca55f67e5b53f5251b9e8f3e Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Mon, 13 Nov 2023 12:05:47 +0530 Subject: [PATCH 211/283] JAVA-27194 Upgarde hibernate validator version in spring-mvc-java --- spring-web-modules/spring-mvc-java/pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index 8098f07282..745a6f45c0 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -101,7 +101,6 @@ org.hibernate.validator hibernate-validator - ${hibernate-validator.version} org.glassfish @@ -217,8 +216,6 @@ 6.0.10.Final 5.1.40 - - 6.0.10.Final 2.2.0 From 7465581d605e220bb4064d2b62d3f892ab4c8c28 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 09:44:21 +0200 Subject: [PATCH 212/283] [JAVA-26714] --- core-java-modules/core-java-string-algorithms-3/pom.xml | 1 - core-java-modules/core-java-string-operations-3/pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index c47967a29f..96bb824f84 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -21,7 +21,6 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} com.vdurmont diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 7795d164a1..ce58669ba0 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -22,7 +22,6 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} org.apache.maven From 0415bc0ec7093073f1fe4960dbc491ef2733ed11 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 09:48:20 +0200 Subject: [PATCH 213/283] [JAVA-26714] --- core-java-modules/core-java-string-algorithms-3/pom.xml | 1 + core-java-modules/core-java-string-operations-3/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 96bb824f84..548a3dc3f8 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -21,6 +21,7 @@ org.apache.commons commons-lang3 + ${commons-lang3.version} com.vdurmont diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index ce58669ba0..0558e71a35 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -22,6 +22,7 @@ org.apache.commons commons-lang3 + ${commons-lang3.version} org.apache.maven From 72391c6947feb37c1bf2783a57e7fe5ed9c7d246 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Mon, 13 Nov 2023 14:52:49 +0530 Subject: [PATCH 214/283] JAVA-27194 Upgrade hibernate validator version in spring-mvc-xml-2 --- spring-web-modules/spring-mvc-xml-2/pom.xml | 29 ++++++++----------- .../ConstraintViolationExceptionHandler.java | 2 +- ...stAndPathVariableValidationController.java | 10 +++---- .../baeldung/spring/taglibrary/Person.java | 2 +- .../spring/taglibrary/PersonController.java | 2 +- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/spring-web-modules/spring-mvc-xml-2/pom.xml b/spring-web-modules/spring-mvc-xml-2/pom.xml index 8c0062f538..49590758cc 100644 --- a/spring-web-modules/spring-mvc-xml-2/pom.xml +++ b/spring-web-modules/spring-mvc-xml-2/pom.xml @@ -10,8 +10,9 @@ com.baeldung - spring-web-modules + parent-spring-6 0.0.1-SNAPSHOT + ../../parent-spring-6 @@ -19,26 +20,18 @@ org.springframework spring-web - ${spring.version} org.springframework spring-webmvc - ${spring.version} - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet-api.version} provided - - javax.servlet - jstl - ${jstl.version} - runtime - org.hibernate.validator hibernate-validator @@ -57,9 +50,9 @@ ${commons-io.version} - org.glassfish - javax.el - ${javax.el.version} + org.glassfish.expressly + expressly + ${expressly.version} org.springframework.boot @@ -98,9 +91,11 @@ 5.1.40 4.4.5 4.5.2 - 6.0.10.Final - 3.0.1-b08 + 8.0.1.Final + 5.0.0 1.6.1 + 6.0.0 + 3.1.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java index 645b36c2a5..d3d833a696 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java @@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolationException; @ControllerAdvice public class ConstraintViolationExceptionHandler extends ResponseEntityExceptionHandler { diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java index 4768237871..e1842564ac 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/paramsvalidation/RequestAndPathVariableValidationController.java @@ -7,11 +7,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; @Controller @RequestMapping("/public/api/1") diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java index ed2fa903ef..a08f0f515c 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/Person.java @@ -2,7 +2,7 @@ package com.baeldung.spring.taglibrary; import java.util.List; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import org.springframework.web.multipart.MultipartFile; diff --git a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java index 0fcb66f2dd..79e65b1fde 100644 --- a/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java +++ b/spring-web-modules/spring-mvc-xml-2/src/main/java/com/baeldung/spring/taglibrary/PersonController.java @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; From 7d0c744c7c89d845b32cc4609fa98e40d876e2fd Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:27:36 +0000 Subject: [PATCH 215/283] [JAVA-26433] Formatting (#15179) --- .../collectors/Java8CollectorsUnitTest.java | 155 ++++++++++-------- 1 file changed, 91 insertions(+), 64 deletions(-) diff --git a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java index 085c1b5d7f..1faada9d23 100644 --- a/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java +++ b/core-java-modules/core-java-streams-simple/src/test/java/com/baeldung/streams/collectors/Java8CollectorsUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.streams.collectors; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; + import org.junit.Test; import java.util.*; @@ -23,142 +24,159 @@ public class Java8CollectorsUnitTest { private final List listWithDuplicates = Arrays.asList("a", "bb", "c", "d", "bb"); @Test - public void whenCollectingToList_shouldCollectToList() throws Exception { - final List result = givenList.stream().collect(toList()); + public void whenCollectingToList_shouldCollectToList() { + final List result = givenList.stream() + .collect(toList()); assertThat(result).containsAll(givenList); } @Test public void whenCollectingToUnmodifiableList_shouldCollectToUnmodifiableList() { - final List result = givenList.stream().collect(toUnmodifiableList()); + final List result = givenList.stream() + .collect(toUnmodifiableList()); - assertThatThrownBy(() -> result.add("foo")) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.add("foo")).isInstanceOf(UnsupportedOperationException.class); } @Test - public void whenCollectingToSet_shouldCollectToSet() throws Exception { - final Set result = givenList.stream().collect(toSet()); + public void whenCollectingToSet_shouldCollectToSet() { + final Set result = givenList.stream() + .collect(toSet()); assertThat(result).containsAll(givenList); } @Test public void whenCollectingToUnmodifiableSet_shouldCollectToUnmodifiableSet() { - final Set result = givenList.stream().collect(toUnmodifiableSet()); + final Set result = givenList.stream() + .collect(toUnmodifiableSet()); - assertThatThrownBy(() -> result.add("foo")) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.add("foo")).isInstanceOf(UnsupportedOperationException.class); } @Test public void givenContainsDuplicateElements_whenCollectingToSet_shouldAddDuplicateElementsOnlyOnce() throws Exception { - final Set result = listWithDuplicates.stream().collect(toSet()); + final Set result = listWithDuplicates.stream() + .collect(toSet()); assertThat(result).hasSize(4); } @Test - public void whenCollectingToCollection_shouldCollectToCollection() throws Exception { - final List result = givenList.stream().collect(toCollection(LinkedList::new)); + public void whenCollectingToCollection_shouldCollectToCollection() { + final List result = givenList.stream() + .collect(toCollection(LinkedList::new)); - assertThat(result).containsAll(givenList).isInstanceOf(LinkedList.class); + assertThat(result).containsAll(givenList) + .isInstanceOf(LinkedList.class); } @Test - public void whenCollectingToImmutableCollection_shouldThrowException() throws Exception { + public void whenCollectingToImmutableCollection_shouldThrowException() { assertThatThrownBy(() -> { - givenList.stream().collect(toCollection(ImmutableList::of)); + givenList.stream() + .collect(toCollection(ImmutableList::of)); }).isInstanceOf(UnsupportedOperationException.class); } @Test - public void whenCollectingToMap_shouldCollectToMap() throws Exception { - final Map result = givenList.stream().collect(toMap(Function.identity(), String::length)); + public void whenCollectingToMap_shouldCollectToMap() { + final Map result = givenList.stream() + .collect(toMap(Function.identity(), String::length)); - assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); + assertThat(result).containsEntry("a", 1) + .containsEntry("bb", 2) + .containsEntry("ccc", 3) + .containsEntry("dd", 2); } @Test public void whenCollectingToUnmodifiableMap_shouldCollectToUnmodifiableMap() { final Map result = givenList.stream() - .collect(toUnmodifiableMap(Function.identity(), String::length)); + .collect(toUnmodifiableMap(Function.identity(), String::length)); - assertThatThrownBy(() -> result.put("foo", 3)) - .isInstanceOf(UnsupportedOperationException.class); + assertThatThrownBy(() -> result.put("foo", 3)).isInstanceOf(UnsupportedOperationException.class); } @Test public void whenCollectingToMapwWithDuplicates_shouldCollectToMapMergingTheIdenticalItems() throws Exception { - final Map result = listWithDuplicates.stream().collect( - toMap( - Function.identity(), - String::length, - (item, identicalItem) -> item - ) - ); + final Map result = listWithDuplicates.stream() + .collect(toMap(Function.identity(), String::length, (item, identicalItem) -> item)); - assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("c", 1).containsEntry("d", 1); + assertThat(result).containsEntry("a", 1) + .containsEntry("bb", 2) + .containsEntry("c", 1) + .containsEntry("d", 1); } @Test - public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() throws Exception { + public void givenContainsDuplicateElements_whenCollectingToMap_shouldThrowException() { assertThatThrownBy(() -> { - listWithDuplicates.stream().collect(toMap(Function.identity(), String::length)); + listWithDuplicates.stream() + .collect(toMap(Function.identity(), String::length)); }).isInstanceOf(IllegalStateException.class); } @Test - public void whenCollectingAndThen_shouldCollect() throws Exception { - final List result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf)); + public void whenCollectingAndThen_shouldCollect() { + final List result = givenList.stream() + .collect(collectingAndThen(toList(), ImmutableList::copyOf)); - assertThat(result).containsAll(givenList).isInstanceOf(ImmutableList.class); + assertThat(result).containsAll(givenList) + .isInstanceOf(ImmutableList.class); } @Test - public void whenJoining_shouldJoin() throws Exception { - final String result = givenList.stream().collect(joining()); + public void whenJoining_shouldJoin() { + final String result = givenList.stream() + .collect(joining()); assertThat(result).isEqualTo("abbcccdd"); } @Test - public void whenJoiningWithSeparator_shouldJoinWithSeparator() throws Exception { - final String result = givenList.stream().collect(joining(" ")); + public void whenJoiningWithSeparator_shouldJoinWithSeparator() { + final String result = givenList.stream() + .collect(joining(" ")); assertThat(result).isEqualTo("a bb ccc dd"); } @Test - public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() throws Exception { - final String result = givenList.stream().collect(joining(" ", "PRE-", "-POST")); + public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() { + final String result = givenList.stream() + .collect(joining(" ", "PRE-", "-POST")); assertThat(result).isEqualTo("PRE-a bb ccc dd-POST"); } @Test - public void whenPartitioningBy_shouldPartition() throws Exception { - final Map> result = givenList.stream().collect(partitioningBy(s -> s.length() > 2)); + public void whenPartitioningBy_shouldPartition() { + final Map> result = givenList.stream() + .collect(partitioningBy(s -> s.length() > 2)); - assertThat(result).containsKeys(true, false).satisfies(booleanListMap -> { - assertThat(booleanListMap.get(true)).contains("ccc"); + assertThat(result).containsKeys(true, false) + .satisfies(booleanListMap -> { + assertThat(booleanListMap.get(true)).contains("ccc"); - assertThat(booleanListMap.get(false)).contains("a", "bb", "dd"); - }); + assertThat(booleanListMap.get(false)).contains("a", "bb", "dd"); + }); } @Test - public void whenCounting_shouldCount() throws Exception { - final Long result = givenList.stream().collect(counting()); + public void whenCounting_shouldCount() { + final Long result = givenList.stream() + .collect(counting()); assertThat(result).isEqualTo(4); } @Test - public void whenSummarizing_shouldSummarize() throws Exception { - final DoubleSummaryStatistics result = givenList.stream().collect(summarizingDouble(String::length)); + public void whenSummarizing_shouldSummarize() { + final DoubleSummaryStatistics result = givenList.stream() + .collect(summarizingDouble(String::length)); assertThat(result.getAverage()).isEqualTo(2); assertThat(result.getCount()).isEqualTo(4); @@ -168,38 +186,47 @@ public class Java8CollectorsUnitTest { } @Test - public void whenAveraging_shouldAverage() throws Exception { - final Double result = givenList.stream().collect(averagingDouble(String::length)); + public void whenAveraging_shouldAverage() { + final Double result = givenList.stream() + .collect(averagingDouble(String::length)); assertThat(result).isEqualTo(2); } @Test - public void whenSumming_shouldSum() throws Exception { - final Double result = givenList.stream().filter(i -> true).collect(summingDouble(String::length)); + public void whenSumming_shouldSum() { + final Double result = givenList.stream() + .collect(summingDouble(String::length)); assertThat(result).isEqualTo(8); } @Test - public void whenMaxingBy_shouldMaxBy() throws Exception { - final Optional result = givenList.stream().collect(maxBy(Comparator.naturalOrder())); + public void whenMaxingBy_shouldMaxBy() { + final Optional result = givenList.stream() + .collect(maxBy(Comparator.naturalOrder())); - assertThat(result).isPresent().hasValue("dd"); + assertThat(result).isPresent() + .hasValue("dd"); } @Test - public void whenGroupingBy_shouldGroupBy() throws Exception { - final Map> result = givenList.stream().collect(groupingBy(String::length, toSet())); + public void whenGroupingBy_shouldGroupBy() { + final Map> result = givenList.stream() + .collect(groupingBy(String::length, toSet())); - assertThat(result).containsEntry(1, newHashSet("a")).containsEntry(2, newHashSet("bb", "dd")).containsEntry(3, newHashSet("ccc")); + assertThat(result).containsEntry(1, newHashSet("a")) + .containsEntry(2, newHashSet("bb", "dd")) + .containsEntry(3, newHashSet("ccc")); } @Test - public void whenCreatingCustomCollector_shouldCollect() throws Exception { - final ImmutableSet result = givenList.stream().collect(toImmutableSet()); + public void whenCreatingCustomCollector_shouldCollect() { + final ImmutableSet result = givenList.stream() + .collect(toImmutableSet()); - assertThat(result).isInstanceOf(ImmutableSet.class).contains("a", "bb", "ccc", "dd"); + assertThat(result).isInstanceOf(ImmutableSet.class) + .contains("a", "bb", "ccc", "dd"); } From e82269d2069859be8ef9e1b253c5b95b7d34256e Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Mon, 13 Nov 2023 15:02:17 +0530 Subject: [PATCH 216/283] JAVA-27224 Upgrade parent-boot-3 to latest version of Boot (#15188) --- parent-boot-3/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent-boot-3/pom.xml b/parent-boot-3/pom.xml index dabcd7850b..9f9d6f7901 100644 --- a/parent-boot-3/pom.xml +++ b/parent-boot-3/pom.xml @@ -230,7 +230,7 @@ 3.3.0 2.22.2 - 3.1.2 + 3.1.5 5.8.2 0.9.17 17 From 5040974af23bf29aec2fafb44ff94af538b7e026 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 11:48:01 +0200 Subject: [PATCH 217/283] [JAVA-26714] --- libraries-security/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 969f14ec43..8a6dad6da2 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -40,12 +40,12 @@ org.bouncycastle - bcprov-jdk18on + bcprov-jdk15on ${bouncycastle.version} org.bouncycastle - bcpkix-jdk18on + bcpkix-jdk15on ${bouncycastle.version} @@ -122,7 +122,7 @@ 1.2.2 1.2.2 1.9.2 - 1.76 + 1.68 0.1.55 2.5.1 2.4.0.RELEASE From 21eb70547f10f84ac1be2b903f8a6d00742253ff Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 13 Nov 2023 10:00:45 +0000 Subject: [PATCH 218/283] [JAVA-26719] Upgraded joda-time to latest version (#15189) --- .../core-java-8-datetime-2/pom.xml | 2 +- .../parsingDates/SimpleParseDate.java | 2 +- .../parsingDates/SimpleParseDateUnitTest.java | 42 +++++++++---------- .../core-java-8-datetime/pom.xml | 2 +- .../core-java-date-operations-1/pom.xml | 2 +- .../core-java-date-operations-2/pom.xml | 2 +- .../core-java-datetime-conversion/pom.xml | 2 +- json-modules/gson/pom.xml | 2 +- .../spring-data-couchbase-2/pom.xml | 2 +- spring-ejb-modules/ejb-beans/pom.xml | 2 +- spring-static-resources/pom.xml | 7 ---- testing-modules/rest-assured/pom.xml | 6 --- video-tutorials/jackson-annotations/pom.xml | 2 +- 13 files changed, 30 insertions(+), 45 deletions(-) diff --git a/core-java-modules/core-java-8-datetime-2/pom.xml b/core-java-modules/core-java-8-datetime-2/pom.xml index ce349d9dc3..02af06dc9d 100644 --- a/core-java-modules/core-java-8-datetime-2/pom.xml +++ b/core-java-modules/core-java-8-datetime-2/pom.xml @@ -55,7 +55,7 @@ 1.8 1.8 - 2.10 + 2.12.5 \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java index cb024eea53..ba4f14ec5f 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/parsingDates/SimpleParseDate.java @@ -7,7 +7,7 @@ import java.util.List; public class SimpleParseDate { - public Date parseDate(String dateString, List formatStrings) { + public static Date parseDate(String dateString, List formatStrings) { for (String formatString : formatStrings) { try { return new SimpleDateFormat(formatString).parse(dateString); diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java index d7cbb6a834..ed8607fd96 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/parsingDates/SimpleParseDateUnitTest.java @@ -1,43 +1,41 @@ package com.baeldung.parsingDates; -import com.baeldung.parsingDates.SimpleDateTimeFormat; -import com.baeldung.parsingDates.SimpleDateTimeFormater; -import com.baeldung.parsingDates.SimpleDateUtils; -import com.baeldung.parsingDates.SimpleParseDate; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.time.format.DateTimeParseException; import java.util.Arrays; -import org.junit.*; -import static org.junit.Assert.*; + import org.joda.time.LocalDate; +import org.junit.jupiter.api.Test; -public class SimpleParseDateUnitTest { +class SimpleParseDateUnitTest { @Test - public void whenInvalidInput_thenGettingUnexpectedResult() { - SimpleParseDate simpleParseDate = new SimpleParseDate(); + void whenInvalidInput_thenGettingUnexpectedResult() { String date = "2022-40-40"; - assertEquals("Sat May 10 00:00:00 UTC 2025", simpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")).toString()); + assertEquals("Sat May 10 00:00:00 UTC 2025", SimpleParseDate.parseDate(date, Arrays.asList("MM/dd/yyyy", "dd.MM.yyyy", "yyyy-MM-dd")) + .toString()); } @Test - public void whenInvalidDate_thenAssertThrows() { - SimpleDateTimeFormater simpleDateTimeFormater = new SimpleDateTimeFormater(); - assertEquals(java.time.LocalDate.parse("2022-12-04"), simpleDateTimeFormater.parseDate("2022-12-04")); - assertThrows(DateTimeParseException.class, () -> simpleDateTimeFormater.parseDate("2022-13-04")); + void whenInvalidDate_thenAssertThrows() { + assertEquals(java.time.LocalDate.parse("2022-12-04"), SimpleDateTimeFormater.parseDate("2022-12-04")); + assertThrows(DateTimeParseException.class, () -> SimpleDateTimeFormater.parseDate("2022-13-04")); } @Test - public void whenDateIsCorrect_thenParseCorrect() { - SimpleDateUtils simpleDateUtils = new SimpleDateUtils(); - assertNull(simpleDateUtils.parseDate("53/10/2014")); - assertEquals("Wed Sep 10 00:00:00 UTC 2014", simpleDateUtils.parseDate("10/09/2014").toString()); + void whenDateIsCorrect_thenParseCorrect() { + assertNull(SimpleDateUtils.parseDate("53/10/2014")); + assertEquals("Wed Sep 10 00:00:00 UTC 2014", SimpleDateUtils.parseDate("10/09/2014") + .toString()); } @Test - public void whenDateIsCorrect_thenResultCorrect() { - SimpleDateTimeFormat simpleDateTimeFormat = new SimpleDateTimeFormat(); - assertNull(simpleDateTimeFormat.parseDate("53/10/2014")); - assertEquals(LocalDate.parse("2014-10-10"), simpleDateTimeFormat.parseDate("2014-10-10")); + void whenDateIsCorrect_thenResultCorrect() { + assertNull(SimpleDateTimeFormat.parseDate("53/10/2014")); + assertEquals(LocalDate.parse("2014-10-10"), SimpleDateTimeFormat.parseDate("2014-10-10")); } } diff --git a/core-java-modules/core-java-8-datetime/pom.xml b/core-java-modules/core-java-8-datetime/pom.xml index 481b1a6a69..06ecc3d017 100644 --- a/core-java-modules/core-java-8-datetime/pom.xml +++ b/core-java-modules/core-java-8-datetime/pom.xml @@ -56,7 +56,7 @@ 1.8 1.8 - 2.10 + 2.12.5 \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-1/pom.xml b/core-java-modules/core-java-date-operations-1/pom.xml index 5bfbb5bab0..3d7335c86e 100644 --- a/core-java-modules/core-java-date-operations-1/pom.xml +++ b/core-java-modules/core-java-date-operations-1/pom.xml @@ -54,7 +54,7 @@ - 2.10 + 2.12.5 RELEASE 1.9 1.9 diff --git a/core-java-modules/core-java-date-operations-2/pom.xml b/core-java-modules/core-java-date-operations-2/pom.xml index c6a22a4166..86fbbf614e 100644 --- a/core-java-modules/core-java-date-operations-2/pom.xml +++ b/core-java-modules/core-java-date-operations-2/pom.xml @@ -47,7 +47,7 @@ - 2.10 + 2.12.5 1.5.1 3.2.7.Final 5.9 diff --git a/core-java-modules/core-java-datetime-conversion/pom.xml b/core-java-modules/core-java-datetime-conversion/pom.xml index 3ff26323df..8e148edaad 100644 --- a/core-java-modules/core-java-datetime-conversion/pom.xml +++ b/core-java-modules/core-java-datetime-conversion/pom.xml @@ -54,7 +54,7 @@ - 2.10 + 2.12.5 1.9 1.9 diff --git a/json-modules/gson/pom.xml b/json-modules/gson/pom.xml index ba968d9ae1..9e29bab3c4 100644 --- a/json-modules/gson/pom.xml +++ b/json-modules/gson/pom.xml @@ -65,7 +65,7 @@ 2.10.1 - 2.9.6 + 2.12.5 \ No newline at end of file diff --git a/persistence-modules/spring-data-couchbase-2/pom.xml b/persistence-modules/spring-data-couchbase-2/pom.xml index 45462d477e..eda2c45371 100644 --- a/persistence-modules/spring-data-couchbase-2/pom.xml +++ b/persistence-modules/spring-data-couchbase-2/pom.xml @@ -72,7 +72,7 @@ 6.0.6 5.0.3 8.0.1.Final - 2.12.2 + 2.12.5 \ No newline at end of file diff --git a/spring-ejb-modules/ejb-beans/pom.xml b/spring-ejb-modules/ejb-beans/pom.xml index 94f7963ad6..6203db5f5a 100644 --- a/spring-ejb-modules/ejb-beans/pom.xml +++ b/spring-ejb-modules/ejb-beans/pom.xml @@ -192,7 +192,7 @@ 2.21.0 2.8 8.2.1.Final - 2.10.12 + 2.12.5 \ No newline at end of file diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index f682eafdbe..173c5a5af0 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -121,12 +121,6 @@ hibernate-validator ${hibernate-validator.version} - - - joda-time - joda-time - ${joda-time.version} - com.github.jknack @@ -196,7 +190,6 @@ 6.0.10.Final 4.1.0 - 2.10 1 1.5.1 diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index a4860b641d..d07e6d3b28 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -93,11 +93,6 @@ mail ${javax.mail.version} - - joda-time - joda-time - ${joda-time.version} - com.fasterxml.jackson.core jackson-annotations @@ -184,7 +179,6 @@ 4.5.2 0.9 8.0.0 - 2.9.6 1.1 1.2 2.27.2 diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index eaec50c1f7..611a337b0c 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -114,7 +114,7 @@ - 2.9.6 + 2.12.5 2.8.0 3.0.1 From 25a02eb86de26a26bb983f4dfa357480d8384247 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 13 Nov 2023 12:24:40 +0100 Subject: [PATCH 219/283] fix: add only one spring boot app --- .../baeldung/overridebean/{basic => }/Config.java | 5 +---- .../overridebean/{basic => boot}/Application.java | 2 +- .../overridebean/conditional/Application.java | 14 -------------- .../baeldung/overridebean/profile/Application.java | 14 -------------- .../conditional/ConditionIntegrationTest.java | 1 + .../mockbean/MockBeanIntegrationTest.java | 2 +- .../OverrideBeanDefinitionIntegrationTest.java | 4 ++-- .../primary/PrimaryIntegrationTest.java | 4 ++-- .../profile/ProfileIntegrationTest.java | 1 + 9 files changed, 9 insertions(+), 38 deletions(-) rename spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/{basic => }/Config.java (64%) rename spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/{basic => boot}/Application.java (93%) delete mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java delete mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java similarity index 64% rename from spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java index 67d999958d..f0892338f8 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java @@ -1,11 +1,8 @@ -package com.baeldung.overridebean.basic; +package com.baeldung.overridebean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.baeldung.overridebean.Service; -import com.baeldung.overridebean.ServiceImpl; - @Configuration public class Config { diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java similarity index 93% rename from spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java index 6f9acde3d8..1eb0012493 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java @@ -1,4 +1,4 @@ -package com.baeldung.overridebean.basic; +package com.baeldung.overridebean.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java deleted file mode 100644 index 9c4cdbf8ec..0000000000 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.overridebean.conditional; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; - -@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java deleted file mode 100644 index d3298b2eb4..0000000000 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.overridebean.profile; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; - -@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java index 5f6b1d128f..b3a5164ff5 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ConditionalConfig.class, Endpoint.class, ConditionalTestConfig.class }, properties = "service.stub=true") @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java index 6a7be1cbda..2ece28482d 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; import com.baeldung.overridebean.Service; -import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Endpoint.class }) @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java index 0f3753ef34..a8dba58b79 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java @@ -11,9 +11,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; +import com.baeldung.overridebean.Config; import com.baeldung.overridebean.Endpoint; -import com.baeldung.overridebean.basic.Application; -import com.baeldung.overridebean.basic.Config; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, OverrideBeanDefinitionTestConfig.class }, properties = "spring.main.allow-bean-definition-overriding=true") @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java index 2bddfd4637..b6061c86d5 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java @@ -11,9 +11,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; +import com.baeldung.overridebean.Config; import com.baeldung.overridebean.Endpoint; -import com.baeldung.overridebean.basic.Application; -import com.baeldung.overridebean.basic.Config; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, PrimaryTestConfig.class }) @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java index deabfea9e5..7f4aae026c 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc From 8325025cb7cddb8e7ffee50e533e65face3bfed3 Mon Sep 17 00:00:00 2001 From: Bipinkumar27 Date: Mon, 13 Nov 2023 23:08:31 +0530 Subject: [PATCH 220/283] JAVA-18764: Changes made for adding the H2 dependency for removing integration failure --- security-modules/cas/cas-secured-app/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/security-modules/cas/cas-secured-app/pom.xml b/security-modules/cas/cas-secured-app/pom.xml index 6e1b878354..7c4864b1c0 100644 --- a/security-modules/cas/cas-secured-app/pom.xml +++ b/security-modules/cas/cas-secured-app/pom.xml @@ -55,6 +55,11 @@ spring-security-test test + + com.h2database + h2 + ${h2.version} + From f8e9ed2925735ff03f26c968769c2a0a82930dcd Mon Sep 17 00:00:00 2001 From: Michael Olayemi Date: Tue, 14 Nov 2023 05:35:36 +0100 Subject: [PATCH 221/283] Converting a File to a MultipartFile (#15180) * Converting a File to a MultipartFile * Converting a File to a MultipartFile --- spring-web-modules/spring-mvc-java-2/pom.xml | 6 +++ .../ConvertFileToMultipartFileUnitTest.java | 45 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java diff --git a/spring-web-modules/spring-mvc-java-2/pom.xml b/spring-web-modules/spring-mvc-java-2/pom.xml index d88a9c320a..b1b5a797f8 100644 --- a/spring-web-modules/spring-mvc-java-2/pom.xml +++ b/spring-web-modules/spring-mvc-java-2/pom.xml @@ -41,6 +41,11 @@ jaxb-runtime ${jaxb-runtime.version} + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + @@ -57,6 +62,7 @@ 4.0.1 5.2.2.RELEASE 2.3.5 + 1.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java new file mode 100644 index 0000000000..7d99f7f9bb --- /dev/null +++ b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertFileToMultipartFileUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.multipart.file; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; +import org.springframework.mock.web.MockMultipartFile; + +public class ConvertFileToMultipartFileUnitTest { + + @Test + public void givenFile_whenCreateMultipartFile_thenContentMatch() throws IOException { + File file = new File("src/main/resources/targetFile.tmp"); + byte[] fileBytes = Files.readAllBytes(file.toPath()); + MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", fileBytes); + String fileContent = new String(multipartFile.getBytes()); + assertEquals("Hello World", fileContent); + assertEquals("targetFile.tmp", multipartFile.getOriginalFilename()); + } + + @Test + public void givenFile_whenCreateMultipartFileUsingCommonsMultipart_thenContentMatch() throws IOException { + File file = new File("src/main/resources/targetFile.tmp"); + FileItem fileItem = new DiskFileItem("file", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile()); + InputStream input = new FileInputStream(file); + OutputStream outputStream = fileItem.getOutputStream(); + IOUtils.copy(input, outputStream); + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + String fileContent = new String(multipartFile.getBytes()); + assertEquals("Hello World", fileContent); + assertEquals("targetFile.tmp", multipartFile.getOriginalFilename()); + } + +} From b38b5327fd82481b3828e453286e1b2eddc7324f Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Tue, 14 Nov 2023 07:30:13 +0200 Subject: [PATCH 222/283] [JAVA-26731] Upgraded bucket4j-spring-boot-starter version --- spring-boot-modules/spring-boot-libraries/pom.xml | 10 +++++++--- .../ratelimiting/application-bucket4j-starter.yml | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml index ed9a414a60..b0f0c780aa 100644 --- a/spring-boot-modules/spring-boot-libraries/pom.xml +++ b/spring-boot-modules/spring-boot-libraries/pom.xml @@ -18,6 +18,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-security @@ -95,7 +99,7 @@ - com.github.vladimir-bukhtoyarov + com.bucket4j bucket4j-core ${bucket4j.version} @@ -226,8 +230,8 @@ 2.1 2.6.0 3.3.0 - 7.6.0 - 0.7.0 + 8.1.0 + 0.8.1 3.1.8 diff --git a/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml b/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml index ecc9f22e0a..efff65555b 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml +++ b/spring-boot-modules/spring-boot-libraries/src/main/resources/ratelimiting/application-bucket4j-starter.yml @@ -21,19 +21,19 @@ bucket4j: url: /api/v1/area.* http-response-body: "{ \"status\": 429, \"error\": \"Too Many Requests\", \"message\": \"You have exhausted your API Request Quota\" }" rate-limits: - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" execute-condition: "getHeader('X-api-key').startsWith('PX001-')" bandwidths: - capacity: 100 time: 1 unit: hours - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" execute-condition: "getHeader('X-api-key').startsWith('BX001-')" bandwidths: - capacity: 40 time: 1 unit: hours - - expression: "getHeader('X-api-key')" + - cache-key: "getHeader('X-api-key')" bandwidths: - capacity: 20 time: 1 From 8532499dcc839936968894ce06747c454c4d30a7 Mon Sep 17 00:00:00 2001 From: Mikhail Polivakha <68962645+Mikhail2048@users.noreply.github.com> Date: Tue, 14 Nov 2023 08:40:27 +0300 Subject: [PATCH 223/283] BAEL-7187 implemented (#15208) * BAEL-7139 implemented * BAEL-7187 implemented --- ...tableFutureExceptionsHandlingUnitTest.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java diff --git a/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java b/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java new file mode 100644 index 0000000000..afb31f7617 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-5/src/test/java/com/baeldung/exceptions_completablefuture/CompletableFutureExceptionsHandlingUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.exceptions_completablefuture; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class CompletableFutureExceptionsHandlingUnitTest { + + @ParameterizedTest + @MethodSource("parametersSource_handle") + void whenCompletableFutureIsScheduled_thenHandleStageIsAlwaysInvoked(int radius, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (radius <= 0) { + throw new IllegalArgumentException("Supplied with non-positive radius '%d'"); + } + return Math.round(Math.pow(radius, 2) * Math.PI); + }) + .handle((result, ex) -> { + if (ex == null) { + return result; + } else { + return -1L; + } + }) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_exceptionally") + void whenCompletableFutureIsScheduled_thenExceptionallyExecutedOnlyOnFailure(int a, int b, int c, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (a <= 0 || b <= 0 || c <= 0) { + throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c))); + } + return a * b * c; + }) + .exceptionally((ex) -> -1) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_exceptionally") + void givenCompletableFutureIsScheduled_whenHandleIsAlreadyPresent_thenExceptionallyIsNotExecuted(int a, int b, int c, long expected) + throws ExecutionException, InterruptedException { + long actual = CompletableFuture + .supplyAsync(() -> { + if (a <= 0 || b <= 0 || c <= 0) { + throw new IllegalArgumentException(String.format("Supplied with incorrect edge length [%s]", List.of(a, b, c))); + } + return a * b * c; + }) + .handle((result, throwable) -> { + if (throwable != null) { + return -1; + } + return result; + }) + .exceptionally((ex) -> { + System.exit(1); + return 0; + }) + .get(); + + Assertions.assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @MethodSource("parametersSource_whenComplete") + void whenCompletableFutureIsScheduled_thenWhenCompletedExecutedAlways(Double a, long expected, Class ifAny) { + try { + CountDownLatch countDownLatch = new CountDownLatch(1); + + long actual = CompletableFuture + .supplyAsync(() -> { + if (a.isNaN()) { + throw new IllegalArgumentException("Supplied value is NaN"); + } + return Math.round(Math.pow(a, 2)); + }) + .whenComplete((result, exception) -> countDownLatch.countDown()) + .get(); + + Assertions.assertThat(countDownLatch.await(20L, java.util.concurrent.TimeUnit.SECONDS)); + Assertions.assertThat(actual).isEqualTo(expected); + } catch (Exception e) { + Assertions.assertThat(e.getClass()).isSameAs(ExecutionException.class); + Assertions.assertThat(e.getCause().getClass()).isSameAs(ifAny); + } + } + + static Stream parametersSource_handle() { + return Stream.of( + Arguments.of(1, 3), + Arguments.of(-1, -1) + ); + } + + static Stream parametersSource_exceptionally() { + return Stream.of( + Arguments.of(1, 5, 5, 25), + Arguments.of(-1, 10, 15, -1) + ); + } + + static Stream parametersSource_whenComplete() { + return Stream.of( + Arguments.of(2d, 4, null), + Arguments.of(Double.NaN, 1, IllegalArgumentException.class) + ); + } +} From 122ca1a996bb2e014d840eaf879e99dc7432371a Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:17:53 +0530 Subject: [PATCH 224/283] JAVA-27197 Upgrade hibernate-validator version in spring-thymeleaf-5 module --- spring-web-modules/spring-thymeleaf-5/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-thymeleaf-5/pom.xml b/spring-web-modules/spring-thymeleaf-5/pom.xml index 0717e41bac..2d178bd933 100644 --- a/spring-web-modules/spring-thymeleaf-5/pom.xml +++ b/spring-web-modules/spring-thymeleaf-5/pom.xml @@ -139,7 +139,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.6.1 From c5af2f3f3b9b6143b2536d9ce430b0a444a59ff6 Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Tue, 14 Nov 2023 07:53:16 +0200 Subject: [PATCH 225/283] This PR is related to BAEL-7181 (#15192) * This commit is related to BAEL-7181 This commit aims to add a class "TimestampToLong.java" that provides several approaches to convert timestamp string into long. * This commit is related to BAEL-7181 This commit aims to add a test class "TimestampToLongUnitTest.java" that provides several approaches to convert timestamp string into long. --- .../timestamptolong/TimestampToLong.java | 32 ++++++++++++ .../TimestampToLongUnitTest.java | 52 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java create mode 100644 core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java new file mode 100644 index 0000000000..2ebe30f4ff --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java @@ -0,0 +1,32 @@ +package com.baeldung.timestamptolong; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class TimestampToLong { + public void usingSimpleDateFormat() throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String currentDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + long actualTimestamp = sdf.parse(currentDateString).getTime(); + } + + public void usingInstantClass() { + Instant instant = Instant.now(); + long actualTimestamp = instant.toEpochMilli(); + } + + public void usingTimestamp() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + long actualTimestamp = timestamp.getTime(); + } + + public void usingJava8DateTime() { + LocalDateTime localDateTime = LocalDateTime.now(); + long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java new file mode 100644 index 0000000000..ede8f7792d --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.timestamptolong; + +import org.junit.Test; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +import static org.junit.Assert.assertTrue; + +public class TimestampToLongUnitTest { + + private static final long TOLERANCE = 1000; + + @Test + public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String currentDateString = sdf.format(new Date()); + long actualTimestamp = sdf.parse(currentDateString).getTime(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } + + @Test + public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() { + Instant instant = Instant.now(); + long actualTimestamp = instant.toEpochMilli(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } + + @Test + public void givenTimestamp_whenCreatingTimestamp_thenTConvertToLong() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + long actualTimestamp = timestamp.getTime(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } + + @Test + public void givenJava8DateTime_whenGettingTimestamp_thenTConvertToLong() { + LocalDateTime localDateTime = LocalDateTime.now(); + long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + + assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + } +} From f94f248f5a52c110615c827212eefe30b1d2cd82 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:25:35 +0530 Subject: [PATCH 226/283] JAVA-27196 Upgrade hibernate-validator version in spring-mvc-xml module --- spring-web-modules/spring-mvc-xml/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-mvc-xml/pom.xml b/spring-web-modules/spring-mvc-xml/pom.xml index bf0dc52b68..12f0a1a68a 100644 --- a/spring-web-modules/spring-mvc-xml/pom.xml +++ b/spring-web-modules/spring-mvc-xml/pom.xml @@ -142,7 +142,7 @@ 4.4.5 4.5.2 - 6.0.10.Final + 8.0.1.Final 3.0.1-b08 2.8.0 From 68f4c0517caaca2dc5e4fb41fa0e31aacd0fa761 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:50:54 +0530 Subject: [PATCH 227/283] JAVA-27198 Upgrade hibernate-validator version in spring-thymeleaf module --- spring-web-modules/spring-thymeleaf/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-thymeleaf/pom.xml b/spring-web-modules/spring-thymeleaf/pom.xml index 94ae05ca11..ce0c0a7e21 100644 --- a/spring-web-modules/spring-thymeleaf/pom.xml +++ b/spring-web-modules/spring-thymeleaf/pom.xml @@ -140,7 +140,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.9.9 From bf4cc41cb4a77ea0b2be2124bb72af3647a7c7c5 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 12:24:10 +0530 Subject: [PATCH 228/283] JAVA-27199 Upgrade hibernate validator version in vraptor module --- web-modules/vraptor/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-modules/vraptor/pom.xml b/web-modules/vraptor/pom.xml index ecc6fe3313..25f8b5d5e5 100644 --- a/web-modules/vraptor/pom.xml +++ b/web-modules/vraptor/pom.xml @@ -49,7 +49,7 @@ provided - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -115,7 +115,7 @@ 4.2.0.Final 2.1.2.Final 2.2 - 5.1.1.Final + 8.0.1.Final 4.1.0-RC3 4.0.4 8.0.8-dmr From f20a18ed9b97ead5c6f6e67f55993d3acc4c12dc Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 14 Nov 2023 10:28:22 +0100 Subject: [PATCH 229/283] clean, add mock example --- .../conditional/ConditionalTestConfig.java | 2 +- .../mockbean/MockBeanIntegrationTest.java | 4 +- .../profile/ProfileIntegrationMockTest.java | 38 +++++++++++++++++++ ...t.java => ProfileIntegrationStubTest.java} | 6 ++- .../profile/ProfileTestConfig.java | 12 +++++- 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationTest.java => ProfileIntegrationStubTest.java} (84%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java index c48c4e2266..ce82b43df0 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java @@ -9,8 +9,8 @@ import com.baeldung.overridebean.Service; @TestConfiguration public class ConditionalTestConfig { - @ConditionalOnProperty(name = "service.stub", havingValue = "true") @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "true") public Service helloWorld() { return new ConditionalStub(); } diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java index 2ece28482d..9a63ad4113 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -25,11 +25,11 @@ class MockBeanIntegrationTest { private MockMvc mockMvc; @MockBean - private Service serviceExample; + private Service service; @Test void givenServiceMockBean_whenGetHelloEndpoint_thenMockOk() throws Exception { - when(serviceExample.helloWorld()).thenReturn("hello mock bean"); + when(service.helloWorld()).thenReturn("hello mock bean"); this.mockMvc.perform(get("/hello")) .andExpect(status().isOk()) .andExpect(content().string(containsString("hello mock bean"))); diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java new file mode 100644 index 0000000000..43fb69860d --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java @@ -0,0 +1,38 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +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.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +@ActiveProfiles("mock") +class ProfileIntegrationMockTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private Service service; + + @Test + void givenConfigurationWithProfile_whenTestProfileIsActive_thenMockOk() throws Exception { + when(service.helloWorld()).thenReturn("hello profile mock"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile mock"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java similarity index 84% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java index 7f4aae026c..e1c88f2a31 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; @@ -16,13 +17,14 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc -class ProfileIntegrationTest { +@ActiveProfiles("stub") +class ProfileIntegrationStubTest { @Autowired private MockMvc mockMvc; @Test - void givenConfigurationWithProfile_whenNoProductionProfileIsActive_thenStubOk() throws Exception { + void givenConfigurationWithProfile_whenTestProfileIsActive_thenStubOk() throws Exception { this.mockMvc.perform(get("/hello")) .andExpect(status().isOk()) .andExpect(content().string(containsString("hello profile stub"))); diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java index edd33162e0..7e1de309d3 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java @@ -1,7 +1,10 @@ package com.baeldung.overridebean.profile; +import static org.mockito.Mockito.mock; + import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; import com.baeldung.overridebean.Service; @@ -9,7 +12,14 @@ import com.baeldung.overridebean.Service; public class ProfileTestConfig { @Bean - public Service helloWorld() { + @Profile("stub") + public Service helloWorldStub() { return new ProfileServiceStub(); } + + @Bean + @Profile("mock") + public Service helloWorldMock() { + return mock(Service.class); + } } From 690f6edd5169c4bac54828d94c35be8aae417819 Mon Sep 17 00:00:00 2001 From: Ehsan Sasanianno Date: Tue, 14 Nov 2023 12:39:36 +0100 Subject: [PATCH 230/283] java-26772: upgrade jedis to 5.0.2 (#15207) --- persistence-modules/redis/pom.xml | 2 +- persistence-modules/spring-data-redis/pom.xml | 2 ++ spring-boot-modules/spring-boot-3-2/pom.xml | 2 ++ spring-web-modules/spring-session/spring-session-redis/pom.xml | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml index 571487af3d..98be674a8e 100644 --- a/persistence-modules/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -57,7 +57,7 @@ 0.6 3.20.0 - 4.3.2 + 5.0.2 4.1.90.Final diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index ab133192a0..052935e215 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -50,6 +50,7 @@ redis.clients jedis + ${jedis.version} jar @@ -83,6 +84,7 @@ 3.2.4 0.10.0 0.6 + 5.0.2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml index 9b5b7ea254..c85488d44b 100644 --- a/spring-boot-modules/spring-boot-3-2/pom.xml +++ b/spring-boot-modules/spring-boot-3-2/pom.xml @@ -135,6 +135,7 @@ redis.clients jedis + ${jedis.version} jar @@ -285,6 +286,7 @@ 3.0.0-M7 5.14.0 0.2.0 + 5.0.2 diff --git a/spring-web-modules/spring-session/spring-session-redis/pom.xml b/spring-web-modules/spring-session/spring-session-redis/pom.xml index 6824a3632d..6b1aec24e4 100644 --- a/spring-web-modules/spring-session/spring-session-redis/pom.xml +++ b/spring-web-modules/spring-session/spring-session-redis/pom.xml @@ -40,12 +40,14 @@ redis.clients jedis + ${jedis.version} jar 0.6 + 5.0.2 \ No newline at end of file From c6dbdeaaa5ecffef4bf18828a44d604255d9703e Mon Sep 17 00:00:00 2001 From: vunamtien Date: Tue, 14 Nov 2023 18:41:43 +0700 Subject: [PATCH 231/283] BAEL-7106-compress-and-uncompress-bytes (#15216) --- .../compressbytes/CompressByteArrayUtil.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java new file mode 100644 index 0000000000..88e2283985 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/compressbytes/CompressByteArrayUtil.java @@ -0,0 +1,58 @@ +package com.baeldung.compressbytes; + +import java.io.ByteArrayOutputStream; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +public class CompressByteArrayUtil { + + public static byte[] compress(byte[] input) { + Deflater deflater = new Deflater(); + deflater.setInput(input); + deflater.finish(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + + while (!deflater.finished()) { + int compressedSize = deflater.deflate(buffer); + outputStream.write(buffer, 0, compressedSize); + } + + return outputStream.toByteArray(); + } + + public static byte[] decompress(byte[] input) throws DataFormatException { + Inflater inflater = new Inflater(); + inflater.setInput(input); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + + while (!inflater.finished()) { + int decompressedSize = inflater.inflate(buffer); + outputStream.write(buffer, 0, decompressedSize); + } + + return outputStream.toByteArray(); + } + + public static void main(String[] args) throws Exception { + String inputString = "Baeldung helps developers explore the Java ecosystem and simply be better engineers. " + + "We publish to-the-point guides and courses, with a strong focus on building web applications, Spring, " + + "Spring Security, and RESTful APIs"; + byte[] input = inputString.getBytes(); + + // Compression + byte[] compressedData = compress(input); + + // Decompression + byte[] decompressedData = decompress(compressedData); + + System.out.println("Original: " + input.length + " bytes"); + System.out.println("Compressed: " + compressedData.length + " bytes"); + System.out.println("Decompressed: " + decompressedData.length + " bytes"); + } + +} From 2133e9b5db41efebdf7492f9ebd1672e8bdb42ba Mon Sep 17 00:00:00 2001 From: Azhwani <13301425+azhwani@users.noreply.github.com> Date: Tue, 14 Nov 2023 22:48:17 +0100 Subject: [PATCH 232/283] BAEL-7176: How to avoid NoSuchElementException with Stream (#15098) --- .../NoSuchElementExceptionStreamUnitTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java new file mode 100644 index 0000000000..bef834c1af --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/nosuchelementexception/NoSuchElementExceptionStreamUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.nosuchelementexception; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; + +import org.junit.Test; + +public class NoSuchElementExceptionStreamUnitTest { + + @Test(expected = NoSuchElementException.class) + public void givenEmptyOptional_whenCallingGetMethod_thenThrowNoSuchElementException() { + List names = List.of("William", "Amelia", "Albert", "Philip"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Emma")) + .findFirst(); + + emptyOptional.get(); + } + + @Test + public void givenEmptyOptional_whenUsingIsPresentMethod_thenReturnDefault() { + List names = List.of("Tyler", "Amelia", "James", "Emma"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Lucas")) + .findFirst(); + + String name = "unknown"; + if (emptyOptional.isPresent()) { + name = emptyOptional.get(); + } + + assertEquals("unknown", name); + } + + @Test + public void givenEmptyOptional_whenUsingOrElseMethod_thenReturnDefault() { + List names = List.of("Nicholas", "Justin", "James"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Lucas")) + .findFirst(); + + String name = emptyOptional.orElse("unknown"); + + assertEquals("unknown", name); + } + + @Test + public void givenEmptyOptional_whenUsingOrElseGetMethod_thenReturnDefault() { + List names = List.of("Thomas", "Catherine", "David", "Olivia"); + Optional emptyOptional = names.stream() + .filter(name -> name.equals("Liam")) + .findFirst(); + + String name = emptyOptional.orElseGet(() -> "unknown"); + + assertEquals("unknown", name); + } + +} From 6a7e63795d0f332c00eb2d06699da87dc94adca3 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:15:27 +0530 Subject: [PATCH 233/283] BAEL-7091 removed Java 9 snippets --- testing-modules/testing-assertions/pom.xml | 12 ---- .../AssertNestedMapUnitTest.java | 68 ++++++++++++------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 1f2b4e335d..1da53bd77e 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -4,18 +4,6 @@ 4.0.0 testing-assertions 0.0.1-SNAPSHOT - - - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - - - com.baeldung diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index 7c48a5eb4a..ceef5efdd2 100644 --- a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; +import java.util.HashMap; import java.util.Map; import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; @@ -13,16 +14,22 @@ import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); } @Test void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertAll( () -> assertTrue(outerMap.containsKey("address")), @@ -32,8 +39,11 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertTrue(outerMap.containsKey("address") && ((Map)outerMap.get("address")).get("city").equals("Chicago")); @@ -41,8 +51,12 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); + assertAll( () -> assertThat(outerMap, hasKey("address")), () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) @@ -51,42 +65,46 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); } @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = Map.of - ( - "city", "Chicago", - "zip", "10005" - ); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + innerMap.put("zip", "10005"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = Map.of - ( - "city", "Chicago", - "zip", "10005" - ); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + innerMap.put("zip", "10005"); + + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); } - } From 4d9a5ea8b46689b1c7f3a1f224a30c9207b431c5 Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Wed, 15 Nov 2023 10:55:56 +0100 Subject: [PATCH 234/283] JAVA-12712 | intelliJ Module (#15152) --- intelliJ-modules/.gitignore | 1 + .../gradle/wrapper/gradle-wrapper.properties | 7 + intelliJ-modules/gradlew | 248 ++++++++++++++++++ intelliJ-modules/gradlew.bat | 92 +++++++ intelliJ-modules/settings.gradle | 3 + .../stackoverflow-plugin-gradle/build.gradle | 10 +- .../stackoverflow-plugin/build.gradle | 5 + .../stackoverflow-plugin/settings.gradle | 1 + 8 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 intelliJ-modules/.gitignore create mode 100644 intelliJ-modules/gradle/wrapper/gradle-wrapper.properties create mode 100644 intelliJ-modules/gradlew create mode 100644 intelliJ-modules/gradlew.bat create mode 100644 intelliJ-modules/settings.gradle create mode 100644 intelliJ-modules/stackoverflow-plugin/build.gradle create mode 100644 intelliJ-modules/stackoverflow-plugin/settings.gradle diff --git a/intelliJ-modules/.gitignore b/intelliJ-modules/.gitignore new file mode 100644 index 0000000000..d16386367f --- /dev/null +++ b/intelliJ-modules/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/intelliJ-modules/gradle/wrapper/gradle-wrapper.properties b/intelliJ-modules/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..62f495dfed --- /dev/null +++ b/intelliJ-modules/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/intelliJ-modules/gradlew b/intelliJ-modules/gradlew new file mode 100644 index 0000000000..fcb6fca147 --- /dev/null +++ b/intelliJ-modules/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/intelliJ-modules/gradlew.bat b/intelliJ-modules/gradlew.bat new file mode 100644 index 0000000000..93e3f59f13 --- /dev/null +++ b/intelliJ-modules/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/intelliJ-modules/settings.gradle b/intelliJ-modules/settings.gradle new file mode 100644 index 0000000000..ff10e09b3c --- /dev/null +++ b/intelliJ-modules/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'intellij-modules' +include 'stackoverflow-plugin' +include 'stackoverflow-plugin-gradle' diff --git a/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle b/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle index cd0cc258bf..3967a1f075 100644 --- a/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle +++ b/intelliJ-modules/stackoverflow-plugin-gradle/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.jetbrains.intellij' version '0.4.21' + id 'org.jetbrains.intellij' version '1.16.0' } group 'com.baeldung' @@ -11,15 +11,17 @@ repositories { } dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' + testImplementation('junit:junit:4.12') } // See https://github.com/JetBrains/gradle-intellij-plugin/ intellij { - version '2020.1.1' + version = "2022.2.5" + type = "IC" } + patchPluginXml { - changeNotes """ + changeNotes = """ Add change notes here.
most HTML tags may be used""" } \ No newline at end of file diff --git a/intelliJ-modules/stackoverflow-plugin/build.gradle b/intelliJ-modules/stackoverflow-plugin/build.gradle new file mode 100644 index 0000000000..81962e0e0a --- /dev/null +++ b/intelliJ-modules/stackoverflow-plugin/build.gradle @@ -0,0 +1,5 @@ +// this project is not supposed to be built. We check only if it compiles fine. + +plugins { + id 'java' +} \ No newline at end of file diff --git a/intelliJ-modules/stackoverflow-plugin/settings.gradle b/intelliJ-modules/stackoverflow-plugin/settings.gradle new file mode 100644 index 0000000000..4ebea35284 --- /dev/null +++ b/intelliJ-modules/stackoverflow-plugin/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'stackoverflow-plugin' From de50130c7461ddb7c12ee4b5832eb4244f852c1d Mon Sep 17 00:00:00 2001 From: Michael Olayemi Date: Wed, 15 Nov 2023 14:30:00 +0100 Subject: [PATCH 235/283] Create Table using ASCII in a Console in Java (#15158) --- core-java-modules/core-java-console/pom.xml | 6 ++ .../consoletableoutput/BodyMassIndex.java | 44 +++++++++++++ .../BodyMassIndexApplication.java | 62 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java create mode 100644 core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java diff --git a/core-java-modules/core-java-console/pom.xml b/core-java-modules/core-java-console/pom.xml index 1b56f1f27c..8677b672ea 100644 --- a/core-java-modules/core-java-console/pom.xml +++ b/core-java-modules/core-java-console/pom.xml @@ -29,6 +29,11 @@
+ + de.vandermeer + asciitable + ${ascii.version} + @@ -157,6 +162,7 @@ 3.0.0-M1 1.8 1.8 + 0.3.2 \ No newline at end of file diff --git a/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java new file mode 100644 index 0000000000..96cede7020 --- /dev/null +++ b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndex.java @@ -0,0 +1,44 @@ +package com.baeldung.consoletableoutput; + +public class BodyMassIndex { + + private String name; + private double height; + private double weight; + + public BodyMassIndex(String name, double height, double weight) { + this.name = name; + this.height = height; + this.weight = weight; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + public double calculate() { + double bmi = weight / (height * height); + String formattedBmi = String.format("%.2f", bmi); + return Double.parseDouble(formattedBmi); + } +} diff --git a/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java new file mode 100644 index 0000000000..cb340256aa --- /dev/null +++ b/core-java-modules/core-java-console/src/main/java/com/baeldung/consoletableoutput/BodyMassIndexApplication.java @@ -0,0 +1,62 @@ +package com.baeldung.consoletableoutput; + +import java.util.ArrayList; +import java.util.List; + +import de.vandermeer.asciitable.AsciiTable; +import de.vandermeer.skb.interfaces.transformers.textformat.TextAlignment; + +public class BodyMassIndexApplication { + + public static void main(String[] args) { + stringFormat(); + asciiTable(); + + } + + public static void stringFormat() { + List bodyMassIndices = new ArrayList<>(); + bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80)); + bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90)); + + String leftAlignment = "| %-7s | %-7.2f | %-7.2f | %-5.2f |%n"; + + System.out.format("+---------+---------+---------+-------+%n"); + System.out.format("| Name | Height | Weight | BMI |%n"); + System.out.format("+---------+---------+---------+-------+%n"); + + for (BodyMassIndex bodyMassIndex : bodyMassIndices) { + System.out.format(leftAlignment, bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate()); + System.out.format("+---------+---------+---------+-------+%n"); + } + + } + + public static void asciiTable() { + List bodyMassIndices = new ArrayList<>(); + bodyMassIndices.add(new BodyMassIndex("Tom", 1.8, 80)); + bodyMassIndices.add(new BodyMassIndex("Elton", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Harry", 1.9, 90)); + bodyMassIndices.add(new BodyMassIndex("Hannah", 1.9, 90)); + + AsciiTable asciiTable = new AsciiTable(); + asciiTable.addRule(); + asciiTable.addRow("Name", "Height", "Weight", "BMI"); + asciiTable.addRule(); + + for (BodyMassIndex bodyMassIndex : bodyMassIndices) { + + asciiTable.addRow(bodyMassIndex.getName(), bodyMassIndex.getHeight(), bodyMassIndex.getWeight(), bodyMassIndex.calculate()); + asciiTable.addRule(); + + } + + asciiTable.setTextAlignment(TextAlignment.CENTER); + String render = asciiTable.render(); + System.out.println(render); + + } + +} From 5787183a36f8a30196f5630f4b702010db1b0042 Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Wed, 15 Nov 2023 22:55:03 +0800 Subject: [PATCH 236/283] BAEL-7109 - added code to demostrate how to get max date in java (#14944) * BAEL-7109 - added code to demostrate how to get max date in java * BAEL-7109 Fix test case typo * BAEL-7109 Fix test case file name * Fix the test method * Fix the test method * Fix the test method * Remove public * add new line --- .../com/baeldung/maxdate/DateComparison.java | 18 ++++++++++++++++++ .../com/baeldung/maxdate/MaxDateDisplay.java | 18 ++++++++++++++++++ .../maxdate/DateComparisonUnitTest.java | 16 ++++++++++++++++ .../maxdate/MaxDateDisplayUnitTest.java | 18 ++++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java create mode 100644 core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java create mode 100644 core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java create mode 100644 core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java new file mode 100644 index 0000000000..d6450670a2 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/DateComparison.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import java.util.Date; + +public class DateComparison { + public int compareTodayWithMaxDate() { + Date today = new Date(); + Date maxDate = new Date(Long.MAX_VALUE); + + int comparisonResult = today.compareTo(maxDate); + return comparisonResult; + } + + public static void main(String[] args) { + DateComparison comparator = new DateComparison(); + System.out.println(comparator.compareTodayWithMaxDate()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java new file mode 100644 index 0000000000..b79b5f4422 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/maxdate/MaxDateDisplay.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import java.util.Date; +import java.text.SimpleDateFormat; + +public class MaxDateDisplay { + public String getMaxDateValue() { + Date maxDate = new Date(Long.MAX_VALUE); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + return "The maximum date value in Java is: " + sdf.format(maxDate); + } + + public static void main(String[] args) { + MaxDateDisplay display = new MaxDateDisplay(); + System.out.println(display.getMaxDateValue()); + } +} + diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java new file mode 100644 index 0000000000..70aef126da --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/DateComparisonUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.maxdate; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class DateComparisonUnitTest { + + @Test + void whenCompareTodayWithMaxDate_thenCorrectResult() { + DateComparison comparator = new DateComparison(); + int result = comparator.compareTodayWithMaxDate(); + + assertTrue(result < 0); + } +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java new file mode 100644 index 0000000000..dd7000bd29 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/maxdate/MaxDateDisplayUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.maxdate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class MaxDateDisplayUnitTest { + + @Test + void whenGetMaxDate_thenCorrectResult() { + MaxDateDisplay display = new MaxDateDisplay(); + String result = display.getMaxDateValue(); + assertEquals( + "The maximum date value in Java is: 292278994-08-17 07:12:55.807", + result + ); + } +} From 0838279c6afa9bf92a2a89cdb2edcafaddd1a039 Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Wed, 15 Nov 2023 22:16:28 +0100 Subject: [PATCH 237/283] BAEL-7092: How to get the size of a file in MB, KB & GB in java (#15117) * BAEL-7092: How to get the size of a file in MB, KB & GB in java * Update JavaFileSizeUnitTest.java * BAEL-7092: How to get the size of a file in MB, KB & GB in java --------- Co-authored-by: Grzegorz Piwowarek --- .../java/com/baeldung/size/FileSizeUtils.java | 28 +++++++++++++++++ .../baeldung/size/JavaFileSizeUnitTest.java | 31 ++++++++++++++++--- 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java b/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java new file mode 100644 index 0000000000..18c8687043 --- /dev/null +++ b/core-java-modules/core-java-io/src/main/java/com/baeldung/size/FileSizeUtils.java @@ -0,0 +1,28 @@ +package com.baeldung.size; + +import java.io.File; + +public class FileSizeUtils { + public static long getFileSizeInBytes(File file) { + if (file.exists()) { + return file.length(); + } else { + throw new IllegalArgumentException("File not found."); + } + } + + public static double getFileSizeInKilobytes(File file) { + long bytes = getFileSizeInBytes(file); + return (double) bytes / 1024; + } + + public static double getFileSizeInMegabytes(File file) { + double kilobytes = getFileSizeInKilobytes(file); + return kilobytes / 1024; + } + + public static double getFileSizeInGigabytes(File file) { + double megabytes = getFileSizeInMegabytes(file); + return megabytes / 1024; + } +} diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java index d015f2602e..d8f4361260 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java +++ b/core-java-modules/core-java-io/src/test/java/com/baeldung/size/JavaFileSizeUnitTest.java @@ -1,6 +1,8 @@ package com.baeldung.size; -import static org.junit.Assert.assertEquals; +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; import java.io.File; import java.io.FileInputStream; @@ -10,9 +12,9 @@ import java.net.URL; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class JavaFileSizeUnitTest { private static final long EXPECTED_FILE_SIZE_IN_BYTES = 11; @@ -85,4 +87,23 @@ public class JavaFileSizeUnitTest { assertEquals(EXPECTED_FILE_SIZE_IN_BYTES, stream.available()); } } -} \ No newline at end of file + + @Test + public void whenGetFileSizeInDifferentUnits_thenCorrect(){ + filePath = String.join(File.separator, new String[] { "src", "test", "resources", "size", "sample_file_1.in" }); + File file = new File(filePath); + if (file.exists()) { + long expectedBytes = file.length(); + double expectedKilobytes = (double) expectedBytes / 1024; + double expectedMegabytes = expectedKilobytes / 1024; + double expectedGigabytes = expectedMegabytes / 1024; + + assertEquals(expectedBytes, FileSizeUtils.getFileSizeInBytes(file)); + assertEquals(expectedKilobytes, FileSizeUtils.getFileSizeInKilobytes(file), 0.01); + assertEquals(expectedMegabytes, FileSizeUtils.getFileSizeInMegabytes(file), 0.01); + assertEquals(expectedGigabytes, FileSizeUtils.getFileSizeInGigabytes(file), 0.01); + } else { + fail("File not found."); + } + } +} From 336ee922eb0933fef3f6ab6b554f4cc07f2f652d Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:21:18 +0200 Subject: [PATCH 238/283] JAVA-26692 Go over tutorials - integration builds test results - Week 45 - 2023 (#15194) Co-authored-by: timis1 --- .../multipletopics/KafkaMultipleTopicsIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java index 345e84b65b..570670cdf9 100644 --- a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java @@ -21,7 +21,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.ContainerTestUtils; @SpringBootTest(classes = KafkaMultipleTopicsApplication.class) -@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) +@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9099", "port=9099" }) public class KafkaMultipleTopicsIntegrationTest { private static final String CARD_PAYMENTS_TOPIC = "card-payments"; private static final String BANK_TRANSFERS_TOPIC = "bank-transfers"; From f12328011b0a0c254b5096c3ce0dbfd7dcbd4c7f Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:10:00 +0530 Subject: [PATCH 239/283] BAEL-7091 reverted Java 9 snippets --- .../AssertNestedMapUnitTest.java | 68 +++++++------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index ceef5efdd2..7c48a5eb4a 100644 --- a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -3,7 +3,6 @@ package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; -import java.util.HashMap; import java.util.Map; import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; @@ -14,22 +13,16 @@ import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); } @Test void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertAll( () -> assertTrue(outerMap.containsKey("address")), @@ -39,11 +32,8 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); assertTrue(outerMap.containsKey("address") && ((Map)outerMap.get("address")).get("city").equals("Chicago")); @@ -51,12 +41,8 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); - + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertAll( () -> assertThat(outerMap, hasKey("address")), () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) @@ -65,46 +51,42 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); } @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - innerMap.put("zip", "10005"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map> outerMap = Map.of("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - innerMap.put("zip", "10005"); - - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map outerMap = Map.of("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); } + } From 58db4f7a091f29128ddbbacc99ccecec46a2c422 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Thu, 16 Nov 2023 20:22:43 +0100 Subject: [PATCH 240/283] JAVA-27338: Fix VehicleUnitTest --- .../com/baeldung/sealed/classes/VehicleUnitTest.java | 8 ++++---- .../com/baeldung/sealed/records/VehicleUnitTest.java | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java index 73d8aad810..0c437affd8 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(car.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(truck.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java index ac8a8c953c..8dd150b5e7 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(car.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + Assertions.assertThat(car.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(truck.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + Assertions.assertThat(truck.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test From 0b229a9af4cc321f4bebb278d47616f726c7cb48 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Thu, 16 Nov 2023 18:35:11 -0300 Subject: [PATCH 241/283] draft 1 (#15222) --- ...tSpecificDeserializationFilterFactory.java | 47 +++++++ .../pojo/ContextSpecific.java | 7 ++ .../pojo/NestedSample.java | 19 +++ .../deserializationfilters/pojo/Sample.java | 61 +++++++++ .../pojo/SampleExploit.java | 25 ++++ .../service/DeserializationService.java | 11 ++ .../service/LimitedArrayService.java | 15 +++ .../service/LowDepthService.java | 20 +++ .../service/SmallObjectService.java | 15 +++ .../utils/DeserializationUtils.java | 50 ++++++++ .../utils/FilterUtils.java | 32 +++++ .../utils/SerializationUtils.java | 17 +++ ...cDeserializationFilterIntegrationTest.java | 119 ++++++++++++++++++ 13 files changed, 438 insertions(+) create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java new file mode 100644 index 0000000000..25a855487e --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java @@ -0,0 +1,47 @@ +package com.baeldung.deserializationfilters; + +import java.io.ObjectInputFilter; +import java.util.function.BinaryOperator; + +import com.baeldung.deserializationfilters.service.DeserializationService; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.FilterUtils; + +public class ContextSpecificDeserializationFilterFactory implements BinaryOperator { + + @Override + public ObjectInputFilter apply(ObjectInputFilter current, ObjectInputFilter next) { + if (current == null) { + Class caller = findInStack(DeserializationService.class); + + if (caller == null) { + current = FilterUtils.fallbackFilter(); + } else if (caller.equals(SmallObjectService.class)) { + current = FilterUtils.safeSizeFilter(190); + } else if (caller.equals(LowDepthService.class)) { + current = FilterUtils.safeDepthFilter(2); + } else if (caller.equals(LimitedArrayService.class)) { + current = FilterUtils.safeArrayFilter(3); + } + } + + return ObjectInputFilter.merge(current, next); + } + + private static Class findInStack(Class superType) { + for (StackTraceElement element : Thread.currentThread() + .getStackTrace()) { + try { + Class subType = Class.forName(element.getClassName()); + if (superType.isAssignableFrom(subType)) { + return subType; + } + } catch (ClassNotFoundException e) { + return null; + } + } + return null; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java new file mode 100644 index 0000000000..add827d280 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java @@ -0,0 +1,7 @@ +package com.baeldung.deserializationfilters.pojo; + +import java.io.Serializable; + +public interface ContextSpecific extends Serializable { + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java new file mode 100644 index 0000000000..a1d41744e6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java @@ -0,0 +1,19 @@ +package com.baeldung.deserializationfilters.pojo; + +public class NestedSample implements ContextSpecific { + private static final long serialVersionUID = 1L; + + private Sample optional; + + public NestedSample(Sample optional) { + this.optional = optional; + } + + public Sample getOptional() { + return optional; + } + + public void setOptional(Sample optional) { + this.optional = optional; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java new file mode 100644 index 0000000000..fed3639c64 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java @@ -0,0 +1,61 @@ +package com.baeldung.deserializationfilters.pojo; + +public class Sample implements ContextSpecific, Comparable { + private static final long serialVersionUID = 1L; + + private int[] array; + private String name; + private NestedSample nested; + + public Sample(String name) { + this.name = name; + } + + public Sample(int[] array) { + this.array = array; + } + + public Sample(NestedSample nested) { + this.nested = nested; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int[] getArray() { + return array; + } + + public void setArray(int[] array) { + this.array = array; + } + + public NestedSample getNested() { + return nested; + } + + public void setNested(NestedSample nested) { + this.nested = nested; + } + + @Override + public String toString() { + return name; + } + + @Override + public int compareTo(Sample o) { + if (name == null) + return -1; + + if (o == null || o.getName() == null) + return 1; + + return getName().compareTo(o.getName()); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java new file mode 100644 index 0000000000..24dce289c6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java @@ -0,0 +1,25 @@ +package com.baeldung.deserializationfilters.pojo; + +public class SampleExploit extends Sample { + private static final long serialVersionUID = 1L; + + public SampleExploit() { + super("exploit"); + } + + public static void maliciousCode() { + System.out.println("exploit executed"); + } + + @Override + public String toString() { + maliciousCode(); + return "exploit"; + } + + @Override + public int compareTo(Sample o) { + maliciousCode(); + return super.compareTo(o); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java new file mode 100644 index 0000000000..9a66cb0e91 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java @@ -0,0 +1,11 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public interface DeserializationService { + + Set process(InputStream... inputStreams); +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java new file mode 100644 index 0000000000..3aadbe7111 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LimitedArrayService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java new file mode 100644 index 0000000000..69350c1399 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java @@ -0,0 +1,20 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.io.ObjectInputFilter; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LowDepthService implements DeserializationService { + + public Set process(ObjectInputFilter filter, InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(filter, inputStreams); + } + + @Override + public Set process(InputStream... inputStreams) { + return process(null, inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java new file mode 100644 index 0000000000..a0690276b7 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class SmallObjectService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java new file mode 100644 index 0000000000..54db823102 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java @@ -0,0 +1,50 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputFilter; +import java.io.ObjectInputStream; +import java.util.Set; +import java.util.TreeSet; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public class DeserializationUtils { + private DeserializationUtils() { + } + + public static Object deserialize(InputStream inStream) { + return deserialize(inStream, null); + } + + public static Object deserialize(InputStream inStream, ObjectInputFilter filter) { + try (ObjectInputStream in = new ObjectInputStream(inStream)) { + if (filter != null) { + in.setObjectInputFilter(filter); + } + return in.readObject(); + } catch (InvalidClassException e) { + return null; + } catch (Throwable e) { + e.printStackTrace(); + return null; + } + } + + public static Set deserializeIntoSet(InputStream... inputStreams) { + return deserializeIntoSet(null, inputStreams); + } + + public static Set deserializeIntoSet(ObjectInputFilter filter, InputStream... inputStreams) { + Set set = new TreeSet<>(); + + for (InputStream inputStream : inputStreams) { + Object object = deserialize(inputStream, filter); + if (object != null) { + set.add((ContextSpecific) object); + } + } + + return set; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java new file mode 100644 index 0000000000..fac69a94b9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java @@ -0,0 +1,32 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.ObjectInputFilter; + +public class FilterUtils { + + private static final String DEFAULT_PACKAGE_PATTERN = "java.base/*;!*"; + private static final String POJO_PACKAGE = "com.baeldung.deserializationfilters.pojo"; + + private FilterUtils() { + } + + private static ObjectInputFilter baseFilter(String parameter, int max) { + return ObjectInputFilter.Config.createFilter(String.format("%s=%d;%s.**;%s", parameter, max, POJO_PACKAGE, DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter fallbackFilter() { + return ObjectInputFilter.Config.createFilter(String.format("%s", DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter safeSizeFilter(int max) { + return baseFilter("maxbytes", max); + } + + public static ObjectInputFilter safeArrayFilter(int max) { + return baseFilter("maxarray", max); + } + + public static ObjectInputFilter safeDepthFilter(int max) { + return baseFilter("maxdepth", max); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java new file mode 100644 index 0000000000..4f62e5d46b --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +public class SerializationUtils { + + private SerializationUtils() { + } + + public static void serialize(Object object, OutputStream outStream) throws IOException { + try (ObjectOutputStream objStream = new ObjectOutputStream(outStream)) { + objStream.writeObject(object); + } + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java new file mode 100644 index 0000000000..3e7de20070 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java @@ -0,0 +1,119 @@ +package com.baeldung.deserializationfilters; + +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputFilter; +import java.util.Set; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.pojo.NestedSample; +import com.baeldung.deserializationfilters.pojo.Sample; +import com.baeldung.deserializationfilters.pojo.SampleExploit; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; +import com.baeldung.deserializationfilters.utils.FilterUtils; +import com.baeldung.deserializationfilters.utils.SerializationUtils; + +public class ContextSpecificDeserializationFilterIntegrationTest { + + private static ByteArrayOutputStream serialSampleA = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleA = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleB = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleB = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleC = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleC = new ByteArrayOutputStream(); + + private static ByteArrayInputStream bytes(ByteArrayOutputStream stream) { + return new ByteArrayInputStream(stream.toByteArray()); + } + + @BeforeAll + static void setup() throws IOException { + ObjectInputFilter.Config.setSerialFilterFactory(new ContextSpecificDeserializationFilterFactory()); + + SerializationUtils.serialize(new Sample("simple"), serialSampleA); + SerializationUtils.serialize(new SampleExploit(), serialBigSampleA); + + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3 }), serialSampleB); + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3, 4, 5, 6 }), serialBigSampleB); + + SerializationUtils.serialize(new Sample(new NestedSample(null)), serialSampleC); + SerializationUtils.serialize(new Sample(new NestedSample(new Sample("deep"))), serialBigSampleC); + } + + @Test + void whenSmallObjectContext_thenCorrectFilterApplied() { + Set result = new SmallObjectService().process( // + bytes(serialSampleA), // + bytes(serialBigSampleA)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void whenLimitedArrayContext_thenCorrectFilterApplied() { + Set result = new LimitedArrayService().process( // + bytes(serialSampleB), // + bytes(serialBigSampleB)); + + assertEquals(1, result.size()); + } + + @Test + void whenLowDepthContext_thenCorrectFilterApplied() { + Set result = new LowDepthService().process( // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + } + + @Test + void givenExtraFilter_whenCombinedContext_thenMergedFiltersApplied() { + Set result = new LowDepthService().process( // + FilterUtils.safeSizeFilter(190), // + bytes(serialSampleA), // + bytes(serialBigSampleA), // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void givenFallbackContext_whenUsingBaseClasses_thenRestrictiveFilterApplied() throws IOException { + String a = new String("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + String deserializedA = (String) DeserializationUtils.deserialize(bytes(outStream)); + + assertEquals(a, deserializedA); + } + + @Test + void givenFallbackContext_whenUsingAppClasses_thenRejected() throws IOException { + Sample a = new Sample("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + Sample deserializedA = (Sample) DeserializationUtils.deserialize(bytes(outStream)); + + assertNull(deserializedA); + } +} From 290147ff08d2d194a8a054a98301f51dc069f3a6 Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Fri, 17 Nov 2023 00:27:43 +0200 Subject: [PATCH 242/283] This PR is related to BAEL-7181 (#15230) * Update TimestampToLongUnitTest.java * Update TimestampToLong.java --- .../timestamptolong/TimestampToLong.java | 31 +++++++-------- .../TimestampToLongUnitTest.java | 39 +++++++------------ 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java index 2ebe30f4ff..25a8a57ba7 100644 --- a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java @@ -1,32 +1,31 @@ package com.baeldung.timestamptolong; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; public class TimestampToLong { - public void usingSimpleDateFormat() throws ParseException { + + public long usingSimpleDateFormat(String timestampString) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String currentDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - long actualTimestamp = sdf.parse(currentDateString).getTime(); + Date date = sdf.parse(timestampString); + String currentDateString = sdf.format(date); + return sdf.parse(currentDateString).getTime(); } - public void usingInstantClass() { - Instant instant = Instant.now(); - long actualTimestamp = instant.toEpochMilli(); + public long usingInstantClass(String timestampString) { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); + return instant.toEpochMilli(); } - public void usingTimestamp() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); + public long usingJava8DateTime(String timestampString) { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); + return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } - - public void usingJava8DateTime() { - LocalDateTime localDateTime = LocalDateTime.now(); - long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - } -} \ No newline at end of file +} diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java index ede8f7792d..868d019cf2 100644 --- a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java @@ -2,51 +2,42 @@ package com.baeldung.timestamptolong; import org.junit.Test; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; public class TimestampToLongUnitTest { - - private static final long TOLERANCE = 1000; + private static final String timestampString = "2023-11-15 01:02:03"; @Test - public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException { + public void givenSimpleDateFormat_whenFormattingDate_thenConvertToLong() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = sdf.parse(timestampString); - String currentDateString = sdf.format(new Date()); + String currentDateString = sdf.format(date); long actualTimestamp = sdf.parse(currentDateString).getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() { - Instant instant = Instant.now(); + public void givenInstantClass_whenGettingTimestamp_thenConvertToLong() { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); long actualTimestamp = instant.toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenTimestamp_whenCreatingTimestamp_thenTConvertToLong() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); - } - - @Test - public void givenJava8DateTime_whenGettingTimestamp_thenTConvertToLong() { - LocalDateTime localDateTime = LocalDateTime.now(); + public void givenJava8DateTime_whenGettingTimestamp_thenConvertToLong() { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } } From 9d441e11b8d53128f733643e3333809564ac6268 Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Fri, 17 Nov 2023 01:47:49 +0200 Subject: [PATCH 243/283] This commit is related to the article BAEL-7172 (#15232) This commit aims to add two classes that provide insights about the time complexity of Collections.sort(). --- .../CollectionsSortTimeComplexityJMH.java | 60 +++++++++++++++++++ .../CollectionsSortTimeComplexityMain.java | 33 ++++++++++ 2 files changed, 93 insertions(+) create mode 100644 core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java create mode 100644 core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java new file mode 100644 index 0000000000..766a89f674 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java @@ -0,0 +1,60 @@ +package com.baeldung.collectionssortcomplexity; + +import org.openjdk.jmh.annotations.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 1, warmups = 1) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +public class CollectionsSortTimeComplexityJMH { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + + } + + @Benchmark + public void measureCollectionsSortBestCase(BestCaseBenchmarkState state) { + List sortedList = new ArrayList<>(state.sortedList); + Collections.sort(sortedList); + } + + @Benchmark + public void measureCollectionsSortAverageWorstCase(AverageWorstCaseBenchmarkState state) { + List unsortedList = new ArrayList<>(state.unsortedList); + Collections.sort(unsortedList); + } + + @State(Scope.Benchmark) + public static class BestCaseBenchmarkState { + List sortedList; + + @Setup(Level.Trial) + public void setUp() { + sortedList = new ArrayList<>(); + for (int i = 1; i <= 1000000; i++) { + sortedList.add(i); + } + } + } + + @State(Scope.Benchmark) + public static class AverageWorstCaseBenchmarkState { + List unsortedList; + + @Setup(Level.Trial) + public void setUp() { + unsortedList = new ArrayList<>(); + for (int i = 1000000; i > 0; i--) { + unsortedList.add(i); + } + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java new file mode 100644 index 0000000000..f273d3562a --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java @@ -0,0 +1,33 @@ +package com.baeldung.collectionssortcomplexity; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class CollectionsSortTimeComplexityMain { + // O(n log n) Time Complexity Example + public static void worstAndAverageCasesTimeComplexity() { + Integer[] sortedArray = {20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31, 18, 19, 32, 33, 34, 27, 35}; + List list = Arrays.asList(sortedArray); + Collections.shuffle(list); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n log n): " + (endTime - startTime) + " nanoseconds"); + } + + // O(n) Time Complexity Example + public static void bestCaseTimeComplexity() { + Integer[] sortedArray = {19, 22, 19, 22, 24, 25, 17, 11, 22, 23, 28, 23, 0, 1, 12, 9, 13, 27, 15}; + List list = Arrays.asList(sortedArray); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n): " + (endTime - startTime) + " nanoseconds"); + } + + public static void main(String[] args) { + worstAndAverageCasesTimeComplexity(); + bestCaseTimeComplexity(); + } +} From e5215678f385ee012464311a3064835c70129325 Mon Sep 17 00:00:00 2001 From: timis1 Date: Thu, 16 Nov 2023 09:17:03 +0200 Subject: [PATCH 244/283] JAVA-27449 Fix test in libraries-data-io module --- .../com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java index 7cfe8984e7..6745b9be7f 100644 --- a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java +++ b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java @@ -74,7 +74,7 @@ public class OpenCsvIntegrationTest { assertThat(contents.split(NEW_LINE)) .containsExactly( - "'colA','colB','colC'", + "'COLA','COLB','COLC'", "'Test1','sample','data'", "'Test2','ipso','facto'" ); From 7f88b9748e82bd6b51f37ae9bfb6981a062a9b98 Mon Sep 17 00:00:00 2001 From: Maiklins Date: Fri, 17 Nov 2023 21:24:13 +0100 Subject: [PATCH 245/283] Update and rename ProfileIntegrationStubTest.java to ProfileStubIntegrationTest.java Satisfy test naming convention --- ...IntegrationStubTest.java => ProfileStubIntegrationTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationStubTest.java => ProfileStubIntegrationTest.java} (97%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java similarity index 97% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java index e1c88f2a31..2d6eb06d32 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java @@ -18,7 +18,7 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc @ActiveProfiles("stub") -class ProfileIntegrationStubTest { +class ProfileStubIntegrationTest { @Autowired private MockMvc mockMvc; From 92ef912fcf29b2fd755560dad3fdcdf67a89fb59 Mon Sep 17 00:00:00 2001 From: Maiklins Date: Fri, 17 Nov 2023 21:24:57 +0100 Subject: [PATCH 246/283] Update and rename ProfileIntegrationMockTest.java to ProfileMockIntegrationTest.java Satisfy naming convention --- ...IntegrationMockTest.java => ProfileMockIntegrationTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationMockTest.java => ProfileMockIntegrationTest.java} (97%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java similarity index 97% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java index 43fb69860d..2fac6d954a 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java @@ -20,7 +20,7 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc @ActiveProfiles("mock") -class ProfileIntegrationMockTest { +class ProfileMockIntegrationTest { @Autowired private MockMvc mockMvc; From 6cbd1b5b5229d8839b265f41590580570e56f94b Mon Sep 17 00:00:00 2001 From: mikr Date: Fri, 17 Nov 2023 21:32:43 +0100 Subject: [PATCH 247/283] Update readme --- spring-boot-modules/spring-boot-testing-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-testing-2/README.md b/spring-boot-modules/spring-boot-testing-2/README.md index 1baf83bf34..fbf708381b 100644 --- a/spring-boot-modules/spring-boot-testing-2/README.md +++ b/spring-boot-modules/spring-boot-testing-2/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot – Testing Redis With Testcontainers](https://www.baeldung.com/spring-boot-redis-testcontainers) - [Spring Boot – Keycloak Integration Testing with Testcontainers](https://www.baeldung.com/spring-boot-keycloak-integration-testing) - [Difference Between @Spy and @SpyBean](https://www.baeldung.com/spring-spy-vs-spybean) +- [Overriding Spring Beans in Integration Test](https://www.baeldung.com/overriding-spring-beans-in-integration-test) - More articles: [[<-- prev]](../spring-boot-testing) From c9321ed9be544b1444d99d43efa02042dece6e49 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:51:09 +0800 Subject: [PATCH 248/283] Update README.md [skip ci] --- patterns-modules/design-patterns-singleton/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/patterns-modules/design-patterns-singleton/README.md b/patterns-modules/design-patterns-singleton/README.md index edec116b93..a4915ebfaf 100644 --- a/patterns-modules/design-patterns-singleton/README.md +++ b/patterns-modules/design-patterns-singleton/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [How to Serialize a Singleton in Java](https://www.baeldung.com/java-serialize-singleton) +- [Bill Pugh Singleton Implementation](https://www.baeldung.com/java-bill-pugh-singleton-implementation) From e264651cfb45520cf11754df075734eae22eb650 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:53:19 +0800 Subject: [PATCH 249/283] Update README.md [skip ci] --- core-java-modules/core-java-io-conversions-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md index 4e179a84d2..bcc1db5f89 100644 --- a/core-java-modules/core-java-io-conversions-2/README.md +++ b/core-java-modules/core-java-io-conversions-2/README.md @@ -12,4 +12,5 @@ This module contains articles about core Java input/output(IO) conversions. - [How to Convert InputStream to Base64 String](https://www.baeldung.com/java-inputstream-to-base64-string) - [Convert an OutputStream to an InputStream](https://www.baeldung.com/java-convert-outputstream-to-inputstream) - [Java PrintStream to String](https://www.baeldung.com/java-printstream-to-string) +- [Convert File to Byte Array in Java](https://www.baeldung.com/java-convert-file-byte-array) - More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions) From a4ac49de8159bf845a8b259ad716293df789bd60 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:56:47 +0800 Subject: [PATCH 250/283] Update README.md [skip ci] --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 28e2dccd39..b95153b5be 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -3,3 +3,4 @@ - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) +- [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) From c921fdcc1981ef629b1f67d0dacd91f9073a7c5f Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:59:00 +0800 Subject: [PATCH 251/283] Update README.md [skip ci] --- core-java-modules/core-java-hex/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-hex/README.md b/core-java-modules/core-java-hex/README.md index 0ba4d1372f..2424137b32 100644 --- a/core-java-modules/core-java-hex/README.md +++ b/core-java-modules/core-java-hex/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Convert Hex to RGB Using Java](https://www.baeldung.com/java-convert-hex-to-rgb) +- [Convert a Hex String to an Integer in Java](https://www.baeldung.com/java-convert-hex-string-to-integer) From 23830bfd79bd091ae8b7ec26b1133333edce5da2 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:02:24 +0800 Subject: [PATCH 252/283] Update README.md [skip ci] --- spring-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-kafka-2/README.md b/spring-kafka-2/README.md index 318312ace6..43b2f59147 100644 --- a/spring-kafka-2/README.md +++ b/spring-kafka-2/README.md @@ -8,3 +8,4 @@ This module contains articles about Spring with Kafka - [Spring Kafka: Configure Multiple Listeners on Same Topic](https://www.baeldung.com/spring-kafka-multiple-listeners-same-topic) - [Understanding Kafka Topics and Partitions](https://www.baeldung.com/kafka-topics-partitions) - [How to Subscribe a Kafka Consumer to Multiple Topics](https://www.baeldung.com/kafka-subscribe-consumer-multiple-topics) +- [Splitting Streams in Kafka](https://www.baeldung.com/kafka-splitting-streams) From de92bcb45d6a25dad5cf1991cc419fb41e154ad3 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:06:22 +0800 Subject: [PATCH 253/283] Update README.md [skip ci] --- core-java-modules/core-java-numbers-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-numbers-6/README.md b/core-java-modules/core-java-numbers-6/README.md index cf84e29710..3a2154efdd 100644 --- a/core-java-modules/core-java-numbers-6/README.md +++ b/core-java-modules/core-java-numbers-6/README.md @@ -7,4 +7,5 @@ - [Java Double vs. BigDecimal](https://www.baeldung.com/java-double-vs-bigdecimal) - [Finding the Square Root of a BigInteger in Java](https://www.baeldung.com/java-find-square-root-biginteger) - [Truncate a Double to Two Decimal Places in Java](https://www.baeldung.com/java-double-round-two-decimal-places) +- [Comparing the Values of Two Generic Numbers in Java](https://www.baeldung.com/java-generic-numbers-comparison-methods) - More articles: [[<-- prev]](../core-java-numbers-5) From 2d538b658253fb44713bc117ad9f5dac580e1ca6 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:08:25 +0800 Subject: [PATCH 254/283] Update README.md [skip ci] --- testing-modules/selenium-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/testing-modules/selenium-2/README.md b/testing-modules/selenium-2/README.md index 5403fb9f06..a1d180814d 100644 --- a/testing-modules/selenium-2/README.md +++ b/testing-modules/selenium-2/README.md @@ -2,6 +2,7 @@ - [Running Selenium Scripts with JMeter](https://www.baeldung.com/selenium-jmeter) - [Fixing Selenium WebDriver Executable Path Error](https://www.baeldung.com/java-selenium-webdriver-path-error) - [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait) +- [Switching Between Frames Using Selenium WebDriver in Java](https://www.baeldung.com/java-selenium-change-frames) #### Notes: - to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described From 8459887d19faa6734e0263a8d774784d5d1e1d4c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:10:58 +0800 Subject: [PATCH 255/283] Update README.md [skip ci] --- core-java-modules/core-java-sun/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 107035cbe8..54eae58d3e 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -5,4 +5,5 @@ This module contains articles about the sun package ### Relevant Articles: - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) -- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) \ No newline at end of file +- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) +- [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) From f589231fde9f5bb62ba2df6495d314e0e47accc1 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:14:42 +0800 Subject: [PATCH 256/283] Update README.md [skip ci] --- core-java-modules/core-java-collections-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 4869158d2b..acee8154f7 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -9,4 +9,5 @@ - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) +- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) From e5fbd59087857f3940e45e308be553f47f3ec107 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:17:12 +0800 Subject: [PATCH 257/283] Create README.md [skip ci] --- persistence-modules/core-java-persistence-3/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 persistence-modules/core-java-persistence-3/README.md diff --git a/persistence-modules/core-java-persistence-3/README.md b/persistence-modules/core-java-persistence-3/README.md new file mode 100644 index 0000000000..6ca158560b --- /dev/null +++ b/persistence-modules/core-java-persistence-3/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Convert ResultSet Into Map](https://www.baeldung.com/java-resultset-map) From 47b2fef64f2d6a535073e06be9339a9ad014e43b Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:20:17 +0800 Subject: [PATCH 258/283] Update README.md [skip ci] --- persistence-modules/spring-boot-persistence-mongodb-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/README.md b/persistence-modules/spring-boot-persistence-mongodb-3/README.md index ee6a96397a..e234c2b3a1 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb-3/README.md @@ -1,4 +1,5 @@ # Relevant Articles - [How to Insert a HashMap Into MongoDB With Java?](https://www.baeldung.com/java-mongodb-insert-hashmap) - [MongoDB – Field Level Encryption](https://www.baeldung.com/mongodb-field-level-encryption) +- [MongoDB Atlas Search Using the Java Driver and Spring Data](https://www.baeldung.com/mongodb-spring-data-atlas-search) - More articles: [[<--prev]](../spring-boot-persistence-mongodb-2) From 3a3459f2b804a2ef5ee56700b83cd35141f18f23 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:22:32 +0800 Subject: [PATCH 259/283] Update README.md [skip ci] --- core-java-modules/core-java-sun/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 54eae58d3e..82977bca6c 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -7,3 +7,4 @@ This module contains articles about the sun package - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) - [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) - [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) +- [Sharing Memory Between JVMs](https://www.baeldung.com/java-sharing-memory-between-jvms) From ccba711e86815cbb9bdd717ac863b9a70c43fad7 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:24:21 +0800 Subject: [PATCH 260/283] Update README.md [skip ci] --- core-java-modules/core-java-concurrency-basic-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 09d085a32b..1021544e11 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -12,4 +12,5 @@ This module contains articles about basic Java concurrency. - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert) +- [Synchronize a Static Variable Among Different Threads](https://www.baeldung.com/java-synchronize-static-variable-different-threads) - [[<-- Prev]](../core-java-concurrency-basic-2) From 2d7f1c60a7128a96aa347d435985cd61207819f3 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:26:37 +0800 Subject: [PATCH 261/283] Update README.md [skip ci] --- core-java-modules/core-java-console/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-console/README.md b/core-java-modules/core-java-console/README.md index 180193d8c1..77ad16d015 100644 --- a/core-java-modules/core-java-console/README.md +++ b/core-java-modules/core-java-console/README.md @@ -7,3 +7,4 @@ - [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java) - [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out) - [How to Log to the Console in Color](https://www.baeldung.com/java-log-console-in-color) +- [Create Table Using ASCII in a Console in Java](https://www.baeldung.com/java-console-ascii-make-table) From cf421052d972731820f5c9e74b87b457227ba116 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:30:06 +0800 Subject: [PATCH 262/283] Update README.md [skip ci] --- core-java-modules/core-java-8-datetime-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 462a4be6f1..f7ada52da6 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -7,4 +7,5 @@ - [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins) - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) +- [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) From b62d0436d4de59f26ece1b2808c2ecf5105963eb Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:33:12 +0800 Subject: [PATCH 263/283] Update README.md [skip ci] --- core-java-modules/core-java-streams-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 64bc4e6b7a..dfd5a649b5 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -7,3 +7,4 @@ - [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams) - [Modifying Objects Within Stream While Iterating](https://www.baeldung.com/java-stream-modify-objects-during-iteration) - [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) +- [How to Avoid NoSuchElementException in Stream API](https://www.baeldung.com/java-streams-api-avoid-nosuchelementexception) From 66b8dc1411c5c82db4fc431859dde3e128eb248e Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:35:11 +0800 Subject: [PATCH 264/283] Update README.md [skip ci] --- apache-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index 40ee701be1..3aa8fcf4ad 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -14,3 +14,4 @@ You can build the project from the command line using: *mvn clean install*, or i - [Get Partition Count for a Topic in Kafka](https://www.baeldung.com/java-kafka-partition-count-topic) - [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server) - [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka) +- [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering) From 607fc54bf009a23551a107dc2bcd3f45ba66280c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:48:00 +0800 Subject: [PATCH 265/283] Update README.md --- core-java-modules/core-java-string-operations-6/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java-modules/core-java-string-operations-6/README.md b/core-java-modules/core-java-string-operations-6/README.md index 9d92552dd1..506b548304 100644 --- a/core-java-modules/core-java-string-operations-6/README.md +++ b/core-java-modules/core-java-string-operations-6/README.md @@ -11,4 +11,3 @@ - [Check if a String Has All Unique Characters in Java](https://www.baeldung.com/java-check-string-all-unique-chars) - [Performance Comparison Between Different Java String Concatenation Methods](https://www.baeldung.com/java-string-concatenation-methods) - [Replacing Single Quote with \’ in Java String](https://www.baeldung.com/java-replacing-single-quote-string) -- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) From cf51f27dfc3bf62af25ef71b3a6b6e42ba510ec1 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:48:36 +0800 Subject: [PATCH 266/283] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index b95153b5be..2b9c4c25f3 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -4,3 +4,4 @@ - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) - [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) +- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) From 80da8b957d2633c47de5973dd062722ada1b6312 Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Sun, 19 Nov 2023 11:48:20 +0100 Subject: [PATCH 267/283] JAVA-13263 | individual build (#15221) * JAVA-13263 | individual build * JAVA-13263 | updating wrapper to more recent version of gradle 7 * JAVA-13263 | adding wrapper jar --- gradle-modules/.gitignore | 1 + gradle-modules/gradle-5/README.md | 2 + .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 +- gradle-modules/gradle/gradle/shipkit.gradle | 41 ------------------ .../gradle/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 ++- 10 files changed, 11 insertions(+), 45 deletions(-) create mode 100644 gradle-modules/.gitignore create mode 100644 gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle/gradle/shipkit.gradle create mode 100644 gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle-modules/.gitignore b/gradle-modules/.gitignore new file mode 100644 index 0000000000..63b7142f43 --- /dev/null +++ b/gradle-modules/.gitignore @@ -0,0 +1 @@ +!gradle-wrapper.jar \ No newline at end of file diff --git a/gradle-modules/gradle-5/README.md b/gradle-modules/gradle-5/README.md index 7871c0e822..6d701ac43c 100644 --- a/gradle-modules/gradle-5/README.md +++ b/gradle-modules/gradle-5/README.md @@ -1,5 +1,7 @@ ### Relevant Articles: +This module is using gradle-8.3. + - [Run a Java main Method Using Gradle](https://www.baeldung.com/gradle-run-java-main) - [Finding Unused Gradle Dependencies](https://www.baeldung.com/gradle-finding-unused-dependencies) - [Intro to Gradle Lint Plugin](https://www.baeldung.com/java-gradle-lint-intro) diff --git a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties index 94920145f3..cd141cfc9d 100644 --- a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists + diff --git a/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties index 774fae8767..878fe049c2 100644 --- a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle/gradle/shipkit.gradle b/gradle-modules/gradle/gradle/shipkit.gradle deleted file mode 100644 index 144c01dc05..0000000000 --- a/gradle-modules/gradle/gradle/shipkit.gradle +++ /dev/null @@ -1,41 +0,0 @@ -//This default Shipkit configuration file was created automatically and is intended to be checked-in. -//Default configuration is sufficient for local testing and trying out Shipkit. -//To leverage Shipkit fully, please fix the TODO items, refer to our Getting Started Guide for help: -// -// https://github.com/mockito/shipkit/blob/master/docs/getting-started.md -// -shipkit { - //TODO is the repository correct? - gitHub.repository = "unspecified-user/unspecified-repo" - - //TODO generate and use your own read-only GitHub personal access token - gitHub.readOnlyAuthToken = "76826c9ec886612f504d12fd4268b16721c4f85d" - - //TODO generate GitHub write token, and ensure your Travis CI has this env variable exported - gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") -} - -allprojects { - plugins.withId("com.jfrog.bintray") { - - //Bintray configuration is handled by JFrog Bintray Gradle Plugin - //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin - bintray { - - //TODO sign up for free open source account with https://bintray.com, then look up your API key on your profile page in Bintray - key = '7ea297848ca948adb7d3ee92a83292112d7ae989' - //TODO don't check in the key, remove above line and use env variable exported on CI: - //key = System.getenv("BINTRAY_API_KEY") - - pkg { - //TODO configure Bintray settings per your project (https://github.com/bintray/gradle-bintray-plugin) - repo = 'bootstrap' - user = 'shipkit-bootstrap-bot' - userOrg = 'shipkit-bootstrap' - name = 'maven' - licenses = ['MIT'] - labels = ['continuous delivery', 'release automation', 'shipkit'] - } - } - } -} diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties index ebf7ae9184..3fa8f862f7 100644 --- a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Thu Oct 12 16:43:02 BDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip From 3371e4fe5311c59f9797f0fd23c30b0d2872ce85 Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Sun, 19 Nov 2023 20:27:45 +0100 Subject: [PATCH 268/283] BAEL-6718: Setting a Spring Bean to Null (#15242) * BAEL-6718: Setting a Spring Bean to Null * BAEL-6718: Java Nullable Example --- .../baeldung/nullablebean/MainComponent.java | 21 ++++ .../baeldung/nullablebean/SubComponent.java | 8 ++ .../nonrequired/NonRequiredConfiguration.java | 8 ++ .../nonrequired/NonRequiredMainComponent.java | 19 ++++ .../nonrequired/NonRequiredSubComponent.java | 5 + .../NullableJavaConfiguration.java | 9 ++ .../nullablejava/NullableMainComponent.java | 22 +++++ .../nullablejava/NullableSubComponent.java | 5 + .../nullablespring/NullableConfiguration.java | 20 ++++ .../NullableSupplierConfiguration.java | 21 ++++ .../optionable/OptionableConfiguration.java | 17 ++++ .../NullableXMLComponentUnitTest.java | 95 +++++++++++++++++++ .../non-nullable-application-context.xml | 10 ++ ...-configurable-spel-application-context.xml | 14 +++ .../test/resources/non-nullable.properties | 1 + .../nullable-application-context.xml | 11 +++ ...-configurable-spel-application-context.xml | 14 +++ .../nullable-spel-application-context.xml | 9 ++ .../src/test/resources/nullable.properties | 1 + 19 files changed, 310 insertions(+) create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java create mode 100644 spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java create mode 100644 spring-di-4/src/test/resources/non-nullable-application-context.xml create mode 100644 spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/non-nullable.properties create mode 100644 spring-di-4/src/test/resources/nullable-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable.properties diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java new file mode 100644 index 0000000000..9f97b108da --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class MainComponent { + + private SubComponent subComponent; + + public MainComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } + + public SubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java new file mode 100644 index 0000000000..b171d28db4 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class SubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java new file mode 100644 index 0000000000..d34479a565 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan +public class NonRequiredConfiguration { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java new file mode 100644 index 0000000000..f181d2068d --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java @@ -0,0 +1,19 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NonRequiredMainComponent { + + @Autowired(required = false) + private NonRequiredSubComponent subComponent; + + public NonRequiredSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NonRequiredSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java new file mode 100644 index 0000000000..6678880a24 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nonrequired; + +public class NonRequiredSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java new file mode 100644 index 0000000000..c13dbe3363 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java @@ -0,0 +1,9 @@ +package com.baeldung.nullablebean.nullablejava; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +public class NullableJavaConfiguration { +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java new file mode 100644 index 0000000000..f35ead7477 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java @@ -0,0 +1,22 @@ +package com.baeldung.nullablebean.nullablejava; + +import jakarta.annotation.Nullable; +import org.springframework.stereotype.Component; + +@Component +public class NullableMainComponent { + + private NullableSubComponent subComponent; + + public NullableMainComponent(final @Nullable NullableSubComponent subComponent) { + this.subComponent = subComponent; + } + + public NullableSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NullableSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java new file mode 100644 index 0000000000..c3cbd78c43 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nullablejava; + +public class NullableSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java new file mode 100644 index 0000000000..17942d31cd --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java @@ -0,0 +1,20 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableConfiguration { + + @Bean + public MainComponent mainComponent(SubComponent subComponent) { + return new MainComponent(subComponent); + } + + @Bean + public SubComponent subComponent() { + return null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java new file mode 100644 index 0000000000..debaa60fa9 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.function.Supplier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableSupplierConfiguration { + + @Bean + public MainComponent mainComponent(Supplier subComponentSupplier) { + return new MainComponent(subComponentSupplier.get()); + } + + @Bean + public Supplier subComponentSupplier() { + return () -> null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java new file mode 100644 index 0000000000..fd54553e8c --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java @@ -0,0 +1,17 @@ +package com.baeldung.nullablebean.optionable; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.Optional; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OptionableConfiguration { + + @Bean + public MainComponent mainComponent(Optional optionalSubComponent) { + return new MainComponent(optionalSubComponent.orElse(null)); + } + +} diff --git a/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java new file mode 100644 index 0000000000..2997da478c --- /dev/null +++ b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.nullablebean; + +import static org.junit.jupiter.api.Assertions.*; + +import com.baeldung.nullablebean.nonrequired.NonRequiredConfiguration; +import com.baeldung.nullablebean.nonrequired.NonRequiredMainComponent; +import com.baeldung.nullablebean.nullablejava.NullableJavaConfiguration; +import com.baeldung.nullablebean.nullablejava.NullableMainComponent; +import com.baeldung.nullablebean.nullablespring.NullableConfiguration; +import com.baeldung.nullablebean.nullablespring.NullableSupplierConfiguration; +import com.baeldung.nullablebean.optionable.OptionableConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +class NullableXMLComponentUnitTest { + + @Test + void givenContextWhenCreatingNullableMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableJavaConfiguration.class); + final NullableMainComponent bean = context.getBean(NullableMainComponent.class); + assertNull(bean.getSubComponent()); + } + @Test + void givenNonRequiredContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NonRequiredConfiguration.class); + final NonRequiredMainComponent bean = context.getBean(NonRequiredMainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenOptionableContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + OptionableConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSupplierContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableSupplierConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableContextWhenCreatingMainComponentThenSubComponentIsNull() { + assertThrows(UnsatisfiedDependencyException.class, () -> new AnnotationConfigApplicationContext( + NullableConfiguration.class)); + } + + @Test + void givenNullableXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNonNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } + + @Test + void givenXMLContextWhenCreatingMainComponentThenSubComponentNotNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } +} \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-application-context.xml b/spring-di-4/src/test/resources/non-nullable-application-context.xml new file mode 100644 index 0000000000..07a8115bac --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-application-context.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..8a7b107ee4 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable.properties b/spring-di-4/src/test/resources/non-nullable.properties new file mode 100644 index 0000000000..76b127a2e5 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable.properties @@ -0,0 +1 @@ +nullableBean = subComponent \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-application-context.xml b/spring-di-4/src/test/resources/nullable-application-context.xml new file mode 100644 index 0000000000..9794dbbfff --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-application-context.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..f6f04a6289 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-spel-application-context.xml new file mode 100644 index 0000000000..c0a14b4cbb --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-spel-application-context.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable.properties b/spring-di-4/src/test/resources/nullable.properties new file mode 100644 index 0000000000..315f9b0d03 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable.properties @@ -0,0 +1 @@ +nullableBean = null \ No newline at end of file From 684a14ce5f29d574486e8846c12d88d7575b88af Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Mon, 20 Nov 2023 01:06:51 +0530 Subject: [PATCH 269/283] [BAEL-6787] increment value of a map (#15243) Co-authored-by: Bhaskar --- .../core-java-collections-maps-7/pom.xml | 5 + .../com/baeldung/map/BenchmarkMapMethods.java | 70 ++++++++++++ .../baeldung/map/IncrementMapValueWays.java | 80 ++++++++++++++ .../map/IncrementMapValueUnitTest.java | 103 ++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java create mode 100644 core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java create mode 100644 core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-7/pom.xml b/core-java-modules/core-java-collections-maps-7/pom.xml index a7acded9cf..a05b1b3528 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -33,6 +33,11 @@ commons-csv ${csv.version}
+ + com.google.guava + guava + 32.1.2-jre + diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java new file mode 100644 index 0000000000..eca028efe4 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java @@ -0,0 +1,70 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; + +public class BenchmarkMapMethods { + public static void main(String[] args) { + BenchmarkMapMethods bmm = new BenchmarkMapMethods(); + Map map = new HashMap<>(); + map.put("Guava", bmm.benchMarkGuavaMap()); + map.put("ContainsKey", bmm.benchContainsKeyMap()); + map.put("MergeMethod", bmm.benchMarkMergeMethod()); + map.put("ComputeMethod", bmm.benchMarComputeMethod()); + map.put("GetOrDefault", bmm.benchMarkGetOrDefaultMethod()); + } + + private long benchMarkGuavaMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingAtomicMap(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchContainsKeyMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingContainsKey(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarComputeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingCompute(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkMergeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingMerge(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkGetOrDefaultMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingGetOrDefault(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private String getString() { + return + "Once upon a time in a quaint village nestled between rolling hills and whispering forests, there lived a solitary storyteller named Elias. Elias was known for spinning tales that transported listeners to magical realms and awakened forgotten dreams.\n" + + "\n" + + "His favorite spot was beneath an ancient oak tree, its sprawling branches offering shade to those who sought refuge from the bustle of daily life. Villagers of all ages would gather around Elias, their faces illuminated by the warmth of his stories.\n" + + "\n" + "One evening, as dusk painted the sky in hues of orange and purple, a curious young girl named Lily approached Elias. Her eyes sparkled with wonder as she asked for a tale unlike any other.\n" + "\n" + + "Elias smiled, sensing her thirst for adventure, and began a story about a forgotten kingdom veiled by mist, guarded by mystical creatures and enchanted by ancient spells. With each word, the air grew thick with anticipation, and the listeners were transported into a world where magic danced on the edges of reality.\n" + + "\n" + "As Elias weaved the story, Lily's imagination took flight. She envisioned herself as a brave warrior, wielding a shimmering sword against dark forces, her heart fueled by courage and kindness.\n" + "\n" + + "The night wore on, but the spell of the tale held everyone captive. The villagers laughed, gasped, and held their breaths, journeying alongside the characters through trials and triumphs.\n" + "\n" + + "As the final words lingered in the air, a sense of enchantment settled upon the listeners. They thanked Elias for the gift of his storytelling, each carrying a piece of the magical kingdom within their hearts.\n" + "\n" + + "Lily, inspired by the story, vowed to cherish the spirit of adventure and kindness in her own life. With a newfound spark in her eyes, she bid Elias goodnight, already dreaming of the countless adventures awaiting her.\n" + "\n" + + "Under the star-studded sky, Elias remained beneath the ancient oak, his heart aglow with the joy of sharing tales that ignited imagination and inspired dreams. And as the night embraced the village, whispers of the enchanted kingdom lingered in the breeze, promising endless possibilities to those who dared to believe."; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java new file mode 100644 index 0000000000..70b3c6c54d --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java @@ -0,0 +1,80 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.common.util.concurrent.AtomicLongMap; + +public class IncrementMapValueWays { + + public Map charFrequencyUsingContainsKey(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + int count = 0; + if (charMap.containsKey(sentence.charAt(c))) { + count = charMap.get(sentence.charAt(c)); + } + charMap.put(sentence.charAt(c), count + 1); + } + return charMap; + } + + public Map charFrequencyUsingGetOrDefault(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.put(sentence.charAt(c), charMap.getOrDefault(sentence.charAt(c), 0) + 1); + } + return charMap; + } + + public Map charFrequencyUsingMerge(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.merge(sentence.charAt(c), 1, Integer::sum); + } + return charMap; + } + + public Map charFrequencyUsingCompute(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyUsingAtomicMap(String sentence) { + AtomicLongMap map = AtomicLongMap.create(); + for (int c = 0; c < sentence.length(); c++) { + map.getAndIncrement(sentence.charAt(c)); + } + return map.asMap(); + } + + public Map charFrequencyWithConcurrentMap(String sentence, Map charMap) { + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrement(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.putIfAbsent(sentence.charAt(c), new AtomicInteger(0)); + charMap.get(sentence.charAt(c)) + .incrementAndGet(); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrementComputeIfAbsent(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.computeIfAbsent(sentence.charAt(c), k -> new AtomicInteger(0)) + .incrementAndGet(); + } + return charMap; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java new file mode 100644 index 0000000000..df4f2b787e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java @@ -0,0 +1,103 @@ +package com.baeldung.map; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +public class IncrementMapValueUnitTest { + + @Test + public void givenString_whenUsingContainsKey_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingContainsKey(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGetOrDefault_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingGetOrDefault(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapMerge_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingMerge(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapCompute_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingCompute(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGuava_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingAtomicMap(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap.keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGet_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrement(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGetAndComputeIfAbsent_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrementComputeIfAbsent(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingConcurrentMapCompute_thenReturnFreqMap() throws InterruptedException { + Map charMap = new ConcurrentHashMap<>(); + Thread thread1 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap("the quick brown", charMap); + }); + + Thread thread2 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap(" fox jumps over the lazy dog", charMap); + }); + + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, charMap); + } + + private Map getExpectedMap() { + return Stream.of( + new Object[][] { { ' ', 8 }, { 'a', 1 }, { 'b', 1 }, { 'c', 1 }, { 'd', 1 }, { 'e', 3 }, { 'f', 1 }, { 'g', 1 }, { 'h', 2 }, { 'i', 1 }, { 'j', 1 }, { 'k', 1 }, { 'l', 1 }, { 'm', 1 }, { 'n', 1 }, { 'o', 4 }, { 'p', 1 }, { 'q', 1 }, { 'r', 2 }, + { 's', 1 }, { 't', 2 }, { 'u', 2 }, { 'v', 1 }, { 'w', 1 }, { 'x', 1 }, { 'y', 1 }, { 'z', 1 } }) + .collect(Collectors.toMap(data -> (Character) data[0], data -> (Integer) data[1])); + } +} From a7ab16d81e505a46c56ca25fa60c89a72893416d Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 20 Nov 2023 03:14:46 -0300 Subject: [PATCH 270/283] BAEL-6566: Manage Kafka Consumer Groups (#15007) * test removing consumer * test removing consumer * wrapping up * fix main class * addressing request changes * introducing constants for numbers. optimizing imports * introducing class level constants * using constant naming conventions --- .../KafkaConsumerConfiguration.java | 37 ++++++++++++ .../KafkaProducerConfiguration.java | 35 ++++++++++++ .../KafkaTopicConfiguration.java | 30 ++++++++++ ...gingConsumerGroupsApplicationKafkaApp.java | 13 +++++ .../MessageConsumerService.java | 34 +++++++++++ ...ManagingConsumerGroupsIntegrationTest.java | 57 +++++++++++++++++++ 6 files changed, 206 insertions(+) create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java create mode 100644 spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java new file mode 100644 index 0000000000..04025bf484 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.DoubleDeserializer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaConsumerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ConsumerFactory kafkaConsumer() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, DoubleDeserializer.class); + return new DefaultKafkaConsumerFactory<>(props); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaConsumerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(kafkaConsumer()); + return factory; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java new file mode 100644 index 0000000000..b5b10e8301 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.DoubleSerializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaProducerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ProducerFactory kafkaProducer() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, DoubleSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaProducerTemplate() { + return new KafkaTemplate<>(kafkaProducer()); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java new file mode 100644 index 0000000000..1535f0c358 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.TopicBuilder; +import org.springframework.kafka.core.KafkaAdmin; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaTopicConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + public KafkaAdmin kafkaAdmin() { + Map configs = new HashMap<>(); + configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + return new KafkaAdmin(configs); + } + + public NewTopic celciusTopic() { + return TopicBuilder.name("topic-1") + .partitions(2) + .build(); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java new file mode 100644 index 0000000000..c5c990ff9d --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(value = {KafkaConsumerConfiguration.class, KafkaProducerConfiguration.class, KafkaTopicConfiguration.class}) +public class ManagingConsumerGroupsApplicationKafkaApp { + public static void main(String[] args) { + SpringApplication.run(ManagingConsumerGroupsApplicationKafkaApp.class, args); + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java new file mode 100644 index 0000000000..d010b19a80 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class MessageConsumerService { + + Map> consumedPartitions = new ConcurrentHashMap<>(); + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer0(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-0", consumerRecord); + } + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer1(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-1", consumerRecord); + } + + private void trackConsumedPartitions(String key, ConsumerRecord record) { + consumedPartitions.computeIfAbsent(key, k -> new HashSet<>()); + consumedPartitions.computeIfPresent(key, (k, v) -> { + v.add(record.partition()); + return v; + }); + } +} diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java new file mode 100644 index 0000000000..1620add9ca --- /dev/null +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.commons.lang3.RandomUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.config.KafkaListenerEndpointRegistry; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.listener.MessageListenerContainer; +import org.springframework.kafka.test.context.EmbeddedKafka; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = ManagingConsumerGroupsApplicationKafkaApp.class) +@EmbeddedKafka(partitions = 2, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"}) +public class ManagingConsumerGroupsIntegrationTest { + + private static final String CONSUMER_1_IDENTIFIER = "org.springframework.kafka.KafkaListenerEndpointContainer#1"; + private static final int TOTAL_PRODUCED_MESSAGES = 50000; + private static final int MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP = 10000; + + @Autowired + KafkaTemplate kafkaTemplate; + + @Autowired + KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry; + + @Autowired + MessageConsumerService consumerService; + + @Test + public void givenContinuousMessageFlow_whenAConsumerLeavesTheGroup_thenKafkaTriggersPartitionRebalance() throws InterruptedException { + int currentMessage = 0; + + do { + kafkaTemplate.send("topic-1", RandomUtils.nextDouble(10.0, 20.0)); + currentMessage++; + + if (currentMessage == MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP) { + String containerId = kafkaListenerEndpointRegistry.getListenerContainerIds() + .stream() + .filter(a -> a.equals(CONSUMER_1_IDENTIFIER)) + .findFirst() + .orElse(""); + MessageListenerContainer container = kafkaListenerEndpointRegistry.getListenerContainer(containerId); + Thread.sleep(2000); + Objects.requireNonNull(container).stop(); + kafkaListenerEndpointRegistry.unregisterListenerContainer(containerId); + } + } while (currentMessage != TOTAL_PRODUCED_MESSAGES); + Thread.sleep(2000); + assertEquals(1, consumerService.consumedPartitions.get("consumer-1").size()); + assertEquals(2, consumerService.consumedPartitions.get("consumer-0").size()); + } +} From 40315beb0df5754add38e8afaf8596ba8f620811 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:44:00 +0200 Subject: [PATCH 271/283] JAVA-26733 Upgrade wiremock to the latest version (#15206) --- apache-httpclient/pom.xml | 10 ++++++++-- .../com/baeldung/httpclient/GetRequestMockServer.java | 2 +- .../baeldung/httpclient/HttpAsyncClientLiveTest.java | 6 ++---- .../java/com/baeldung/httpclient/ResponseUtil.java | 6 +++--- ...HttpClientAdvancedConfigurationIntegrationTest.java | 4 ++-- apache-httpclient4/pom.xml | 4 ++-- ...HttpClientAdvancedConfigurationIntegrationTest.java | 4 ++-- core-java-modules/core-java-httpclient/pom.xml | 4 ++-- core-java-modules/core-java-io-2/pom.xml | 5 ++--- httpclient-simple/pom.xml | 4 ++-- spring-jersey/pom.xml | 4 ++-- testing-modules/rest-testing/pom.xml | 4 ++-- 12 files changed, 30 insertions(+), 27 deletions(-) diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index 1b22d64799..3b178d4df8 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -58,11 +58,16 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test + + org.apache.httpcomponents + httpclient + ${httpclient.version} + @@ -77,11 +82,12 @@ 5.6.1 - 2.5.1 + 3.3.1 5.2 5.2 5.2 + 4.5.14 diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java index 92cb452dc8..1a4f4aebf3 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java @@ -8,7 +8,7 @@ import static org.mockserver.model.HttpResponse.response; import java.io.IOException; import java.net.ServerSocket; -import org.apache.http.HttpStatus; +import org.apache.hc.core5.http.HttpStatus; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.mockserver.client.MockServerClient; diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java index d421de1c7a..50cf1b7a64 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -38,8 +38,6 @@ import org.junit.jupiter.api.Test; class HttpAsyncClientLiveTest extends GetRequestMockServer { - - private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; private static final String HOST_WITH_PROXY = "http://httpbin.org/"; private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php";// "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"; @@ -136,7 +134,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { client.start(); - final SimpleHttpRequest request = new SimpleHttpRequest("GET",HOST_WITH_SSL); + final SimpleHttpRequest request = new SimpleHttpRequest("GET", HOST_WITH_SSL); final Future future = client.execute(request, null); final HttpResponse response = future.get(); @@ -201,7 +199,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { @Override public void run() { try { - final Future future = client.execute(SimpleHttpRequest.copy(request), context, null); + final Future future = client.execute(SimpleRequestBuilder.copy(request).build(), context, null); final HttpResponse response = future.get(); assertThat(response.getCode(), equalTo(200)); } catch (final Exception ex) { diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java index e9ea08a723..537f501d93 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java @@ -1,10 +1,10 @@ package com.baeldung.httpclient; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; - import java.io.IOException; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.core5.http.HttpEntity; + public final class ResponseUtil { private ResponseUtil() { } diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 3ac3ee88be..2a8665b624 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -103,7 +103,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -129,7 +129,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index 8b2fd76f0e..90890ef7b9 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -158,7 +158,7 @@ ${mockserver.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -237,7 +237,7 @@ 1.16.0 4.1.5 - 2.5.1 + 3.3.1 4.4.16 4.5.14 5.11.2 diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 5ced756644..714c01192e 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -102,7 +102,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -128,7 +128,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml index f3730d1b45..fc95366392 100644 --- a/core-java-modules/core-java-httpclient/pom.xml +++ b/core-java-modules/core-java-httpclient/pom.xml @@ -32,7 +32,7 @@ test - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -58,7 +58,7 @@ 11 3.22.0 5.11.2 - 2.27.2 + 3.3.1 \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index 8f4f2518fe..8632748baa 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -31,9 +31,8 @@ log4j-over-slf4j ${org.slf4j.version} - - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -63,7 +62,7 @@ 3.0.0-M1 - 2.26.3 + 3.3.1 \ No newline at end of file diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index 8cbc1237c2..a0f2dd6514 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -99,7 +99,7 @@ ${commons-codec.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -207,7 +207,7 @@ 1.16.0 - 2.5.1 + 3.3.1 5.2 5.2 diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 32f75aa676..9ea5f62778 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -85,7 +85,7 @@ ${jersey.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -219,7 +219,7 @@ 1.6.1 4.4.9 4.5.5 - 2.27.2 + 3.3.1 1.5.10.RELEASE diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index f8005092ae..975b6fb647 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -34,7 +34,7 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -135,7 +135,7 @@ 2.9.0 6.8.0 - 2.21.0 + 3.3.1 1.3.1 4.1 From c10a404f57152bccaf50d097712f50700147e58f Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:58:10 +0000 Subject: [PATCH 272/283] [JAVA-26734] Upgraded aspectjrt, aspectjweaver to latest version (#15140) --- .../core-java-concurrency-advanced-3/pom.xml | 6 +++--- core-java-modules/core-java-os/pom.xml | 1 - .../core-java-time-measurements/pom.xml | 4 ++-- di-modules/cdi/pom.xml | 2 +- libraries-3/pom.xml | 6 +++--- parent-boot-2/pom.xml | 12 +++++++++++- spring-boot-modules/spring-boot-annotations/pom.xml | 1 - spring-boot-modules/spring-boot-mvc/pom.xml | 3 +-- spring-di/pom.xml | 2 +- spring-static-resources/pom.xml | 4 ++-- 10 files changed, 24 insertions(+), 17 deletions(-) diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml index 7fa859c2d5..e3b399782e 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml @@ -85,12 +85,12 @@ 1.8 1.8 0.22.6 - 1.9.5 + 1.9.20.1 0.43 1.2.3 0.14.1 - 1.9.1 - 1.9.1 + 1.9.20.1 + 1.9.20.1 \ No newline at end of file diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index d4ee34b8b7..cd5b479974 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -75,7 +75,6 @@ 4.01 - 1.8.9 1.9 1.9 0.4 diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index 7b2bc31ebb..2dd713efe8 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -33,7 +33,7 @@ org.aspectj aspectjrt - ${asspectj.version} + ${aspectj.version} org.mockito @@ -74,7 +74,7 @@ 3.6.1 2.10 - 1.8.9 + 1.9.20.1 1.44 4.1.0 diff --git a/di-modules/cdi/pom.xml b/di-modules/cdi/pom.xml index fd920c8ce1..09f69f3dc3 100644 --- a/di-modules/cdi/pom.xml +++ b/di-modules/cdi/pom.xml @@ -59,7 +59,7 @@ 2.0.SP1 3.1.6.Final - 1.9.19 + 1.9.20.1 \ No newline at end of file diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 8d45b95a7b..9923e46267 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -219,10 +219,10 @@ 2.7.2 1.2.3.Final 0.22.6 - 1.9.2 + 1.9.20.1 0.14.1 - 1.9.2 - 1.9.2 + 1.9.20.1 + 1.9.20.1 1.19 4.4.13 4.5.12 diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 3f6ad8ef8a..b79be81a66 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -36,6 +36,16 @@ pom import + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + @@ -95,7 +105,7 @@ 1.0.22.RELEASE 2.7.11 - 1.9.1 + 1.9.20.1 8.0.31 diff --git a/spring-boot-modules/spring-boot-annotations/pom.xml b/spring-boot-modules/spring-boot-annotations/pom.xml index 91f2614de8..13a28cbd4e 100644 --- a/spring-boot-modules/spring-boot-annotations/pom.xml +++ b/spring-boot-modules/spring-boot-annotations/pom.xml @@ -17,7 +17,6 @@ org.aspectj aspectjweaver - ${aspectjweaver.version} org.springframework.boot diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index a251c5049b..963cda61b9 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -84,12 +84,10 @@ org.aspectj aspectjrt - ${aspectjweaver.version} org.aspectj aspectjweaver - ${aspectjweaver.version} org.projectlombok @@ -114,6 +112,7 @@ 1.10.0 2.3.7 + 1.9.20.1 com.baeldung.springbootmvc.SpringBootMvcApplication diff --git a/spring-di/pom.xml b/spring-di/pom.xml index bae7263ef9..d073f5359d 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -134,7 +134,7 @@ org.baeldung.org.baeldung.sample.App 3.1.2 - 1.9.5 + 1.9.20.1 \ No newline at end of file diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index 875b8de31b..2bf865ddbe 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -88,7 +88,7 @@ org.aspectj aspectjrt - ${org.aspectj-version} + ${aspectj.version} javax.inject @@ -186,7 +186,7 @@ - 1.8.9 + 1.9.20.1 8.0.1.Final 4.1.0 From a3e0639a75506908027421d647c50704dd882edd Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:18:13 +0200 Subject: [PATCH 273/283] This commit is related to the article BAEL-7232 (#15252) This commit adds a new test class "TimeToLocalDateTimeUnitTest" that shows how to convert a long timestamp into a LocalDateTime object. --- .../TimeToLocalDateTimeUnitTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java new file mode 100644 index 0000000000..e8fb821c75 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.timestamptolocaldatetime; + +import org.joda.time.DateTimeZone; +import org.junit.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import static org.junit.Assert.assertEquals; + +public class TimeToLocalDateTimeUnitTest { + private static final long timestampInMillis = 1700010123000L; + private static final String expectedTimestampString = "2023-11-15 01:02:03"; + + @Test + public void givenTimestamp_whenConvertingToLocalDateTime_thenConvertSuccessfully() { + Instant instant = Instant.ofEpochMilli(timestampInMillis); + LocalDateTime localDateTime = + LocalDateTime.ofInstant(instant, ZoneId.of("UTC")); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String formattedDateTime = localDateTime.format(formatter); + + assertEquals(expectedTimestampString, formattedDateTime); + } + + @Test + public void givenJodaTime_whenGettingTimestamp_thenConvertToLong() { + DateTime dateTime = new DateTime(timestampInMillis, DateTimeZone.UTC); + org.joda.time.LocalDateTime localDateTime = dateTime.toLocalDateTime(); + + org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); + String actualTimestamp = formatter.print(localDateTime); + + assertEquals(expectedTimestampString, actualTimestamp); + } +} From ec1fde9dc1e03cf83678f194b29c4c6b437a0e84 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 14:36:44 +0200 Subject: [PATCH 274/283] BAEL-6014: Check certificate name and alias in keystore file --- .../KeystoreCertificateNameAliasUnitTest.java | 50 ++++++++++++++++++ .../baeldung/keystorealias/my-keystore.jks | Bin 0 -> 2764 bytes 2 files changed, 50 insertions(+) create mode 100644 core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java create mode 100644 core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java new file mode 100644 index 0000000000..47bc4c3425 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.keystorealias; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import org.junit.jupiter.api.Test; + +public class KeystoreCertificateNameAliasUnitTest { + private static final String KEYSTORE_FILE = "my-keystore.jks"; + private static final String KEYSTORE_PWD = "storepw@1"; + private static final String KEYSTORE_ALIAS = "baeldung"; + + private KeyStore readKeyStore() throws Exception { + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(getClass().getResourceAsStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray()); + return keystore; + } + + @Test + void whenCheckingAliasAndName_thenMatchIsFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String owner = x509Certificate.getSubjectX500Principal().getName(); + assertThat(owner.contains("my-cn.localhost")).isTrue(); + } + + @Test + void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String owner = x509Certificate.getSubjectX500Principal() + .getName(); + assertThat(owner.contains("commonName1")).isFalse(); + } + + @Test + void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias("alias1")).isFalse(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks b/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8f7709ee9656d443f21a53170449736898f0325b GIT binary patch literal 2764 zcma);S5y-W5`~kHMsGnRg0xViXoB?K1q?+g(wh*9G%3{r zC<2DAfb^zdp(#OBSoiE6|FciK4|C?soqOl;JA=kE4S;|QXgpIelu?RcM4+<*VL%d| z={gwCXlBRO&d=MMuWX=da_eb-q(?9bFV!6WW*!0{X_kG9svM) z?xUJzn&1b&{VUdNM9G;;Q(?tiGM+n+TxiEM{FlaCH94FY;BeXEqBcuh;X`KI!E!a~ z`dNv*29>23L_{zT3m*oW4slqpoS#DtCD;#d%*@x!M>@+HvQBJyIL$J^15#c#aER3lr{W{9H%Ms|L|B zIn-x~`K0MlRqK;7&MmoP__V$)XVZlJU_9N~StOx0e!SStk6c<#zYW=Y@uTscD{^bY zWVs$vq-hep-{`QoI(@gwBntI~W>j4DI(4waP>N8W5c8d8UgS)``u2qk`J7fzoZI!Cu!PMEqcZd#$zVwm0H-c^yXWAUpQlL4n9<8lfcFtbeJKe zVGl}wd~SRWOG2-EXeK|Dx$XmB`szEuf1ScQ?5;m(NUbvQ2(+8abHgULF+5^ZOEvdU zD3ml{^YDBq$e29yk%&5*l zpqpNA_OFEdbI5Gxxatp5YXTwiNh%h%*XQPsj=eI~<$RbtS`Z1JGKqU$jpo{lhi^aj zL_*8*r?NXo>@*4E?$uQp@EkS+26)uK;E~HrNE^5B zxO~oKn}r$|JJN2rgHxX2l43KKc9`AoT4^wsieIyglL}8H%J5h@h+=HBA7g^X3D#3c ztL)a5WJ0d>&d<6m&C5BQHjv2-oRs#&yPBWdLD3Xbk&sq)_Ell!+kQN=nsd>p5-Zcg z%pPORJaT>VNv@dw+cj8u=Tn`6CNlv&*;B4;(8IXlXE{6grl!#zhl}gH2jl~UxdG2a z2L-k))S#Xi2gUK89@;$1HdcGmIe9-iB_dIC5b5E@>~v$jY4iz~fzA#|*!I()`ngB< zD0Su;Pfj5g|oyK>?#eXR3%Zr1Q7O_%( z4;-CBa=OXE6zWF%(Bf;jYL_B^6~c+!YHB9@=A&d z3UZ2a%4j^e?2icsCE>wYzook%AmDdP{(A%bU#Nc1H(f)Iu-qPp4J0~RBJyyX8L{ENv;c9+K}{&!9EQc^z`jEhgwO_s%?5tW?et!Td)F<=kmZPue|)|XZpPwHhZl7UrE z5Bri;9?m}XwgCEbkJ5se14(Yzqsr$`kXJ`RvyE$Kd?nd>(T`4wBy|BUE~Q_RK3Dcc>t8{K3@>_B3moTdEejCRja_cK$r;B}L zXUP3m>&KX_$nT^M8w~tfN-oW>w)|(PqAXF$?kjfbOUn_>03)6FVM70$rR1A6!5gy1 zmH0Ba8QRUNXE?gGy6?1OGux?3$ONHY6jLZ>+BclMuChD2b6W{3pXZ9IMyv!&#Mvl3 zE-LMg@60T>AC0!U3txI#U5RZ^SJ}CJCY_FYe@oelsu8poYORX6qX+fs-B*p_6<{Yn zD1eY49`Nb?`3j-Kfd@kGw9_I!HmZQ;yn2*i<0q1N6|I4I7t!5x^~i0a1?A;{2o7WW zPSvL@iH-Vg5rvD{vK&@b-4}prL9>6gjX%R8machpgIoFcIsuQ8jn4PaYJmsm>xxi5 z>Nr&@ea6qKHhv(33i=@}3aJet8th$V3}APO7aZvtsLee^b>+V95-ah50cVuF?BMH0 zaP9Hh9TDZcQm8MR-#@Xh$-y6BGdWWwbrI@IyzJtjTI+9urXEbfNQR=#pKi8r4~ZYU zJR2iDnR&r4Vj03x-5gBw-E!G%$zu^wYIc$FS$cIW9laj*-YXLon)Q|k`MmuaKfgMu z*ZRxpQ_r;)+~Gu$l1ga+EHtCGZ*%3lSz_^>nr7AMpzUXnhCT1e5{1ucmO+5$zJG;^ zZ6`QtoD9CMqM;%c37+QE0Abd2{To5*`=#QJx{J^i=B?m^!1L9zdf1ANdwnh&DxI(5!zxJP;5901MR*oaT&uZ*eCJ>8i8%J%Pi& s4Oyc}^70n{XjUP7XTl7O;75 Date: Mon, 20 Nov 2023 20:12:51 +0200 Subject: [PATCH 275/283] BAEL-6014: Remove newline --- .../keystorealias/KeystoreCertificateNameAliasUnitTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index 47bc4c3425..26bd937ca4 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -36,8 +36,7 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal() - .getName(); + String owner = x509Certificate.getSubjectX500Principal().getName(); assertThat(owner.contains("commonName1")).isFalse(); } From 34754e74ad17231b515fd8f25da96a8fd0f44858 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 22:12:10 +0200 Subject: [PATCH 276/283] BAEL-6014: Address PR comments --- .../KeystoreCertificateNameAliasUnitTest.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index 26bd937ca4..e53c1c57cb 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -25,25 +25,25 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal().getName(); - assertThat(owner.contains("my-cn.localhost")).isTrue(); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("my-cn.localhost")).isTrue(); } - @Test - void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); +@Test +void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); - X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal().getName(); - assertThat(owner.contains("commonName1")).isFalse(); - } + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("commonName1")).isFalse(); +} - @Test - void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); +@Test +void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias("alias1")).isFalse(); - } + assertThat(keystore.containsAlias("alias1")).isFalse(); +} } \ No newline at end of file From 0bf89cfe37de372f25b378ca0aa02aa8a10e3ea6 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 22:28:07 +0200 Subject: [PATCH 277/283] BAEL-6014: Fix formatting --- .../KeystoreCertificateNameAliasUnitTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index e53c1c57cb..8f3ec35160 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -29,21 +29,21 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(ownerName.contains("my-cn.localhost")).isTrue(); } -@Test -void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); + @Test + void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); - X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String ownerName = x509Certificate.getSubjectX500Principal().getName(); - assertThat(ownerName.contains("commonName1")).isFalse(); -} + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("commonName1")).isFalse(); + } -@Test -void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); + @Test + void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias("alias1")).isFalse(); -} + assertThat(keystore.containsAlias("alias1")).isFalse(); + } } \ No newline at end of file From 111dcccb922f20b2fb7865a973d0ba7eac6a195e Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:28:10 +0100 Subject: [PATCH 278/283] Bael 7060 (#15247) * BAEL-7060: Converting String to ByteBuffer * BAEL-7060: Converting String to ByteBuffer (format code) --- .../ByteArrayToStringUnitTest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java index c498921d9a..c54bb1236e 100644 --- a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java +++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java @@ -1,12 +1,12 @@ package com.baeldung.bytebuffertostring; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.Test; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ByteArrayToStringUnitTest { private static Charset charset = StandardCharsets.UTF_8; @@ -37,8 +37,17 @@ public class ByteArrayToStringUnitTest { // Allocate a ByteBuffer ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); String newContent = charset.decode(byteBuffer) - .toString(); + .toString(); assertEquals(content, newContent); } + @Test + public void convertStringToByteBuffer_thenOk() { + byte[] expectedBytes = content.getBytes(Charset.forName(charset.toString())); + ByteBuffer byteBuffer = ByteBuffer.wrap(expectedBytes); + + // Test the conversion from string to ByteBuffer + assertEquals(expectedBytes, byteBuffer.array()); + } + } From 85c4c1450b68d7dbcc0bdf95daa210d3341be137 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 20 Nov 2023 19:43:54 -0300 Subject: [PATCH 279/283] BAEL-2499 - Write to CSV in Java Closes #15250 Adding a null check. --- .../src/main/java/com/baeldung/csv/WriteCsvFileExample.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java index f409d05b06..184ae6d3e3 100644 --- a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java +++ b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java @@ -12,6 +12,10 @@ public class WriteCsvFileExample { } public String escapeSpecialCharacters(String data) { + if (data == null) { + throw new IllegalArgumentException("Input data cannot be null"); + } + String escapedData = data.replaceAll("\\R", " "); if (data.contains(",") || data.contains("\"") || data.contains("'")) { data = data.replace("\"", "\"\""); From 94595ea00060ca94784f60a94c523074aaecf8e7 Mon Sep 17 00:00:00 2001 From: Shahul Basha <32072554+shahulbasha@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:50:44 -0500 Subject: [PATCH 280/283] BAEL-7016 (#15050) * initial commit * initial commit * code cleanup * code cleanup * code cleanup * code cleanup * code review comments addressed * pom version * code review comments * formatting updated * updated as per code review comments --- xml-2/pom.xml | 12 ++ .../com/baeldung/xml/tohashmap/Employee.java | 31 +++++ .../com/baeldung/xml/tohashmap/Employees.java | 21 +++ .../baeldung/xml/tohashmap/XmlToHashMap.java | 124 ++++++++++++++++++ .../main/resources/xml/xmltohashmap/test.xml | 12 ++ .../xml/tohashmap/XmlToHashMapUnitTest.java | 71 ++++++++++ 6 files changed, 271 insertions(+) create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java create mode 100644 xml-2/src/main/resources/xml/xmltohashmap/test.xml create mode 100644 xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java diff --git a/xml-2/pom.xml b/xml-2/pom.xml index 0f94588ba0..ccb84e1687 100644 --- a/xml-2/pom.xml +++ b/xml-2/pom.xml @@ -46,6 +46,16 @@ underscore ${underscore.version} + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + com.sun.xml.bind + jaxb-impl + ${jaxb.version} + org.apache.xmlbeans xmlbeans @@ -82,6 +92,8 @@ 2.1.3 20230227 1.89 + 1.4.18 + 2.3.3 diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java new file mode 100644 index 0000000000..c9c40e743a --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java @@ -0,0 +1,31 @@ +package com.baeldung.xml.tohashmap; + +public class Employee { + private String id; + private String firstName; + private String lastName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java new file mode 100644 index 0000000000..d2f2276e5c --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java @@ -0,0 +1,21 @@ +package com.baeldung.xml.tohashmap; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "employees") +public class Employees { + + private List employeeList; + + @XmlElement(name = "employee") + public List getEmployeeList() { + return employeeList; + } + + public void setEmployeeList(List employeeList) { + this.employeeList = employeeList; + } +} \ No newline at end of file diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java new file mode 100644 index 0000000000..ec651486ac --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java @@ -0,0 +1,124 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.github.underscore.U; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.security.AnyTypePermission; + +public class XmlToHashMap { + + public Map xmlToHashMapUsingXstream(String xml) { + XStream xStream = new XStream(); + xStream.alias("employees", List.class); + xStream.alias("employee", Employee.class); + xStream.addPermission(AnyTypePermission.ANY); + List employees = (List) xStream.fromXML(xml); + return employees.stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingUnderscore(String xml) { + Map employeeMap = new HashMap<>(); + Map employeeList = (Map) U.fromXmlMap(xml) + .get("employees"); + List> list = (List>) employeeList.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJackson(String xml) throws JsonProcessingException { + XmlMapper xmlMapper = new XmlMapper(); + Map employeeMap = new HashMap<>(); + Map map = xmlMapper.readValue(xml, Map.class); + List> list = (List>) map.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJAXB(String xmlData) throws JAXBException { + JAXBContext context = JAXBContext.newInstance(Employees.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + Employees employees = (Employees) unmarshaller.unmarshal(new StringReader(xmlData)); + return employees.getEmployeeList() + .stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingDOMParserXpath(String xmlData) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xmlData))); + + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression xPathExpr = xpath.compile("/employees/employee"); + NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET); + + HashMap map = new HashMap<>(); + for (int i = 0; i < nodes.getLength(); i++) { + Element node = (Element) nodes.item(i); + Employee employee = new Employee(); + employee.setId(node.getElementsByTagName("id") + .item(0) + .getTextContent()); + employee.setFirstName(node.getElementsByTagName("firstName") + .item(0) + .getTextContent()); + employee.setLastName(node.getElementsByTagName("lastName") + .item(0) + .getTextContent()); + map.put(employee.getId(), employee); + } + return map; + } + + private static void parseXmlToMap(Map employeeMap, List> list) { + list.forEach(empMap -> { + Employee employee = new Employee(); + for (Map.Entry key : empMap.entrySet()) { + switch (key.getKey()) { + case "id": + employee.setId(key.getValue()); + break; + case "firstName": + employee.setFirstName(key.getValue()); + break; + case "lastName": + employee.setLastName(key.getValue()); + break; + default: + break; + } + } + employeeMap.put(employee.getId(), employee); + }); + } +} diff --git a/xml-2/src/main/resources/xml/xmltohashmap/test.xml b/xml-2/src/main/resources/xml/xmltohashmap/test.xml new file mode 100644 index 0000000000..ef0d12e2af --- /dev/null +++ b/xml-2/src/main/resources/xml/xmltohashmap/test.xml @@ -0,0 +1,12 @@ + + + 654 + John + Doe + + + 776 + Steve + Smith + + \ No newline at end of file diff --git a/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java new file mode 100644 index 0000000000..5e05dd3ccb --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Map; + +import javax.xml.bind.JAXBException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class XmlToHashMapUnitTest { + + private XmlToHashMap xmlToHashMap; + private static final String TEST_XML_PATH = "src/main/resources/xml/xmltohashmap/test.xml"; + + @BeforeEach + void setUp() { + xmlToHashMap = new XmlToHashMap(); + } + + @Test + void whenUsingXstream_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingXstream(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingUnderscore_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingUnderscore(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJackson_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJackson(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJAXB_thenHashMapShouldBeCreated() throws IOException, JAXBException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJAXB(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingDOMXpath_thenHashMapShouldBeCreated() throws Exception { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingDOMParserXpath(getXml()); + verify(employeeMap); + } + + private void verify(Map employeeMap) { + Employee employee1 = employeeMap.get("654"); + Employee employee2 = employeeMap.get("776"); + Assertions.assertEquals("John", employee1 + .getFirstName()); + Assertions.assertEquals("Doe", employee1 + .getLastName()); + Assertions.assertEquals("Steve", employee2 + .getFirstName()); + Assertions.assertEquals("Smith", employee2 + .getLastName()); + } + + private String getXml() throws IOException { + return new String(Files.readAllBytes(Paths.get(TEST_XML_PATH))); + } +} From 9c995714f78f6715d0b99586c1f12e422ecca545 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Tue, 21 Nov 2023 04:47:17 +0100 Subject: [PATCH 281/283] JAVA-26732: Update the equalsverifier dependency --- core-java-modules/core-java-lang-oop-methods/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-lang-oop-methods/pom.xml b/core-java-modules/core-java-lang-oop-methods/pom.xml index 6f246d78ce..5e53004d62 100644 --- a/core-java-modules/core-java-lang-oop-methods/pom.xml +++ b/core-java-modules/core-java-lang-oop-methods/pom.xml @@ -35,7 +35,7 @@ 2.6 3.10.0 - 3.0.3 + 3.15.3 \ No newline at end of file From 923556ea274f141a02b9eca22b414961f9c94664 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 21 Nov 2023 16:22:50 +0530 Subject: [PATCH 282/283] Java 27246 (#15255) --- core-java-modules/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index a237fe0ed6..27d84c742d 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -198,7 +198,8 @@ core-java-records core-java-9-jigsaw - + + core-java-collections-set core-java-date-operations-1 core-java-datetime-conversion From ea7466682bd16d35e126ab859662d1d0b3783782 Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Tue, 21 Nov 2023 11:39:23 -0300 Subject: [PATCH 283/283] BAEL-7178: StringUtils.isBlank() vs String.isEmpty() (#15213) * adding first test cases * final code --- .../StringIsEmptyVsIsBlankUnitTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java new file mode 100644 index 0000000000..f6950237c5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.isemptyvsisblank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StringIsEmptyVsIsBlankUnitTest { + + @Test + public void givenString_whenCallIsEmpty_thenReturnCorrectValues() { + assertFalse("Example text".isEmpty()); + assertTrue("".isEmpty()); + assertFalse(" ".isEmpty()); + assertFalse("\t\n\r\f".isEmpty()); + } + + @Test + public void givenString_whenCallStringIsBlank_thenReturnCorrectValues() { + assertFalse("Example text".isBlank()); + assertTrue("".isBlank()); + assertTrue(" ".isBlank()); + assertTrue("\t\n\r\f ".isBlank()); + } +}