diff --git a/.gitignore b/.gitignore index 0b6bd24070..06c5242898 100644 --- a/.gitignore +++ b/.gitignore @@ -64,13 +64,13 @@ core-java-io/hard_link.txt core-java-io/target_link.txt core-java/src/main/java/com/baeldung/manifest/MANIFEST.MF ethereum/logs/ -jmeter/src/main/resources/*-JMeter.csv -jmeter/src/main/resources/*-Basic*.csv -jmeter/src/main/resources/*-JMeter*.csv -jmeter/src/main/resources/*ReportsDashboard*.csv -jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv -jmeter/src/main/resources/*FileExtractionExample.csv -jmeter/src/main/resources/*_Summary-Report.csv +testing-modules/jmeter/src/main/resources/*-JMeter.csv +testing-modules/jmeter/src/main/resources/*-Basic*.csv +testing-modules/jmeter/src/main/resources/*-JMeter*.csv +testing-modules/jmeter/src/main/resources/*ReportsDashboard*.csv +testing-modules/jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv +testing-modules/jmeter/src/main/resources/*FileExtractionExample.csv +testing-modules/jmeter/src/main/resources/*_Summary-Report.csv ninja/devDb.mv.db @@ -128,3 +128,6 @@ persistence-modules/neo4j/data/** /deep-shallow-copy/.mvn/wrapper /deep-shallow-copy/mvnw /deep-shallow-copy/mvnw.cmd + +#spring-5-webflux-2 +**/testdb.mv.db \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-2/pom.xml b/algorithms-modules/algorithms-miscellaneous-2/pom.xml index ca14533e82..e04c22680a 100644 --- a/algorithms-modules/algorithms-miscellaneous-2/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-2/pom.xml @@ -14,16 +14,6 @@ - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - commons-codec - commons-codec - ${commons-codec.version} - org.projectlombok lombok diff --git a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java index 7e80d335be..849eb86427 100644 --- a/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java @@ -1,7 +1,5 @@ package com.baeldung.algorithms; - - import com.baeldung.algorithms.ga.dijkstra.Dijkstra; import com.baeldung.algorithms.ga.dijkstra.Graph; import com.baeldung.algorithms.ga.dijkstra.Node; diff --git a/apache-cxf-modules/cxf-aegis/pom.xml b/apache-cxf-modules/cxf-aegis/pom.xml index 6b9e026cdd..d013aabc65 100644 --- a/apache-cxf-modules/cxf-aegis/pom.xml +++ b/apache-cxf-modules/cxf-aegis/pom.xml @@ -20,8 +20,4 @@ - - 4.0.0 - - \ No newline at end of file diff --git a/apache-cxf-modules/cxf-introduction/pom.xml b/apache-cxf-modules/cxf-introduction/pom.xml index fdcd100cc5..5e68bf3cbf 100644 --- a/apache-cxf-modules/cxf-introduction/pom.xml +++ b/apache-cxf-modules/cxf-introduction/pom.xml @@ -48,7 +48,6 @@ - 4.0.0 4.0.0 3.0.0 diff --git a/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml b/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml index 8418853b1e..978c5a51ed 100644 --- a/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml +++ b/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml @@ -16,12 +16,12 @@ org.apache.cxf cxf-rt-frontend-jaxrs - 4.0.0 + ${cxf.version} org.apache.cxf cxf-rt-transports-http-jetty - 4.0.0 + ${cxf.version} jakarta.xml.ws diff --git a/apache-cxf-modules/cxf-spring/pom.xml b/apache-cxf-modules/cxf-spring/pom.xml index 67a61e8200..234a19eebc 100644 --- a/apache-cxf-modules/cxf-spring/pom.xml +++ b/apache-cxf-modules/cxf-spring/pom.xml @@ -115,6 +115,7 @@ + 3.1.8 5.3.25 1.6.1 1.2 diff --git a/apache-cxf-modules/pom.xml b/apache-cxf-modules/pom.xml index 63c4e16747..245a31614b 100644 --- a/apache-cxf-modules/pom.xml +++ b/apache-cxf-modules/pom.xml @@ -35,7 +35,7 @@ - 3.1.8 + 4.0.0 \ No newline at end of file diff --git a/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml index ce2b0059c3..b092345334 100644 --- a/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml +++ b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml @@ -16,12 +16,12 @@ org.apache.cxf cxf-rt-rs-client - ${cxf-version} + ${cxf.version} org.apache.cxf cxf-rt-rs-sse - ${cxf-version} + ${cxf.version} jakarta.ws.rs @@ -60,7 +60,6 @@ - 4.0.0 3.1.0 diff --git a/apache-poi-3/README.md b/apache-poi-3/README.md index 9e9d6a94eb..b7272d5e69 100644 --- a/apache-poi-3/README.md +++ b/apache-poi-3/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [How To Convert Excel Data Into List Of Java Objects](https://www.baeldung.com/java-convert-excel-data-into-list) - [Expand Columns with Apache POI](https://www.baeldung.com/java-apache-poi-expand-columns) +- [Apply Bold Text Style for an Entire Row Using Apache POI](https://www.baeldung.com/appache-poi-apply-bold-text-style-entire-row) diff --git a/aws-modules/aws-lambda-modules/lambda-function/pom.xml b/aws-modules/aws-lambda-modules/lambda-function/pom.xml index 9fff7d1d9a..8c56aaabed 100644 --- a/aws-modules/aws-lambda-modules/lambda-function/pom.xml +++ b/aws-modules/aws-lambda-modules/lambda-function/pom.xml @@ -97,7 +97,7 @@ 1.1.1 3.11.0 1.2.1 - 2.8.2 + 2.10.1 \ No newline at end of file diff --git a/core-java-modules/core-java-11-3/pom.xml b/core-java-modules/core-java-11-3/pom.xml index 0161f4dcca..cacbc9089c 100644 --- a/core-java-modules/core-java-11-3/pom.xml +++ b/core-java-modules/core-java-11-3/pom.xml @@ -46,7 +46,7 @@ 11 11 2.16.0 - 2.10 + 2.10.1 \ No newline at end of file diff --git a/core-java-modules/core-java-21/README.md b/core-java-modules/core-java-21/README.md index ffb999a4ba..fcb9faaace 100644 --- a/core-java-modules/core-java-21/README.md +++ b/core-java-modules/core-java-21/README.md @@ -3,3 +3,4 @@ - [String Templates in Java 21](https://www.baeldung.com/java-21-string-templates) - [Unnamed Classes and Instance Main Methods in Java 21](https://www.baeldung.com/java-21-unnamed-class-instance-main) - [Unnamed Patterns and Variables in Java 21](https://www.baeldung.com/java-unnamed-patterns-variables) +- [JFR View Command in Java 21](https://www.baeldung.com/java-flight-recorder-view) 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 8a508404ee..e689e7257f 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -11,4 +11,6 @@ - [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time) - [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) - [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) +- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap) +- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) diff --git a/core-java-modules/core-java-arrays-convert/README.md b/core-java-modules/core-java-arrays-convert/README.md index 118d8e00ed..01a65670b2 100644 --- a/core-java-modules/core-java-arrays-convert/README.md +++ b/core-java-modules/core-java-arrays-convert/README.md @@ -12,3 +12,4 @@ This module contains articles about arrays conversion in Java - [Convert an ArrayList of String to a String Array in Java](https://www.baeldung.com/java-convert-string-arraylist-array) - [Convert Char Array to Int Array in Java](https://www.baeldung.com/java-convert-char-int-array) - [How to Convert Byte Array to Char Array](https://www.baeldung.com/java-convert-byte-array-char) +- [Convert byte[] to Byte[] and Vice Versa in Java](https://www.baeldung.com/java-byte-array-wrapper-primitive-type-convert) diff --git a/core-java-modules/core-java-arrays-guides/pom.xml b/core-java-modules/core-java-arrays-guides/pom.xml index cc67add9e3..12da6b2145 100644 --- a/core-java-modules/core-java-arrays-guides/pom.xml +++ b/core-java-modules/core-java-arrays-guides/pom.xml @@ -7,10 +7,6 @@ core-java-arrays-guides jar - - 2.1.5 - - core-java-modules com.baeldung.core-java-modules @@ -34,7 +30,10 @@ ${system-stubs.jupiter.version} test - + + 2.1.5 + + diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index cf731e8f09..4f174b5163 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -13,4 +13,5 @@ - [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort) - [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence) - [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators) +- [PriorityQueue iterator() Method in Java](https://www.baeldung.com/java-priorityqueue-iterator) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) diff --git a/core-java-modules/core-java-collections-5/pom.xml b/core-java-modules/core-java-collections-5/pom.xml index da58ef1db5..06d872ec37 100644 --- a/core-java-modules/core-java-collections-5/pom.xml +++ b/core-java-modules/core-java-collections-5/pom.xml @@ -5,18 +5,6 @@ 4.0.0 core-java-collections-5 core-java-collections-5 - - - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - - - jar @@ -61,6 +49,19 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + 5.9.2 0.9.38 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 10c0ded0c3..d62263eb63 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -55,7 +55,6 @@ ${org.json.version} test - diff --git a/core-java-modules/core-java-collections-list-6/README.md b/core-java-modules/core-java-collections-list-6/README.md index 30ae5eb2dd..bf634fb79c 100644 --- a/core-java-modules/core-java-collections-list-6/README.md +++ b/core-java-modules/core-java-collections-list-6/README.md @@ -3,3 +3,4 @@ - [Removing the Last Node in a Linked List](https://www.baeldung.com/java-linked-list-remove-last-element) - [Call a Method on Each Element of a List in Java](https://www.baeldung.com/java-call-method-each-list-item) - [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another) +- [Reset ListIterator to First Element of the List in Java](https://www.baeldung.com/java-reset-listiterator) diff --git a/core-java-modules/core-java-collections-maps-6/pom.xml b/core-java-modules/core-java-collections-maps-6/pom.xml index a0cdc07644..6d10115d31 100644 --- a/core-java-modules/core-java-collections-maps-6/pom.xml +++ b/core-java-modules/core-java-collections-maps-6/pom.xml @@ -27,7 +27,7 @@ com.google.code.gson gson - 2.8.9 + 2.10.1 org.json diff --git a/core-java-modules/core-java-collections-set/pom.xml b/core-java-modules/core-java-collections-set/pom.xml index 1fb59db991..b3cd1ec90f 100644 --- a/core-java-modules/core-java-collections-set/pom.xml +++ b/core-java-modules/core-java-collections-set/pom.xml @@ -41,7 +41,7 @@ - 2.8.5 + 2.10.1 \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/CountDownLatchDemo.java b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/CountDownLatchDemo.java new file mode 100644 index 0000000000..e2435bb544 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/CountDownLatchDemo.java @@ -0,0 +1,33 @@ +package com.baeldung.countdownlatchvssemaphore; + +import java.util.concurrent.CountDownLatch; + +public class CountDownLatchDemo { + + public static void main(String[] args) throws InterruptedException { + // Create a CountDownLatch with an initial count equal to the number of tasks to be completed + int numberOfTasks = 3; + CountDownLatch latch = new CountDownLatch(numberOfTasks); + + // Simulate completion of tasks by worker threads + for (int i = 1; i <= numberOfTasks; i++) { + new Thread(() -> { + System.out.println("Task completed by Thread " + Thread.currentThread() + .getId()); + + // Decrement the latch count to signal completion of a task + latch.countDown(); + }).start(); + } + + // Main thread waits until all tasks are completed + latch.await(); + System.out.println("All tasks completed. Main thread proceeds."); + + // Attempting to reset will have no effect + latch.countDown(); + // Latch is already at zero, await() returns immediately + latch.await(); // This line won't block + System.out.println("Latch is already at zero and cannot be reset."); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/SemaphoreDemo.java b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/SemaphoreDemo.java new file mode 100644 index 0000000000..483462e7fb --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/countdownlatchvssemaphore/SemaphoreDemo.java @@ -0,0 +1,42 @@ +package com.baeldung.countdownlatchvssemaphore; + +import java.util.concurrent.Semaphore; + +public class SemaphoreDemo { + + public static void main(String[] args) { + // Create a Semaphore with a fixed number of permits + int NUM_PERMITS = 3; + Semaphore semaphore = new Semaphore(NUM_PERMITS); + + // Simulate resource access by worker threads + for (int i = 1; i <= 5; i++) { + new Thread(() -> { + try { + // Acquire a permit to access the resource + semaphore.acquire(); + System.out.println("Thread " + Thread.currentThread().getId() + " accessing resource."); + + // Simulate resource usage + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + // Release the permit after resource access is complete + semaphore.release(); + } + }).start(); + } + + // Simulate resetting the Semaphore by releasing additional permits after a delay + try { + Thread.sleep(5000); + + // Resetting the semaphore permits to the initial count + semaphore.release(NUM_PERMITS); + System.out.println("Semaphore permits reset to initial count."); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-console/README.md b/core-java-modules/core-java-console/README.md index 77ad16d015..cab2cc24be 100644 --- a/core-java-modules/core-java-console/README.md +++ b/core-java-modules/core-java-console/README.md @@ -8,3 +8,4 @@ - [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) +- [Printing Message on Console without Using main() Method in Java](https://www.baeldung.com/java-no-main-print-message-console) diff --git a/core-java-modules/core-java-date-operations-4/README.md b/core-java-modules/core-java-date-operations-4/README.md index b7817ebd1e..bfc460f5eb 100644 --- a/core-java-modules/core-java-date-operations-4/README.md +++ b/core-java-modules/core-java-date-operations-4/README.md @@ -2,4 +2,5 @@ This module contains articles about date operations in Java. ### Relevant Articles: +- [Calculate Number of Weekdays Between Two Dates in Java](https://www.baeldung.com/java-count-weekdays-between-two-dates) diff --git a/core-java-modules/core-java-datetime-conversion-2/src/main/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverter.java b/core-java-modules/core-java-datetime-conversion-2/src/main/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverter.java new file mode 100644 index 0000000000..2ec1efecd0 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion-2/src/main/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverter.java @@ -0,0 +1,42 @@ +package com.baeldung.stringdatetoxmlgregoriancalendar; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Date; +import java.util.GregorianCalendar; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +public class StringDateToXMLGregorianCalendarConverter { + public static XMLGregorianCalendar usingDatatypeFactoryForDate(String dateAsString) throws DatatypeConfigurationException { + return DatatypeFactory.newInstance().newXMLGregorianCalendar(dateAsString); + } + + public static XMLGregorianCalendar usingLocalDate(String dateAsString) throws DatatypeConfigurationException { + LocalDate localDate = LocalDate.parse(dateAsString); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(localDate.toString()); + } + + public static XMLGregorianCalendar usingSimpleDateFormat(String dateTimeAsString) throws DatatypeConfigurationException, ParseException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + Date date = simpleDateFormat.parse(dateTimeAsString); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(simpleDateFormat.format(date)); + } + + public static XMLGregorianCalendar usingGregorianCalendar(String dateTimeAsString) throws DatatypeConfigurationException, ParseException { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(dateTimeAsString)); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar); + } + + public static XMLGregorianCalendar usingJodaTime(String dateTimeAsString) throws DatatypeConfigurationException { + DateTime dateTime = DateTime.parse(dateTimeAsString, DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss")); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTime.toGregorianCalendar()); + } +} diff --git a/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverterUnitTest.java b/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverterUnitTest.java new file mode 100644 index 0000000000..b3c15a3fd4 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/stringdatetoxmlgregoriancalendar/StringDateToXMLGregorianCalendarConverterUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.stringdatetoxmlgregoriancalendar; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.ParseException; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.jupiter.api.Test; + +public class StringDateToXMLGregorianCalendarConverterUnitTest { + private static final String dateAsString = "2014-04-24"; + private static final String dateTimeAsString = "2014-04-24T15:45:30"; + + @Test + void givenStringDate_whenUsingDatatypeFactory_thenConvertToXMLGregorianCalendar() throws DatatypeConfigurationException { + XMLGregorianCalendar xmlGregorianCalendar = StringDateToXMLGregorianCalendarConverter.usingDatatypeFactoryForDate(dateAsString); + assertEquals(24,xmlGregorianCalendar.getDay()); + assertEquals(4,xmlGregorianCalendar.getMonth()); + assertEquals(2014,xmlGregorianCalendar.getYear()); + } + + @Test + void givenStringDateTime_whenUsingApacheCommonsLang3_thenConvertToXMLGregorianCalendar() throws DatatypeConfigurationException { + XMLGregorianCalendar xmlGregorianCalendar = StringDateToXMLGregorianCalendarConverter.usingLocalDate(dateAsString); + assertEquals(24,xmlGregorianCalendar.getDay()); + assertEquals(4,xmlGregorianCalendar.getMonth()); + assertEquals(2014,xmlGregorianCalendar.getYear()); + } + + @Test + void givenStringDateTime_whenUsingSimpleDateFormat_thenConvertToXMLGregorianCalendar() throws DatatypeConfigurationException, ParseException { + XMLGregorianCalendar xmlGregorianCalendar = StringDateToXMLGregorianCalendarConverter.usingSimpleDateFormat(dateTimeAsString); + assertEquals(24,xmlGregorianCalendar.getDay()); + assertEquals(4,xmlGregorianCalendar.getMonth()); + assertEquals(2014,xmlGregorianCalendar.getYear()); + assertEquals(15,xmlGregorianCalendar.getHour()); + assertEquals(45,xmlGregorianCalendar.getMinute()); + assertEquals(30,xmlGregorianCalendar.getSecond()); + } + + @Test + void givenStringDateTime_whenUsingGregorianCalendar_thenConvertToXMLGregorianCalendar() throws DatatypeConfigurationException, ParseException { + XMLGregorianCalendar xmlGregorianCalendar = StringDateToXMLGregorianCalendarConverter.usingGregorianCalendar(dateTimeAsString); + assertEquals(24,xmlGregorianCalendar.getDay()); + assertEquals(4,xmlGregorianCalendar.getMonth()); + assertEquals(2014,xmlGregorianCalendar.getYear()); + assertEquals(15,xmlGregorianCalendar.getHour()); + assertEquals(45,xmlGregorianCalendar.getMinute()); + assertEquals(30,xmlGregorianCalendar.getSecond()); + } + + @Test + void givenStringDateTime_whenUsingJodaTime_thenConvertToXMLGregorianCalendar() throws DatatypeConfigurationException { + XMLGregorianCalendar xmlGregorianCalendar = StringDateToXMLGregorianCalendarConverter.usingJodaTime(dateTimeAsString); + assertEquals(24,xmlGregorianCalendar.getDay()); + assertEquals(4,xmlGregorianCalendar.getMonth()); + assertEquals(2014,xmlGregorianCalendar.getYear()); + assertEquals(15,xmlGregorianCalendar.getHour()); + assertEquals(45,xmlGregorianCalendar.getMinute()); + assertEquals(30,xmlGregorianCalendar.getSecond()); + } +} diff --git a/core-java-modules/core-java-datetime-string-2/README.md b/core-java-modules/core-java-datetime-string-2/README.md index 6ff19a44ab..c6f06da8fb 100644 --- a/core-java-modules/core-java-datetime-string-2/README.md +++ b/core-java-modules/core-java-datetime-string-2/README.md @@ -5,3 +5,4 @@ This module contains articles about parsing and formatting Java date and time ob ### Relevant Articles: - [Convert String to Instant](https://www.baeldung.com/java-string-to-instant) - [Sort Date Strings in Java](https://www.baeldung.com/java-sort-date-strings) +- [Using Current Time as Filename in Java](https://www.baeldung.com/java-current-time-filename) diff --git a/core-java-modules/core-java-io-5/file.txt b/core-java-modules/core-java-io-5/file.txt new file mode 100644 index 0000000000..5dd01c177f --- /dev/null +++ b/core-java-modules/core-java-io-5/file.txt @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteBlockingQueue.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteBlockingQueue.java new file mode 100644 index 0000000000..ee0cc84955 --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteBlockingQueue.java @@ -0,0 +1,85 @@ +package com.baeldung.readwritethread; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class ReadWriteBlockingQueue { + + public static void main(String[] args) throws InterruptedException { + + BlockingQueue queue = new LinkedBlockingQueue<>(); + String readFileName = "src/main/resources/read_file.txt"; + String writeFileName = "src/main/resources/write_file.txt"; + + Thread producerThread = new Thread(new FileProducer(queue, readFileName)); + Thread consumerThread1 = new Thread(new FileConsumer(queue, writeFileName)); + + producerThread.start(); + Thread.sleep(100); // Give producer a head start + consumerThread1.start(); + try { + producerThread.join(); + consumerThread1.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} + +class FileProducer implements Runnable { + + private final BlockingQueue queue; + private final String inputFileName; + + public FileProducer(BlockingQueue queue, String inputFileName) { + this.queue = queue; + this.inputFileName = inputFileName; + } + + @Override + public void run() { + try (BufferedReader reader = new BufferedReader(new FileReader(inputFileName))) { + String line; + while ((line = reader.readLine()) != null) { + queue.offer(line); + System.out.println("Producer added line: " + line); + System.out.println("Queue size: " + queue.size()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} + +class FileConsumer implements Runnable { + + private final BlockingQueue queue; + private final String outputFileName; + + public FileConsumer(BlockingQueue queue, String outputFileName) { + this.queue = queue; + this.outputFileName = outputFileName; + } + + @Override + public void run() { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileName))) { + String line; + while ((line = queue.poll()) != null) { + writer.write(line); + writer.newLine(); + System.out.println(Thread.currentThread() + .getId() + " - Consumer processed line: " + line); + System.out.println("Queue size: " + queue.size()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteThread.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteThread.java new file mode 100644 index 0000000000..47f6a79d5f --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/readwritethread/ReadWriteThread.java @@ -0,0 +1,55 @@ +package com.baeldung.readwritethread; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class ReadWriteThread { + + public static void readFile(String filePath) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + thread.start(); + } + + public static void writeFile(String filePath, String content) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try (FileWriter fileWriter = new FileWriter(filePath)) { + fileWriter.write("Hello, world!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + thread.start(); + } + + public static void main(String[] args) { + String file = "src/main/resources/text.txt"; + + writeFile(file, "Hello, world!"); + + readFile(file); + + // Sleep for a while to allow the threads to complete + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/core-java-modules/core-java-io-5/src/main/resources/read_file.txt b/core-java-modules/core-java-io-5/src/main/resources/read_file.txt new file mode 100644 index 0000000000..9193448ace --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/resources/read_file.txt @@ -0,0 +1,5 @@ +Hello, +Baeldung! +Nice to meet you! +My name is +Wynn. \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/resources/text.txt b/core-java-modules/core-java-io-5/src/main/resources/text.txt new file mode 100644 index 0000000000..5dd01c177f --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/resources/text.txt @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/resources/write_file.txt b/core-java-modules/core-java-io-5/src/main/resources/write_file.txt new file mode 100644 index 0000000000..f1df68d0ad --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/resources/write_file.txt @@ -0,0 +1,5 @@ +Hello, +Baeldung! +Nice to meet you! +My name is +Wynn. diff --git a/core-java-modules/core-java-io-apis-2/pom.xml b/core-java-modules/core-java-io-apis-2/pom.xml index 579fa4a589..89ab6d163a 100644 --- a/core-java-modules/core-java-io-apis-2/pom.xml +++ b/core-java-modules/core-java-io-apis-2/pom.xml @@ -82,6 +82,7 @@ test + core-java-io-apis-2 @@ -91,6 +92,7 @@ + 5.9.3 diff --git a/core-java-modules/core-java-lang-6/pom.xml b/core-java-modules/core-java-lang-6/pom.xml index 7bf2fafaa1..8f7f574e22 100644 --- a/core-java-modules/core-java-lang-6/pom.xml +++ b/core-java-modules/core-java-lang-6/pom.xml @@ -3,14 +3,14 @@ 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 + core-java-lang-6 + com.baeldung.core-java-modules core-java-modules 0.0.1-SNAPSHOT - core-java-lang-6 - diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index 97d99ad468..e0d7ccdcf5 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -14,4 +14,7 @@ - [Clamp Function in Java](https://www.baeldung.com/java-clamp-function) - [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square) - [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) +- [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation) +- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point) +- [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math/pom.xml b/core-java-modules/core-java-lang-math/pom.xml index 118998991f..85e653930c 100644 --- a/core-java-modules/core-java-lang-math/pom.xml +++ b/core-java-modules/core-java-lang-math/pom.xml @@ -5,6 +5,14 @@ 4.0.0 core-java-lang-math core-java-lang-math + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + org.projectlombok @@ -13,13 +21,6 @@ compile - jar - - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - core-java-lang-math diff --git a/core-java-modules/core-java-lang-oop-patterns/pom.xml b/core-java-modules/core-java-lang-oop-patterns/pom.xml index 4b89584def..f0a714e911 100644 --- a/core-java-modules/core-java-lang-oop-patterns/pom.xml +++ b/core-java-modules/core-java-lang-oop-patterns/pom.xml @@ -32,7 +32,7 @@ - 2.8.2 + 2.10.1 \ No newline at end of file diff --git a/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java b/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java index 13d2abc62c..3f57b0da48 100644 --- a/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java +++ b/core-java-modules/core-java-networking-4/urlnormalization/URLNormalizationUnitTest.java @@ -22,7 +22,7 @@ public class URLNormalizationUnitTest { String normalizedUri = originalUrl.split("\\?")[0]; assertEquals(expectedNormalizedUrl, normalizedUri); } else { - throw new IllegalArgumentException("Invalid URL: " + originalUrl); + fail(originalUrl); } } @@ -35,7 +35,7 @@ public class URLNormalizationUnitTest { } @Test - public void givenOriginalUrl_whenUsingRegularExpression_thenNormalizedUrl() throws URISyntaxException, UnsupportedEncodingException { + public void givenOriginalUrl_whenUsingRegularExpression_thenNormalizedUrl() { String regex = "^(https?://[^/]+/[^?#]+)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(originalUrl); @@ -44,7 +44,7 @@ public class URLNormalizationUnitTest { String normalizedUrl = matcher.group(1); assertEquals(expectedNormalizedUrl, normalizedUrl); } else { - throw new IllegalArgumentException("Invalid URL: " + originalUrl); + fail(originalUrl); } } } diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 34e53056a4..a5ddcfc0ee 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -31,6 +31,7 @@ ${guava.version} + core-java-numbers-6 @@ -44,4 +45,5 @@ 1.16.0 + \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-7/README.md b/core-java-modules/core-java-numbers-7/README.md index af5334eea6..e86d199d97 100644 --- a/core-java-modules/core-java-numbers-7/README.md +++ b/core-java-modules/core-java-numbers-7/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Check if a double Is an Integer in Java](https://www.baeldung.com/java-check-double-integer) - [Print a Double Value Without Scientific Notation in Java](https://www.baeldung.com/java-print-double-number-no-scientific-notation) +- [Check if a Float Value is Equivalent to an Integer Value in Java](https://www.baeldung.com/java-float-integer-equal) diff --git a/core-java-modules/core-java-numbers-7/pom.xml b/core-java-modules/core-java-numbers-7/pom.xml index dec3084108..3940a0b1d0 100644 --- a/core-java-modules/core-java-numbers-7/pom.xml +++ b/core-java-modules/core-java-numbers-7/pom.xml @@ -25,6 +25,7 @@ ${guava.version} + core-java-numbers-7 @@ -34,4 +35,5 @@ + \ No newline at end of file diff --git a/core-java-modules/core-java-records/pom.xml b/core-java-modules/core-java-records/pom.xml index 0caa1765fd..5968bbb344 100644 --- a/core-java-modules/core-java-records/pom.xml +++ b/core-java-modules/core-java-records/pom.xml @@ -2,14 +2,15 @@ + 4.0.0 + core-java-records + core-java-modules com.baeldung.core-java-modules 0.0.1-SNAPSHOT - 4.0.0 - core-java-records diff --git a/core-java-modules/core-java-security-4/README.md b/core-java-modules/core-java-security-4/README.md index 8f5ee308bd..5e12606bbf 100644 --- a/core-java-modules/core-java-security-4/README.md +++ b/core-java-modules/core-java-security-4/README.md @@ -7,4 +7,5 @@ This module contains articles about core Java Security - [Extract CN From X509 Certificate in Java](https://www.baeldung.com/java-extract-common-name-x509-certificate) - [Check Certificate Name and Alias in Keystore File](https://www.baeldung.com/java-keystore-check-certificate-name-alias) - [Using a Custom TrustStore in Java](https://www.baeldung.com/java-custom-truststore) +- [Enable Java SSL Debug Logging](https://www.baeldung.com/java-ssl-debug-logging) - More articles: [[<-- prev]](/core-java-modules/core-java-security-3) diff --git a/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/runlength/RunLengthEncodingUnitTest.java b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/runlength/RunLengthEncodingUnitTest.java new file mode 100644 index 0000000000..c7b8b14874 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-4/src/test/java/com/baeldung/string/runlength/RunLengthEncodingUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.string.runlength; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RunLengthEncodingUnitTest { + private static final String INPUT = "WWWWWWWWWWWWBAAACCDEEEEE"; + private static final String RLE = "12W1B3A2C1D5E"; + + String runLengthEncode(String input) { + StringBuilder result = new StringBuilder(); + int count = 1; + char[] chars = input.toCharArray(); + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (i + 1 < chars.length && c == chars[i + 1]) { + count++; + } else { + result.append(count).append(c); + count = 1; + } + } + return result.toString(); + } + + + String runLengthDecode(String rle) { + StringBuilder result = new StringBuilder(); + char[] chars = rle.toCharArray(); + + int count = 0; + for (char c : chars) { + if (Character.isDigit(c)) { + count = 10 * count + Character.getNumericValue(c); + } else { + result.append(String.join("", Collections.nCopies(count, String.valueOf(c)))); + count = 0; + } + } + return result.toString(); + } + + String runLengthEncodeByRegEx(String input) { + String[] arr = input.split("(?<=(\\D))(?!\\1)"); + StringBuilder result = new StringBuilder(); + for (String run : arr) { + result.append(run.length()).append(run.charAt(0)); + } + return result.toString(); + } + + String runLengthDecodeByRegEx(String rle) { + if (rle.isEmpty()) { + return ""; + } + String[] arr = rle.split("(?<=\\D)|(?=\\D+)"); + if (arr.length % 2 != 0) { + throw new IllegalArgumentException("Not a RLE string"); + } + StringBuilder result = new StringBuilder(); + + for (int i = 1; i <= arr.length; i += 2) { + int count = Integer.parseInt(arr[i - 1]); + String c = arr[i]; + + result.append(String.join("", Collections.nCopies(count, c))); + } + return result.toString(); + } + + @Test + void whenInvokingRunLengthEncode_thenGetExpectedResult() { + assertEquals(RLE, runLengthEncode(INPUT)); + } + + @Test + void whenInvokingRunLengthDecode_thenGetExpectedResult() { + assertEquals(INPUT, runLengthDecode(RLE)); + } + + @Test + void whenInvokingRunLengthEncodeByRegEx_thenGetExpectedResult() { + assertEquals(RLE, runLengthEncodeByRegEx(INPUT)); + } + + @Test + void whenInvokingRunLengthDecodeByRegEx_thenGetExpectedResult() { + assertEquals(INPUT, runLengthDecodeByRegEx(RLE)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/pom.xml b/core-java-modules/core-java-string-operations-6/pom.xml index 69deeea0d8..2cd7c6ad3e 100644 --- a/core-java-modules/core-java-string-operations-6/pom.xml +++ b/core-java-modules/core-java-string-operations-6/pom.xml @@ -12,6 +12,7 @@ core-java-modules 0.0.1-SNAPSHOT + org.apache.commons 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 2c112cf24a..c100b66ff7 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -12,3 +12,5 @@ - [Check If a Java StringBuilder Object Contains a Character](https://www.baeldung.com/java-check-stringbuilder-object-contains-character) - [Comparing One String With Multiple Values in One Expression in Java](https://www.baeldung.com/java-compare-string-multiple-values-one-expression) - [UTF-8 Validation in Java](https://www.baeldung.com/java-utf-8-validation) +- [Simple Morse Code Translation in Java](https://www.baeldung.com/java-morse-code-english-translate) +- [How to Determine if a String Contains Invalid Encoded Characters](https://www.baeldung.com/java-check-string-contains-invalid-encoded-characters) diff --git a/core-java-modules/core-java-swing/pom.xml b/core-java-modules/core-java-swing/pom.xml index 53a2e9b1ff..b46fe0f65a 100644 --- a/core-java-modules/core-java-swing/pom.xml +++ b/core-java-modules/core-java-swing/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 core-java-swing core-java-swing @@ -12,6 +12,7 @@ core-java-modules 0.0.1-SNAPSHOT + 20 20 diff --git a/json-modules/gson-2/README.md b/json-modules/gson-2/README.md index 912f8b0a20..4d7d917cc0 100644 --- a/json-modules/gson-2/README.md +++ b/json-modules/gson-2/README.md @@ -6,3 +6,4 @@ This module contains articles about Gson - [Solving Gson Parsing Errors](https://www.baeldung.com/gson-parsing-errors) - [Difference between Gson @Expose and @SerializedName](https://www.baeldung.com/gson-expose-vs-serializedname) - [Resolving Gson’s “Multiple JSON Fields” Exception](https://www.baeldung.com/java-gson-multiple-json-fields-exception) +- [Using Static Methods Instead of Deprecated JsonParser](https://www.baeldung.com/java-static-methods-jsonparser-replacement) diff --git a/maven-modules/maven-build-lifecycle/README.md b/maven-modules/maven-build-lifecycle/README.md new file mode 100644 index 0000000000..0fe002223f --- /dev/null +++ b/maven-modules/maven-build-lifecycle/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Difference Between mvn install and mvn verify](https://www.baeldung.com/maven-install-versus-verify) diff --git a/messaging-modules/rabbitmq/pom.xml b/messaging-modules/rabbitmq/pom.xml index 2ea2700c4a..d4bdae414a 100644 --- a/messaging-modules/rabbitmq/pom.xml +++ b/messaging-modules/rabbitmq/pom.xml @@ -41,7 +41,7 @@ - 2020.0.3 + 2023.0.0 true diff --git a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/ConnectionPerChannelPublisher.java b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/ConnectionPerChannelPublisher.java index 1692066bef..61d5dab8a2 100644 --- a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/ConnectionPerChannelPublisher.java +++ b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/ConnectionPerChannelPublisher.java @@ -1,15 +1,12 @@ package com.baeldung.benchmark; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.LongSummaryStatistics; -import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -18,8 +15,6 @@ import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.baeldung.benchmark.Worker.WorkerResult; -import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; diff --git a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SharedConnectionPublisher.java b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SharedConnectionPublisher.java index 7b44ccb9ea..5e5eb3ef08 100644 --- a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SharedConnectionPublisher.java +++ b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SharedConnectionPublisher.java @@ -8,13 +8,10 @@ import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.slf4j.Logger; diff --git a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SingleConnectionPublisherNio.java b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SingleConnectionPublisherNio.java index cd4fe28ce9..bbfbff83b3 100644 --- a/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SingleConnectionPublisherNio.java +++ b/messaging-modules/rabbitmq/src/main/java/com/baeldung/benchmark/SingleConnectionPublisherNio.java @@ -8,13 +8,10 @@ import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.slf4j.Logger; diff --git a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/ConnectionPerChannelPublisherLiveTest.java b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/ConnectionPerChannelPublisherLiveTest.java index 0309912e91..9131d8dd59 100644 --- a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/ConnectionPerChannelPublisherLiveTest.java +++ b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/ConnectionPerChannelPublisherLiveTest.java @@ -2,6 +2,7 @@ package com.baeldung.benchmark; import java.util.Arrays; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; class ConnectionPerChannelPublisherLiveTest { @@ -9,9 +10,9 @@ class ConnectionPerChannelPublisherLiveTest { @Test void whenConnectionPerChannel_thenRunBenchmark() throws Exception { // host, workerCount, iterations, payloadSize - Arrays.asList(1,5,10,20,50,100,150).stream() + Stream.of(1,5,10,20,50,100,150) .forEach(workers -> { - ConnectionPerChannelPublisher.main(new String[]{"192.168.99.100", Integer.toString(workers), "1000", "4096"}); + ConnectionPerChannelPublisher.main(new String[]{"localhost", Integer.toString(workers), "1000", "4096"}); }); } diff --git a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/SingleConnectionPublisherLiveTest.java b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/SingleConnectionPublisherLiveTest.java index 6c03f90fb0..073b1a08a8 100644 --- a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/SingleConnectionPublisherLiveTest.java +++ b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/SingleConnectionPublisherLiveTest.java @@ -2,6 +2,7 @@ package com.baeldung.benchmark; import java.util.Arrays; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; class SingleConnectionPublisherLiveTest { @@ -9,9 +10,9 @@ class SingleConnectionPublisherLiveTest { @Test void whenSingleChannel_thenRunBenchmark() throws Exception { // host, workerCount, iterations, payloadSize - Arrays.asList(1,5,10,20,50,100,150).stream() + Stream.of(1,5,10,20,50) .forEach(workers -> { - SingleConnectionPublisher.main(new String[]{"192.168.99.100", Integer.toString(workers), "1000", "4096"}); + SingleConnectionPublisher.main(new String[]{"localhost", Integer.toString(workers), "1000", "4096"}); }); } diff --git a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/queue/dynamic/DynamicQueueCreationLiveTest.java b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/queue/dynamic/DynamicQueueCreationLiveTest.java index aa430035ef..2f97440505 100644 --- a/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/queue/dynamic/DynamicQueueCreationLiveTest.java +++ b/messaging-modules/rabbitmq/src/test/java/com/baeldung/benchmark/queue/dynamic/DynamicQueueCreationLiveTest.java @@ -56,11 +56,17 @@ public class DynamicQueueCreationLiveTest { @Test void givenQueueName_whenQueueDoesNotExist_thenCheckingIfQueueExists() throws IOException, TimeoutException { - - try (Channel channel = connection.createChannel()) { + Channel temp = null; + try { + Channel channel = connection.createChannel(); assertThrows(IOException.class, () -> { channel.queueDeclarePassive(QUEUE_NAME_NEW); }); + temp = channel; + } finally { + if(temp != null && temp.isOpen()) { + temp.close(); + } } } diff --git a/patterns-modules/design-patterns-creational-2/README.md b/patterns-modules/design-patterns-creational-2/README.md index b7fdb556d1..3be51963c3 100644 --- a/patterns-modules/design-patterns-creational-2/README.md +++ b/patterns-modules/design-patterns-creational-2/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [The Factory Design Pattern in Java](https://www.baeldung.com/java-factory-pattern) - [Drawbacks of the Singleton Design Pattern](https://www.baeldung.com/java-patterns-singleton-cons) +- [Builder Pattern and Inheritance](https://www.baeldung.com/java-builder-pattern-inheritance) diff --git a/persistence-modules/java-calcite/README.md b/persistence-modules/java-calcite/README.md new file mode 100644 index 0000000000..4f0c24a09c --- /dev/null +++ b/persistence-modules/java-calcite/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Apache Calcite](https://www.baeldung.com/apache-calcite) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 87fa7761b0..de1e7ebdd2 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -102,7 +102,7 @@ spring-data-solr spring-data-shardingsphere spring-hibernate-3 - + spring-hibernate-5 spring-hibernate-6 spring-jpa spring-jpa-2 diff --git a/persistence-modules/spring-boot-persistence-4/README.md b/persistence-modules/spring-boot-persistence-4/README.md index bb2da31d9c..ab69839542 100644 --- a/persistence-modules/spring-boot-persistence-4/README.md +++ b/persistence-modules/spring-boot-persistence-4/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Scroll API in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-scroll-api) +- [List vs. Set in @OneToMany JPA](https://www.baeldung.com/spring-jpa-onetomany-list-vs-set) diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index 3ad8f791df..b6c8176f2f 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -125,6 +125,20 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + 5.0.2.RELEASE @@ -132,7 +146,7 @@ 4.2.1.RELEASE 5.6.15.Final - 5.8.2.Final + 5.11.12.Final 8.2.0 9.0.0.M26 1.1 diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/ehcache.xml b/persistence-modules/spring-hibernate-5/src/main/resources/ehcache.xml new file mode 100644 index 0000000000..6b92162c3c --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/resources/ehcache.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Foo.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Fooo.java similarity index 93% rename from persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Foo.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Fooo.java index f0d57c5b6e..13f5edcfdf 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Foo.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/deletion/model/Fooo.java @@ -7,13 +7,13 @@ import javax.persistence.*; @Entity @Table(name = "FOO") @Where(clause = "DELETED = 0") -public class Foo { +public class Fooo { - public Foo() { + public Fooo() { super(); } - public Foo(final String name) { + public Fooo(final String name) { super(); this.name = name; } diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/service/DeletionIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/service/DeletionIntegrationTest.java index dfc944f649..55a287a4e7 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/service/DeletionIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/service/DeletionIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.transaction.annotation.Transactional; import com.baeldung.persistence.deletion.config.PersistenceJPAConfigDeletion; import com.baeldung.persistence.deletion.model.Bar; import com.baeldung.persistence.deletion.model.Baz; -import com.baeldung.persistence.deletion.model.Foo; +import com.baeldung.persistence.deletion.model.Fooo; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -41,29 +41,29 @@ public class DeletionIntegrationTest { @Test @Transactional public final void givenEntityIsRemoved_thenItIsNotInDB() { - Foo foo = new Foo("foo"); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + entityManager.persist(fooo); flushAndClear(); - foo = entityManager.find(Foo.class, foo.getId()); - assertThat(foo, notNullValue()); + fooo = entityManager.find(Fooo.class, fooo.getId()); + assertThat(fooo, notNullValue()); - entityManager.remove(foo); + entityManager.remove(fooo); flushAndClear(); - assertThat(entityManager.find(Foo.class, foo.getId()), nullValue()); + assertThat(entityManager.find(Fooo.class, fooo.getId()), nullValue()); } @Test @Transactional public final void givenEntityIsRemovedAndReferencedByAnotherEntity_thenItIsNotRemoved() { Bar bar = new Bar("bar"); - Foo foo = new Foo("foo"); - foo.setBar(bar); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + fooo.setBar(bar); + entityManager.persist(fooo); flushAndClear(); - foo = entityManager.find(Foo.class, foo.getId()); + fooo = entityManager.find(Fooo.class, fooo.getId()); bar = entityManager.find(Bar.class, bar.getId()); entityManager.remove(bar); flushAndClear(); @@ -71,8 +71,8 @@ public class DeletionIntegrationTest { bar = entityManager.find(Bar.class, bar.getId()); assertThat(bar, notNullValue()); - foo = entityManager.find(Foo.class, foo.getId()); - foo.setBar(null); + fooo = entityManager.find(Fooo.class, fooo.getId()); + fooo.setBar(null); entityManager.remove(bar); flushAndClear(); @@ -83,16 +83,16 @@ public class DeletionIntegrationTest { @Transactional public final void givenEntityIsRemoved_thenRemovalIsCascaded() { Bar bar = new Bar("bar"); - Foo foo = new Foo("foo"); - foo.setBar(bar); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + fooo.setBar(bar); + entityManager.persist(fooo); flushAndClear(); - foo = entityManager.find(Foo.class, foo.getId()); - entityManager.remove(foo); + fooo = entityManager.find(Fooo.class, fooo.getId()); + entityManager.remove(fooo); flushAndClear(); - assertThat(entityManager.find(Foo.class, foo.getId()), nullValue()); + assertThat(entityManager.find(Fooo.class, fooo.getId()), nullValue()); assertThat(entityManager.find(Bar.class, bar.getId()), nullValue()); } @@ -116,39 +116,39 @@ public class DeletionIntegrationTest { @Test @Transactional public final void givenEntityIsDeletedWithJpaBulkDeleteStatement_thenItIsNotInDB() { - Foo foo = new Foo("foo"); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + entityManager.persist(fooo); flushAndClear(); - entityManager.createQuery("delete from Foo where id = :id").setParameter("id", foo.getId()).executeUpdate(); + entityManager.createQuery("delete from Foo where id = :id").setParameter("id", fooo.getId()).executeUpdate(); - assertThat(entityManager.find(Foo.class, foo.getId()), nullValue()); + assertThat(entityManager.find(Fooo.class, fooo.getId()), nullValue()); } @Test @Transactional public final void givenEntityIsDeletedWithNativeQuery_thenItIsNotInDB() { - Foo foo = new Foo("foo"); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + entityManager.persist(fooo); flushAndClear(); - entityManager.createNativeQuery("delete from FOO where ID = :id").setParameter("id", foo.getId()).executeUpdate(); + entityManager.createNativeQuery("delete from FOO where ID = :id").setParameter("id", fooo.getId()).executeUpdate(); - assertThat(entityManager.find(Foo.class, foo.getId()), nullValue()); + assertThat(entityManager.find(Fooo.class, fooo.getId()), nullValue()); } @Test @Transactional public final void givenEntityIsSoftDeleted_thenItIsNotReturnedFromQueries() { - Foo foo = new Foo("foo"); - entityManager.persist(foo); + Fooo fooo = new Fooo("foo"); + entityManager.persist(fooo); flushAndClear(); - foo = entityManager.find(Foo.class, foo.getId()); - foo.setDeleted(); + fooo = entityManager.find(Fooo.class, fooo.getId()); + fooo.setDeleted(); flushAndClear(); - assertThat(entityManager.find(Foo.class, foo.getId()), nullValue()); + assertThat(entityManager.find(Fooo.class, fooo.getId()), nullValue()); } private void flushAndClear() { diff --git a/pom.xml b/pom.xml index a73d508d89..1783126809 100644 --- a/pom.xml +++ b/pom.xml @@ -465,10 +465,10 @@ parent-spring-4 parent-spring-5 parent-spring-6 - - apache-spark + apache-spark jhipster-modules + web-modules/restx @@ -615,10 +615,10 @@ parent-spring-4 parent-spring-5 parent-spring-6 - - apache-spark + apache-spark jhipster-modules + web-modules/restx @@ -828,7 +828,7 @@ 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-eureka spring-cloud-modules/spring-cloud-netflix-feign @@ -1067,7 +1067,7 @@ 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-eureka spring-cloud-modules/spring-cloud-netflix-feign diff --git a/spring-6/api-gateway/README.md b/spring-6/api-gateway/README.md new file mode 100644 index 0000000000..d0d8cbb8a2 --- /dev/null +++ b/spring-6/api-gateway/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Global Exception Handling with Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-global-exception-handling) diff --git a/spring-batch-2/pom.xml b/spring-batch-2/pom.xml index 378191c91c..5b6a012e96 100644 --- a/spring-batch-2/pom.xml +++ b/spring-batch-2/pom.xml @@ -48,12 +48,18 @@ ${awaitility.version} test + + org.projectlombok + lombok + ${lombok.version} + 5.0.0 4.2.0 com.baeldung.batch.SpringBootBatchProcessingApplication + 1.18.28 \ No newline at end of file diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConfiguration.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConfiguration.java new file mode 100644 index 0000000000..8fe567c4ea --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConfiguration.java @@ -0,0 +1,78 @@ +package com.baeldung.batchreaderproperties; + +import java.time.ZonedDateTime; +import java.util.Map; + +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.transaction.PlatformTransactionManager; + +import com.baeldung.batchreaderproperties.job.ExpiresSoonMedicineReader; +import com.baeldung.batchreaderproperties.job.MedicineProcessor; +import com.baeldung.batchreaderproperties.job.MedicineWriter; +import com.baeldung.batchreaderproperties.model.Medicine; + +@Configuration +public class BatchConfiguration { + + @Bean + @StepScope + public ExpiresSoonMedicineReader expiresSoonMedicineReader(JdbcTemplate jdbcTemplate, @Value("#{jobParameters}") Map jobParameters) { + + ExpiresSoonMedicineReader medicineReader = new ExpiresSoonMedicineReader(jdbcTemplate); + enrichWithJobParameters(jobParameters, medicineReader); + return medicineReader; + } + + @Bean + @StepScope + public MedicineProcessor medicineProcessor(@Value("#{jobParameters}") Map jobParameters) { + MedicineProcessor medicineProcessor = new MedicineProcessor(); + enrichWithJobParameters(jobParameters, medicineProcessor); + return medicineProcessor; + } + + @Bean + @StepScope + public MedicineWriter medicineWriter(@Value("#{jobParameters}") Map jobParameters) { + MedicineWriter medicineWriter = new MedicineWriter(); + enrichWithJobParameters(jobParameters, medicineWriter); + return medicineWriter; + } + + @Bean + public Job medExpirationJob(JobRepository jobRepository, PlatformTransactionManager transactionManager, MedicineWriter medicineWriter, MedicineProcessor medicineProcessor, ExpiresSoonMedicineReader expiresSoonMedicineReader) { + Step notifyAboutExpiringMedicine = new StepBuilder("notifyAboutExpiringMedicine", jobRepository).chunk(10) + .reader(expiresSoonMedicineReader) + .processor(medicineProcessor) + .writer(medicineWriter) + .faultTolerant() + .transactionManager(transactionManager) + .build(); + + return new JobBuilder("medExpirationJob", jobRepository).incrementer(new RunIdIncrementer()) + .start(notifyAboutExpiringMedicine) + .build(); + } + + private void enrichWithJobParameters(Map jobParameters, ContainsJobParameters container) { + if (jobParameters.get(BatchConstants.TRIGGERED_DATE_TIME) != null) { + container.setTriggeredDateTime(ZonedDateTime.parse(jobParameters.get(BatchConstants.TRIGGERED_DATE_TIME) + .toString())); + } + if (jobParameters.get(BatchConstants.TRACE_ID) != null) { + container.setTraceId(jobParameters.get(BatchConstants.TRACE_ID) + .toString()); + } + } + +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConstants.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConstants.java new file mode 100644 index 0000000000..ac86bd223a --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/BatchConstants.java @@ -0,0 +1,10 @@ +package com.baeldung.batchreaderproperties; + +public class BatchConstants { + public static final String TRIGGERED_DATE_TIME = "TRIGGERED_DATE_TIME"; + public static final String TRACE_ID = "TRACE_ID"; + public static final String ALERT_TYPE = "ALERT_TYPE"; + public static final String DEFAULT_EXPIRATION = "DEFAULT_EXPIRATION"; + public static final String SALE_STARTS_DAYS = "SALE_STARTS_DAYS"; + public static final String MEDICINE_SALE = "MEDICINE_SALE"; +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/ContainsJobParameters.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/ContainsJobParameters.java new file mode 100644 index 0000000000..517246ca07 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/ContainsJobParameters.java @@ -0,0 +1,11 @@ +package com.baeldung.batchreaderproperties; + +import java.time.ZonedDateTime; + +public interface ContainsJobParameters { + ZonedDateTime getTriggeredDateTime(); + String getTraceId(); + + void setTriggeredDateTime(ZonedDateTime triggeredDateTime); + void setTraceId(String traceId); +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/MedExpirationBatchRunner.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/MedExpirationBatchRunner.java new file mode 100644 index 0000000000..cf031727ba --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/MedExpirationBatchRunner.java @@ -0,0 +1,65 @@ +package com.baeldung.batchreaderproperties; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.UUID; + +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +@EnableScheduling +public class MedExpirationBatchRunner { + + @Autowired + private Job medExpirationJob; + + @Autowired + private JobLauncher jobLauncher; + + @Value("${batch.medicine.alert_type}") + private String alertType; + + @Value("${batch.medicine.expiration.default.days}") + private long defaultExpiration; + + @Value("${batch.medicine.start.sale.default.days}") + private long saleStartDays; + + @Value("${batch.medicine.sale}") + private double medicineSale; + + @Scheduled(cron = "${batch.medicine.cron}", zone = "GMT") + public void runJob() { + ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); + launchJob(now); + } + + public void launchJob(ZonedDateTime triggerZonedDateTime) { + try { + JobParameters jobParameters = new JobParametersBuilder().addString(BatchConstants.TRIGGERED_DATE_TIME, triggerZonedDateTime.toString()) + .addString(BatchConstants.ALERT_TYPE, alertType) + .addLong(BatchConstants.DEFAULT_EXPIRATION, defaultExpiration) + .addLong(BatchConstants.SALE_STARTS_DAYS, saleStartDays) + .addDouble(BatchConstants.MEDICINE_SALE, medicineSale) + .addString(BatchConstants.TRACE_ID, UUID.randomUUID() + .toString()) + .toJobParameters(); + + jobLauncher.run(medExpirationJob, jobParameters); + } catch (Exception e) { + log.error("Failed to run", e); + } + } + +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/SpringBatchExpireMedicationApplication.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/SpringBatchExpireMedicationApplication.java new file mode 100644 index 0000000000..f71dc323c7 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/SpringBatchExpireMedicationApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.batchreaderproperties; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:disable-job-autorun.properties") +public class SpringBatchExpireMedicationApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBatchExpireMedicationApplication.class, args); + } + +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/ExpiresSoonMedicineReader.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/ExpiresSoonMedicineReader.java new file mode 100644 index 0000000000..821d054818 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/ExpiresSoonMedicineReader.java @@ -0,0 +1,84 @@ +package com.baeldung.batchreaderproperties.job; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; + +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.annotation.BeforeStep; +import org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.util.ClassUtils; + +import com.baeldung.batchreaderproperties.ContainsJobParameters; +import com.baeldung.batchreaderproperties.model.Medicine; +import com.baeldung.batchreaderproperties.model.MedicineCategory; + +import jakarta.annotation.PostConstruct; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Getter +@Setter +@RequiredArgsConstructor +@Slf4j +public class ExpiresSoonMedicineReader extends AbstractItemCountingItemStreamItemReader implements ContainsJobParameters { + + private static final String FIND_EXPIRING_SOON_MEDICINE = "Select * from MEDICINE where EXPIRATION_DATE >= CURRENT_DATE AND EXPIRATION_DATE <= DATEADD('DAY', ?, CURRENT_DATE)"; + //common job parameters populated in bean initialization + private ZonedDateTime triggeredDateTime; + private String traceId; + //job parameter injected by Spring + @Value("#{jobParameters['DEFAULT_EXPIRATION']}") + private long defaultExpiration; + + private final JdbcTemplate jdbcTemplate; + + private List expiringMedicineList; + + @Override + protected Medicine doRead() { + if (expiringMedicineList != null && !expiringMedicineList.isEmpty()) { + return expiringMedicineList.get(getCurrentItemCount() - 1); + } + + return null; + } + + @Override + protected void doOpen() { + expiringMedicineList = jdbcTemplate.query(FIND_EXPIRING_SOON_MEDICINE, ps -> ps.setLong(1, defaultExpiration), (rs, row) -> getMedicine(rs)); + + log.info("Trace = {}. Found {} meds that expires soon", traceId, expiringMedicineList.size()); + if (!expiringMedicineList.isEmpty()) { + setMaxItemCount(expiringMedicineList.size()); + } + } + + private static Medicine getMedicine(ResultSet rs) throws SQLException { + return new Medicine(UUID.fromString(rs.getString(1)), rs.getString(2), MedicineCategory.valueOf(rs.getString(3)), rs.getTimestamp(4), rs.getDouble(5), rs.getObject(6, Double.class)); + } + + @Override + protected void doClose() { + + } + + @PostConstruct + public void init() { + setName(ClassUtils.getShortName(getClass())); + } + + @BeforeStep + public void beforeStep(StepExecution stepExecution) { + JobParameters parameters = stepExecution.getJobExecution() + .getJobParameters(); + log.info("Before step params: {}", parameters); + } +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineProcessor.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineProcessor.java new file mode 100644 index 0000000000..5e4e853c98 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineProcessor.java @@ -0,0 +1,46 @@ +package com.baeldung.batchreaderproperties.job; + +import java.sql.Timestamp; +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.beans.factory.annotation.Value; + +import com.baeldung.batchreaderproperties.ContainsJobParameters; +import com.baeldung.batchreaderproperties.model.Medicine; + +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +public class MedicineProcessor implements ItemProcessor, ContainsJobParameters { + + private ZonedDateTime triggeredDateTime; + private String traceId; + + @Value("#{jobParameters['SALE_STARTS_DAYS']}") + private long saleStartsDays; + @Value("#{jobParameters['MEDICINE_SALE']}") + private double medicineSale; + + @Override + public Medicine process(Medicine medicine) { + + final Double originalPrice = medicine.getOriginalPrice(); + final Timestamp expirationDate = medicine.getExpirationDate(); + + Duration daysToExpiration = Duration.between(ZonedDateTime.now(), ZonedDateTime.ofInstant(expirationDate.toInstant(), ZoneId.of("UTC"))); + + if (daysToExpiration.toDays() < saleStartsDays) { + medicine.setSalePrice(originalPrice * (1 - medicineSale)); + log.info("Trace = {}, calculated new sale price {} for medicine {}", traceId, medicine.getSalePrice(), medicine.getId()); + } + + return medicine; + } +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineWriter.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineWriter.java new file mode 100644 index 0000000000..47c1a6a831 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/job/MedicineWriter.java @@ -0,0 +1,29 @@ +package com.baeldung.batchreaderproperties.job; + +import java.time.ZonedDateTime; + +import org.springframework.batch.item.Chunk; +import org.springframework.batch.item.ItemWriter; + +import com.baeldung.batchreaderproperties.ContainsJobParameters; +import com.baeldung.batchreaderproperties.model.Medicine; + +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Getter +@Setter +@Slf4j +public class MedicineWriter implements ItemWriter, ContainsJobParameters { + + private ZonedDateTime triggeredDateTime; + private String traceId; + + @Override + public void write(Chunk chunk) { + chunk.forEach((medicine) -> log.info("Trace = {}. This medicine is expiring {}", traceId, medicine)); + + log.info("Finishing job started at {}", triggeredDateTime); + } +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/Medicine.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/Medicine.java new file mode 100644 index 0000000000..0d657f8a8b --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/Medicine.java @@ -0,0 +1,18 @@ +package com.baeldung.batchreaderproperties.model; + +import java.sql.Timestamp; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Medicine { + private UUID id; + private String name; + private MedicineCategory type; + private Timestamp expirationDate; + private Double originalPrice; + private Double salePrice; +} diff --git a/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/MedicineCategory.java b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/MedicineCategory.java new file mode 100644 index 0000000000..6a2f9b50e1 --- /dev/null +++ b/spring-batch-2/src/main/java/com/baeldung/batchreaderproperties/model/MedicineCategory.java @@ -0,0 +1,5 @@ +package com.baeldung.batchreaderproperties.model; + +public enum MedicineCategory { + ANESTHETICS, ANTIBACTERIALS, ANTIDEPRESSANTS; +} diff --git a/spring-batch-2/src/main/resources/application.properties b/spring-batch-2/src/main/resources/application.properties index 0b8c56d3f8..bbca1d65a2 100644 --- a/spring-batch-2/src/main/resources/application.properties +++ b/spring-batch-2/src/main/resources/application.properties @@ -1 +1,7 @@ -file.input=coffee-list.csv \ No newline at end of file +file.input=coffee-list.csv +##medicine batch related properties +batch.medicine.cron=0 */1 * * * * +batch.medicine.alert_type=LOGS +batch.medicine.expiration.default.days=60 +batch.medicine.start.sale.default.days=45 +batch.medicine.sale=0.1 \ No newline at end of file diff --git a/spring-batch-2/src/main/resources/data.sql b/spring-batch-2/src/main/resources/data.sql new file mode 100644 index 0000000000..4147f20390 --- /dev/null +++ b/spring-batch-2/src/main/resources/data.sql @@ -0,0 +1,4 @@ +INSERT INTO medicine VALUES ('ec278dd3-87b9-4ad1-858f-dfe5bc34bdb5', 'Lidocaine', 'ANESTHETICS', DATEADD('DAY', 120, CURRENT_DATE), 10, null); +INSERT INTO medicine VALUES ('9d39321d-34f3-4eb7-bb9a-a69734e0e372', 'Flucloxacillin', 'ANTIBACTERIALS', DATEADD('DAY', 40, CURRENT_DATE), 20, null); +INSERT INTO medicine VALUES ('87f4ff13-de40-4c7f-95db-627f309394dd', 'Amoxicillin', 'ANTIBACTERIALS', DATEADD('DAY', 70, CURRENT_DATE), 30, null); +INSERT INTO medicine VALUES ('acd99d6a-27be-4c89-babe-0edf4dca22cb', 'Prozac', 'ANTIDEPRESSANTS', DATEADD('DAY', 30, CURRENT_DATE), 40, null); \ No newline at end of file diff --git a/spring-batch-2/src/main/resources/disable-job-autorun.properties b/spring-batch-2/src/main/resources/disable-job-autorun.properties new file mode 100644 index 0000000000..132728afcd --- /dev/null +++ b/spring-batch-2/src/main/resources/disable-job-autorun.properties @@ -0,0 +1 @@ +spring.batch.job.enabled=false \ No newline at end of file diff --git a/spring-batch-2/src/main/resources/schema-all.sql b/spring-batch-2/src/main/resources/schema-all.sql index c17b9f9749..8e04e9a0ed 100644 --- a/spring-batch-2/src/main/resources/schema-all.sql +++ b/spring-batch-2/src/main/resources/schema-all.sql @@ -5,4 +5,15 @@ CREATE TABLE coffee ( brand VARCHAR(20), origin VARCHAR(20), characteristics VARCHAR(30) +); + +DROP TABLE medicine IF EXISTS; + +CREATE TABLE medicine ( + med_id VARCHAR(36) PRIMARY KEY, + name VARCHAR(30), + type VARCHAR(30), + expiration_date TIMESTAMP, + original_price DECIMAL, + sale_price DECIMAL ); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-grpc/README.md b/spring-boot-modules/spring-boot-3-grpc/README.md new file mode 100644 index 0000000000..2aaf35bf20 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-grpc/README.md @@ -0,0 +1,2 @@ +### Relevant Articles +- [Introduction to gRPC with Spring Boot](https://www.baeldung.com/spring-boot-grpc) diff --git a/spring-boot-modules/spring-boot-basic-customization-2/README.md b/spring-boot-modules/spring-boot-basic-customization-2/README.md index 0f4167d25b..4cd0ffc824 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/README.md +++ b/spring-boot-modules/spring-boot-basic-customization-2/README.md @@ -10,4 +10,5 @@ This module contains articles about Spring Boot customization 2 - [Spring Boot Exit Codes](https://www.baeldung.com/spring-boot-exit-codes) - [Guide to Spring Type Conversions](https://www.baeldung.com/spring-type-conversions) - [Container Configuration in Spring Boot 2](https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot) - - [Speed up Spring Boot Startup Time](https://www.baeldung.com/spring-boot-startup-speed) \ No newline at end of file + - [Speed up Spring Boot Startup Time](https://www.baeldung.com/spring-boot-startup-speed) + - More articles: [[<-- prev]](/spring-boot-modules/spring-boot-basic-customization) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml index 439051c7e6..452207bfc2 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml @@ -9,9 +9,10 @@ Module For Spring Boot Basic Customization 2 - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java index 7c52b117fd..9d54a7f80b 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/conf/WebConf.java @@ -7,7 +7,7 @@ import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.servlet.ServletContextListener; +import jakarta.servlet.ServletContextListener; @Configuration public class WebConf { diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java index 8429fc855f..47c8b492a9 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/filter/CustomFilter.java @@ -4,7 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import javax.servlet.*; +import jakarta.servlet.*; import java.io.IOException; @Component diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java index 62b316c012..8ea990a026 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/listener/CustomListener.java @@ -3,8 +3,8 @@ package com.baeldung.dispatchservlet.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; public class CustomListener implements ServletContextListener { diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java index 2a99e797ce..b01116eb20 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/dispatchservlet/servlet/CustomServlet.java @@ -4,11 +4,11 @@ import com.baeldung.dispatchservlet.filter.CustomFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class CustomServlet extends HttpServlet { diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java index 7ddcde7dc8..c7f5ea04f3 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/AuthenticationFilter.java @@ -3,10 +3,10 @@ package com.baeldung.onceperrequestfilter; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Component diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java index 0a354c91ac..225fb7ac78 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/HelloController.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.context.request.async.DeferredResult; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java index 3fd304f86b..4543af06b7 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/onceperrequestfilter/MyOncePerRequestFilter.java @@ -5,10 +5,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Component diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java index e1897de877..d05ecab621 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java @@ -1,7 +1,7 @@ package com.baeldung.typeconversion.entity; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Employee { diff --git a/spring-boot-modules/spring-boot-basic-customization/README.md b/spring-boot-modules/spring-boot-basic-customization/README.md index a3d9f1b1fc..0e5c5ddcbe 100644 --- a/spring-boot-modules/spring-boot-basic-customization/README.md +++ b/spring-boot-modules/spring-boot-basic-customization/README.md @@ -11,3 +11,4 @@ This module contains articles about Spring Boot customization - [Spring Boot: Configuring a Main Class](https://www.baeldung.com/spring-boot-main-class) - [How to Define a Spring Boot Filter?](https://www.baeldung.com/spring-boot-add-filter) - [Guide to the Favicon in Spring Boot](https://www.baeldung.com/spring-boot-favicon) + - More articles: [[next -->]](/spring-boot-modules/spring-boot-basic-customization-2) diff --git a/spring-boot-modules/spring-boot-basic-customization/pom.xml b/spring-boot-modules/spring-boot-basic-customization/pom.xml index 581a7fec06..a491dd769f 100644 --- a/spring-boot-modules/spring-boot-basic-customization/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization/pom.xml @@ -9,9 +9,10 @@ Module For Spring Boot Basic Customization - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -81,7 +82,7 @@ - 1.5.2.RELEASE + 3.1.5 com.baeldung.changeport.CustomApplication diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java index 3924354932..ae2a89dc2d 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java @@ -5,9 +5,14 @@ import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; /** @@ -23,7 +28,7 @@ public class RequestResponseLoggingFilter implements Filter { private final static Logger LOG = LoggerFactory.getLogger(RequestResponseLoggingFilter.class); @Override - public void init(final FilterConfig filterConfig) throws ServletException { + public void init(final FilterConfig filterConfig) { LOG.info("Initializing filter :{}", this); } diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java index 604829c3d3..dcf940614c 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java @@ -5,8 +5,13 @@ import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; /** diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java index be27f099db..604067fe26 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java @@ -5,8 +5,8 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.http.HttpServletRequest; @Controller public class MyErrorController implements ErrorController { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java index 4ad763e0ab..397b872a53 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java @@ -4,7 +4,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Profile; -import javax.annotation.security.RolesAllowed; +import jakarta.annotation.security.RolesAllowed; @Profile("failureanalyzer") @SpringBootApplication(scanBasePackages = "com.baeldung.failureanalyzer") diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java index f31b67615f..dbdb2dfcc3 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java @@ -2,7 +2,7 @@ package com.baeldung.failureanalyzer; import org.springframework.stereotype.Service; -import javax.annotation.Resource; +import jakarta.annotation.Resource; @Service public class MyService { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories index 336477df96..af3bdb6ea6 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories @@ -1,2 +1 @@ org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer - diff --git a/spring-boot-modules/spring-boot-bootstrap/pom.xml b/spring-boot-modules/spring-boot-bootstrap/pom.xml index da16f79a2a..dbaa90644d 100644 --- a/spring-boot-modules/spring-boot-bootstrap/pom.xml +++ b/spring-boot-modules/spring-boot-bootstrap/pom.xml @@ -330,8 +330,8 @@ 4.0.0 - Greenwich.RELEASE - 1.0.0.RELEASE + 2023.0.0 + 1.2.8.RELEASE 2.2.13.RELEASE diff --git a/spring-boot-modules/spring-boot-libraries-3/README.md b/spring-boot-modules/spring-boot-libraries-3/README.md index 1458e3ef39..7d9fd87ad5 100644 --- a/spring-boot-modules/spring-boot-libraries-3/README.md +++ b/spring-boot-modules/spring-boot-libraries-3/README.md @@ -2,4 +2,5 @@ This module contains articles about various Spring Boot libraries -### Relevant Articles: \ No newline at end of file +### Relevant Articles: +- [Event Externalization with Spring Modulith](https://www.baeldung.com/spring-modulith-event-externalization) diff --git a/spring-boot-modules/spring-boot-testing-spock/README.md b/spring-boot-modules/spring-boot-testing-spock/README.md index ab8193ab4e..ac37403a2a 100644 --- a/spring-boot-modules/spring-boot-testing-spock/README.md +++ b/spring-boot-modules/spring-boot-testing-spock/README.md @@ -5,3 +5,4 @@ This module contains articles about Spring Boot testing with Spock framework ### Relevant Articles: - [Testing with Spring and Spock](https://www.baeldung.com/spring-spock-testing) +- [Setting up and Using Spock With Gradle](https://www.baeldung.com/groovy/spock-gradle-setup) diff --git a/spring-cloud-modules/pom.xml b/spring-cloud-modules/pom.xml index ccc8590b0b..2613b9f9ce 100644 --- a/spring-cloud-modules/pom.xml +++ b/spring-cloud-modules/pom.xml @@ -34,7 +34,7 @@ spring-cloud-aws-v3 spring-cloud-consul - + spring-cloud-contract spring-cloud-kubernetes spring-cloud-open-service-broker spring-cloud-archaius diff --git a/spring-cloud-modules/spring-cloud-aws-v3/README.md b/spring-cloud-modules/spring-cloud-aws-v3/README.md index d63b0eaa5d..d42883b1f7 100644 --- a/spring-cloud-modules/spring-cloud-aws-v3/README.md +++ b/spring-cloud-modules/spring-cloud-aws-v3/README.md @@ -1,3 +1,4 @@ # Spring Cloud AWS -TBD \ No newline at end of file +### Relevant Articles: +- [Introduction to Spring Cloud AWS 3.0 – SQS Integration](https://www.baeldung.com/java-spring-cloud-aws-v3-intro) diff --git a/spring-cloud-modules/spring-cloud-contract/pom.xml b/spring-cloud-modules/spring-cloud-contract/pom.xml index 5a987d2862..3044bc3a74 100644 --- a/spring-cloud-modules/spring-cloud-contract/pom.xml +++ b/spring-cloud-modules/spring-cloud-contract/pom.xml @@ -60,7 +60,7 @@ 4.0.3 4.0.4 - 2.1.4.RELEASE + 2.7.11 2.5.6 diff --git a/spring-jinq/pom.xml b/spring-jinq/pom.xml index c1dee7fa9f..ebac1c3112 100644 --- a/spring-jinq/pom.xml +++ b/spring-jinq/pom.xml @@ -64,7 +64,7 @@ 2.0.1 - 6.4.0.Final + 6.4.2.Final \ No newline at end of file diff --git a/spring-kafka-3/README.md b/spring-kafka-3/README.md index f9c0036ce3..5250070952 100644 --- a/spring-kafka-3/README.md +++ b/spring-kafka-3/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Spring Kafka Trusted Packages Feature](https://www.baeldung.com/spring-kafka-trusted-packages-feature) +- [How to Catch Deserialization Errors in Spring-Kafka?](https://www.baeldung.com/spring-kafka-deserialization-errors) diff --git a/spring-reactive-modules/spring-reactive-3/pom.xml b/spring-reactive-modules/spring-reactive-3/pom.xml index 17c9690157..45dd25794e 100644 --- a/spring-reactive-modules/spring-reactive-3/pom.xml +++ b/spring-reactive-modules/spring-reactive-3/pom.xml @@ -64,6 +64,11 @@ org.springframework.session spring-session-data-redis + + com.squareup.okhttp3 + mockwebserver + 4.12.0 + diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/Application.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/Application.java new file mode 100644 index 0000000000..0fcdb3a2fb --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.custom.deserialization; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CodecCustomizerConfig.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CodecCustomizerConfig.java new file mode 100644 index 0000000000..ef3eb1e97f --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CodecCustomizerConfig.java @@ -0,0 +1,27 @@ +package com.baeldung.custom.deserialization.config; + +import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.codec.CodecConfigurer; +import org.springframework.http.codec.json.Jackson2JsonDecoder; +import org.springframework.http.codec.json.Jackson2JsonEncoder; +import org.springframework.util.MimeType; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@Configuration +public class CodecCustomizerConfig { + + @Bean + public CodecCustomizer codecCustomizer(ObjectMapper customObjectMapper) { + return configurer -> { + MimeType mimeType = MimeType.valueOf(MediaType.APPLICATION_JSON_VALUE); + CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs(); + customCodecs.register(new Jackson2JsonDecoder(customObjectMapper, mimeType)); + customCodecs.register(new Jackson2JsonEncoder(customObjectMapper, mimeType)); + }; + } + +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomDeserializer.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomDeserializer.java new file mode 100644 index 0000000000..2eeb250e0b --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomDeserializer.java @@ -0,0 +1,21 @@ +package com.baeldung.custom.deserialization.config; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; + +public class CustomDeserializer extends LocalDateTimeDeserializer { + @Override + public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { + try { + return OffsetDateTime.parse(jsonParser.getText()).atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime(); + } catch (Exception e) { + return super.deserialize(jsonParser, ctxt); + } + } +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomObjectMapper.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomObjectMapper.java new file mode 100644 index 0000000000..9ebd85abf8 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/config/CustomObjectMapper.java @@ -0,0 +1,18 @@ +package com.baeldung.custom.deserialization.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +@Configuration +public class CustomObjectMapper { + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true) + .registerModule(new JavaTimeModule()); + } +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/controller/OrderController.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/controller/OrderController.java new file mode 100644 index 0000000000..20327333f1 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/controller/OrderController.java @@ -0,0 +1,37 @@ +package com.baeldung.custom.deserialization.controller; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.custom.deserialization.model.OrderResponse; +import com.baeldung.custom.deserialization.service.ExternalServiceV1; +import com.baeldung.custom.deserialization.service.ExternalServiceV2; + +import reactor.core.publisher.Mono; + +@RestController +public class OrderController { + + private final ExternalServiceV1 externalServiceV1; + private final ExternalServiceV2 externalServiceV2; + + public OrderController(ExternalServiceV1 externalServiceV1, ExternalServiceV2 externalServiceV2) { + this.externalServiceV1 = externalServiceV1; + this.externalServiceV2 = externalServiceV2; + } + + @GetMapping(value = "v1/order/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + public final Mono searchOrderV1(@PathVariable(value = "id") int id) { + return externalServiceV1.findById(id) + .bodyToMono(OrderResponse.class); + } + + @GetMapping(value = "v2/order/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + public final Mono searchOrderV2(@PathVariable(value = "id") int id) { + return externalServiceV2.findById(id) + .bodyToMono(OrderResponse.class); + } + +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/model/OrderResponse.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/model/OrderResponse.java new file mode 100644 index 0000000000..18d45e7dba --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/model/OrderResponse.java @@ -0,0 +1,19 @@ +package com.baeldung.custom.deserialization.model; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +import lombok.Data; + +@Data +public class OrderResponse { + + private UUID orderId; + + private LocalDateTime orderDateTime; + + private List address; + + private List orderNotes; +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV1.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV1.java new file mode 100644 index 0000000000..34c78ae416 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV1.java @@ -0,0 +1,23 @@ +package com.baeldung.custom.deserialization.service; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; + +@Component +public class ExternalServiceV1 { + + private final WebClient.Builder webclientBuilder; + + public ExternalServiceV1(WebClient.Builder webclientBuilder) { + this.webclientBuilder = webclientBuilder; + } + + public WebClient.ResponseSpec findById(int id) { + return webclientBuilder.baseUrl("http://localhost:8090/") + .build() + .get() + .uri("external/order/" + id) + .retrieve(); + } + +} diff --git a/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV2.java b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV2.java new file mode 100644 index 0000000000..0f976a42f2 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/main/java/com/baeldung/custom/deserialization/service/ExternalServiceV2.java @@ -0,0 +1,40 @@ +package com.baeldung.custom.deserialization.service; + +import java.time.LocalDateTime; + +import org.springframework.http.MediaType; +import org.springframework.http.codec.json.Jackson2JsonDecoder; +import org.springframework.http.codec.json.Jackson2JsonEncoder; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.ExchangeStrategies; +import org.springframework.web.reactive.function.client.WebClient; + +import com.baeldung.custom.deserialization.config.CustomDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +@Component +public class ExternalServiceV2 { + + public WebClient.ResponseSpec findById(int id) { + + ObjectMapper objectMapper = new ObjectMapper().registerModule(new SimpleModule().addDeserializer(LocalDateTime.class, new CustomDeserializer())); + + WebClient webClient = WebClient.builder() + .baseUrl("http://localhost:8090/") + .exchangeStrategies(ExchangeStrategies.builder() + .codecs(clientDefaultCodecsConfigurer -> { + clientDefaultCodecsConfigurer.defaultCodecs() + .jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON)); + clientDefaultCodecsConfigurer.defaultCodecs() + .jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON)); + }) + .build()) + .build(); + + return webClient.get() + .uri("external/order/" + id) + .retrieve(); + } + +} diff --git a/spring-reactive-modules/spring-reactive-3/src/test/java/com/baeldung/custom/deserialization/OrderControllerIntegrationTest.java b/spring-reactive-modules/spring-reactive-3/src/test/java/com/baeldung/custom/deserialization/OrderControllerIntegrationTest.java new file mode 100644 index 0000000000..9c8bd7c0d4 --- /dev/null +++ b/spring-reactive-modules/spring-reactive-3/src/test/java/com/baeldung/custom/deserialization/OrderControllerIntegrationTest.java @@ -0,0 +1,135 @@ +package com.baeldung.custom.deserialization; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.UUID; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.reactive.server.WebTestClient; + +import com.baeldung.custom.deserialization.model.OrderResponse; + +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@TestPropertySource(properties = "server.port=8091") +@AutoConfigureWebTestClient(timeout = "100000") +class OrderControllerIntegrationTest { + + @Autowired + private WebTestClient webTestClient; + + private static MockWebServer mockExternalService; + + @BeforeAll + static void setup() throws IOException { + mockExternalService = new MockWebServer(); + mockExternalService.start(8090); + } + + @Test + void givenMockedExternalResponse_whenSearchByIdV1_thenOrderResponseShouldFailBecauseOfUnknownProperty() { + + mockExternalService.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\n" + " \"orderId\": \"a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab\",\n" + + " \"orderDateTime\": \"2024-01-20T12:34:56\",\n" + + " \"address\": [\"123 Main St\", \"Apt 456\", \"Cityville\"],\n" + + " \"orderNotes\": [\"Special request: Handle with care\", \"Gift wrapping required\"],\n" + + " \"customerName\": \"John Doe\",\n" + " \"totalAmount\": 99.99,\n" + + " \"paymentMethod\": \"Credit Card\"\n" + " }") + .setResponseCode(HttpStatus.OK.value())); + + webTestClient.get() + .uri("v1/order/1") + .exchange() + .expectStatus() + .is5xxServerError(); + } + + @Test + void givenMockedExternalResponse_whenSearchByIdV1_thenOrderResponseShouldBeReceivedSuccessfully() { + + mockExternalService.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\n" + " \"orderId\": \"a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab\",\n" + + " \"orderDateTime\": \"2024-01-20T12:34:56\",\n" + + " \"address\": [\"123 Main St\", \"Apt 456\", \"Cityville\"],\n" + + " \"orderNotes\": [\"Special request: Handle with care\", \"Gift wrapping required\"]\n" + + " }") + .setResponseCode(HttpStatus.OK.value())); + + OrderResponse orderResponse = webTestClient.get() + .uri("v1/order/1") + .exchange() + .expectStatus() + .isOk() + .expectBody(OrderResponse.class) + .returnResult() + .getResponseBody(); + assertEquals(UUID.fromString("a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab"), orderResponse.getOrderId()); + assertEquals(LocalDateTime.of(2024, 1, 20, 12, 34, 56), orderResponse.getOrderDateTime()); + assertThat(orderResponse.getAddress()).hasSize(3); + assertThat(orderResponse.getOrderNotes()).hasSize(2); + } + + @Test + void givenMockedExternalResponse_whenSearchByIdV2_thenOrderResponseShouldFailBecauseOfUnknownProperty() { + + mockExternalService.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\n" + " \"orderId\": \"a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab\",\n" + + " \"orderDateTime\": \"2024-01-20T12:34:56\",\n" + + " \"address\": [\"123 Main St\", \"Apt 456\", \"Cityville\"],\n" + + " \"orderNotes\": [\"Special request: Handle with care\", \"Gift wrapping required\"],\n" + + " \"customerName\": \"John Doe\",\n" + + " \"totalAmount\": 99.99,\n" + + " \"paymentMethod\": \"Credit Card\"\n" + + " }") + .setResponseCode(HttpStatus.OK.value())); + + webTestClient.get() + .uri("v2/order/1") + .exchange() + .expectStatus() + .is5xxServerError(); + } + + @Test + void givenMockedExternalResponse_whenSearchByIdV2_thenOrderResponseShouldBeReceivedSuccessfully() { + + mockExternalService.enqueue(new MockResponse().addHeader("Content-Type", "application/json; charset=utf-8") + .setBody("{\n" + " \"orderId\": \"a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab\",\n" + + " \"orderDateTime\": \"2024-01-20T14:34:56+01:00\",\n" + + " \"address\": [\"123 Main St\", \"Apt 456\", \"Cityville\"],\n" + + " \"orderNotes\": [\"Special request: Handle with care\", \"Gift wrapping required\"]\n" + " }") + .setResponseCode(HttpStatus.OK.value())); + + OrderResponse orderResponse = webTestClient.get() + .uri("v2/order/1") + .exchange() + .expectStatus() + .isOk() + .expectBody(OrderResponse.class) + .returnResult() + .getResponseBody(); + assertEquals(UUID.fromString("a1b2c3d4-e5f6-4a5b-8c9d-0123456789ab"), orderResponse.getOrderId()); + assertEquals(LocalDateTime.of(2024, 1, 20, 13, 34, 56), orderResponse.getOrderDateTime()); + assertThat(orderResponse.getAddress()).hasSize(3); + assertThat(orderResponse.getOrderNotes()).hasSize(2); + } + + @AfterAll + static void tearDown() throws IOException { + mockExternalService.shutdown(); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-azuread/pom.xml b/spring-security-modules/spring-security-azuread/pom.xml index b32a1eb16a..c334bbba3e 100644 --- a/spring-security-modules/spring-security-azuread/pom.xml +++ b/spring-security-modules/spring-security-azuread/pom.xml @@ -2,14 +2,15 @@ - 4.0.0 + spring-security-azuread + com.baeldung - spring-security-modules + parent-boot-3 + ../../parent-boot-3 0.0.1-SNAPSHOT - spring-security-azuread diff --git a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/Application.java b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/Application.java index ac36bc1328..ada9b69df4 100644 --- a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/Application.java +++ b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/Application.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { - + public static void main(String[] args) { SpringApplication.run(Application.class, args); } diff --git a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationConfiguration.java b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationConfiguration.java index 4d82e930ae..9945ad44fa 100644 --- a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationConfiguration.java +++ b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationConfiguration.java @@ -10,9 +10,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; -import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; -import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.web.SecurityFilterChain; @@ -22,18 +20,14 @@ import com.baeldung.security.azuread.support.NamedOidcUser; @Configuration @EnableConfigurationProperties(JwtAuthorizationProperties.class) public class JwtAuthorizationConfiguration { - - - + @Bean SecurityFilterChain customJwtSecurityChain(HttpSecurity http, JwtAuthorizationProperties props) throws Exception { // @formatter:off return http - .authorizeRequests( r -> r.anyRequest().authenticated()) - .oauth2Login(oauth2 -> { - oauth2.userInfoEndpoint(ep -> - ep.oidcUserService(customOidcUserService(props))); - }) + .authorizeHttpRequests( r -> r.anyRequest().authenticated()) + .oauth2Login(oauth2 -> oauth2.userInfoEndpoint(ep -> + ep.oidcUserService(customOidcUserService(props)))) .build(); // @formatter:on } @@ -45,28 +39,16 @@ public class JwtAuthorizationConfiguration { props.getGroupsClaim(), props.getGroupToAuthorities()); - return (userRequest) -> { + return userRequest -> { OidcUser oidcUser = delegate.loadUser(userRequest); // Enrich standard authorities with groups Set mappedAuthorities = new HashSet<>(); mappedAuthorities.addAll(oidcUser.getAuthorities()); mappedAuthorities.addAll(mapper.mapAuthorities(oidcUser)); - + oidcUser = new NamedOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo(),oidcUser.getName()); return oidcUser; }; } - - - -// @Bean -// GrantedAuthoritiesMapper jwtAuthoritiesMapper(JwtAuthorizationProperties props) { -// return new MappingJwtGrantedAuthoritiesMapper( -// props.getAuthoritiesPrefix(), -// props.getGroupsClaim(), -// props.getGroupToAuthorities()); -// } - - } diff --git a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationProperties.java b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationProperties.java index 981be317a3..3520c4aa6d 100644 --- a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationProperties.java +++ b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/config/JwtAuthorizationProperties.java @@ -62,7 +62,4 @@ public class JwtAuthorizationProperties { public void setAuthoritiesPrefix(String authoritiesPrefix) { this.authoritiesPrefix = authoritiesPrefix; } - - - } diff --git a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/support/GroupsClaimMapper.java b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/support/GroupsClaimMapper.java index 2487cd9db3..74f92d96d8 100644 --- a/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/support/GroupsClaimMapper.java +++ b/spring-security-modules/spring-security-azuread/src/main/java/com/baeldung/security/azuread/support/GroupsClaimMapper.java @@ -10,19 +10,16 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.oauth2.core.ClaimAccessor; -import org.springframework.security.oauth2.jwt.Jwt; /** * @author Baeldung * */ public class GroupsClaimMapper { - + private final String authoritiesPrefix; private final String groupsClaim; private final Map> groupToAuthorities; diff --git a/spring-security-modules/spring-security-azuread/src/main/resources/application-azuread.yml b/spring-security-modules/spring-security-azuread/src/main/resources/application-azuread.yml index 5e65c381c8..fec11b84c7 100644 --- a/spring-security-modules/spring-security-azuread/src/main/resources/application-azuread.yml +++ b/spring-security-modules/spring-security-azuread/src/main/resources/application-azuread.yml @@ -17,7 +17,7 @@ spring: - openid - email - profile - + # Group mapping baeldung: jwt: diff --git a/spring-security-modules/spring-security-azuread/src/test/java/com/baeldung/security/azuread/ApplicationLiveTest.java b/spring-security-modules/spring-security-azuread/src/test/java/com/baeldung/security/azuread/ApplicationLiveTest.java index 8c941aa787..2ffa9e9a6f 100644 --- a/spring-security-modules/spring-security-azuread/src/test/java/com/baeldung/security/azuread/ApplicationLiveTest.java +++ b/spring-security-modules/spring-security-azuread/src/test/java/com/baeldung/security/azuread/ApplicationLiveTest.java @@ -1,7 +1,6 @@ package com.baeldung.security.azuread; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; import java.net.URI; @@ -12,6 +11,7 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; @@ -27,9 +27,9 @@ class ApplicationLiveTest { @Test void testWhenAccessRootPath_thenRedirectToAzureAD() { - - ResponseEntity response = rest.getForEntity("http://localhost:" + port , String.class); - HttpStatus st = response.getStatusCode(); + + ResponseEntity response = rest.getForEntity("http://localhost:" + port , String.class); + HttpStatusCode st = response.getStatusCode(); assertThat(st) .isEqualTo(HttpStatus.FOUND); diff --git a/spring-security-modules/spring-security-web-thymeleaf/pom.xml b/spring-security-modules/spring-security-web-thymeleaf/pom.xml index dd5f2d7c97..2c8764b88a 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/pom.xml +++ b/spring-security-modules/spring-security-web-thymeleaf/pom.xml @@ -11,7 +11,8 @@ com.baeldung - spring-security-modules + parent-boot-3 + ../../parent-boot-3 0.0.1-SNAPSHOT @@ -40,8 +41,12 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 + + com.baeldung.springsecuritythymeleaf.SpringSecurityThymeleafApplication + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/CustomUserDetailsService.java b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/CustomUserDetailsService.java index e84f9eac55..2382630e62 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/CustomUserDetailsService.java +++ b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/customuserdetails/CustomUserDetailsService.java @@ -7,7 +7,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Collections; import java.util.HashMap; 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 d438aefcdc..cd8eec18aa 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 @@ -21,19 +21,14 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.userDetailsService(userDetailsService) - .authorizeRequests() - .anyRequest() - .authenticated() - .and() - .formLogin() - .loginPage("/login") - .permitAll() - .defaultSuccessUrl("/index") - .and() - .logout() - .permitAll() - .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) - .logoutSuccessUrl("/login"); + .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry + .anyRequest().authenticated()) + .formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer + .loginPage("/login").permitAll() + .defaultSuccessUrl("/index")) + .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.permitAll() + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login")); return http.build(); } } diff --git a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java index b0478ed01c..c270635363 100644 --- a/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java +++ b/spring-security-modules/spring-security-web-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java @@ -16,19 +16,13 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.authorizeRequests() - .anyRequest() - .authenticated() - .and() - .formLogin() - .loginPage("/login") - .permitAll() - .successForwardUrl("/index") - .and() - .logout() - .permitAll() - .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) - .logoutSuccessUrl("/login"); + http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> + authorizationManagerRequestMatcherRegistry.anyRequest().authenticated()) + .formLogin(httpSecurityFormLoginConfigurer -> + httpSecurityFormLoginConfigurer.loginPage("/login").permitAll().successForwardUrl("/index")) + .logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.permitAll() + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login")); return http.build(); } diff --git a/spring-web-modules/spring-mvc-basics-4/pom.xml b/spring-web-modules/spring-mvc-basics-4/pom.xml index 7e8ef257c7..b54ed01161 100644 --- a/spring-web-modules/spring-mvc-basics-4/pom.xml +++ b/spring-web-modules/spring-mvc-basics-4/pom.xml @@ -22,7 +22,6 @@ org.springframework.boot spring-boot-starter-web - 3.0.2 org.apache.tomcat.embed @@ -31,7 +30,7 @@ javax.servlet jstl - 1.2 + ${jstl.version} org.springframework.boot @@ -39,4 +38,8 @@ + + 1.2 + + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics-5/README.md b/spring-web-modules/spring-mvc-basics-5/README.md index ec91449b0f..d503b9e78e 100644 --- a/spring-web-modules/spring-mvc-basics-5/README.md +++ b/spring-web-modules/spring-mvc-basics-5/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring - [Spring @RequestParam vs @PathVariable Annotations](https://www.baeldung.com/spring-requestparam-vs-pathvariable) - [@RequestMapping Value in Properties File](https://www.baeldung.com/spring-requestmapping-properties-file) - [Map a JSON POST to Multiple Spring MVC Parameters](https://www.baeldung.com/spring-mvc-json-param-mapping) +- [Getting Query String Parameters from HttpServletRequest](https://www.baeldung.com/java-httpservletrequest-get-query-parameters) - More articles: [[<-- prev]](../spring-mvc-basics-4) diff --git a/spring-web-modules/spring-mvc-basics/pom.xml b/spring-web-modules/spring-mvc-basics/pom.xml index 919122f591..bfd8ed5d5f 100644 --- a/spring-web-modules/spring-mvc-basics/pom.xml +++ b/spring-web-modules/spring-mvc-basics/pom.xml @@ -26,9 +26,14 @@ tomcat-embed-jasper - javax.servlet - jstl - ${jstl-version} + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + ${jakarta.servlet.jsp.jstl.version} + + + org.glassfish.web + jakarta.servlet.jsp.jstl + ${jakarta.servlet.jsp.jstl.version} com.sun.xml.bind @@ -67,6 +72,7 @@ 4.0.1 5.4.0 1.2 + 2.0.0 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerIntegrationTest.java b/spring-web-modules/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerIntegrationTest.java new file mode 100644 index 0000000000..af79ef8ec8 --- /dev/null +++ b/spring-web-modules/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.web.controller; + +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.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.BeforeEach; +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +@SpringBootTest +@AutoConfigureMockMvc +public class SampleControllerIntegrationTest { + @Autowired + private MockMvc mockMvc; + + @Test + public void givenBookId_whenMockMVC_thenVerifyResponse() throws Exception { + // Verifies that the controller can be invoked without any error. + this.mockMvc + .perform(get("/sample")) + .andExpect(status().isOk()); + } +} + diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index 213d44f350..e7c66ac0ee 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -65,8 +65,8 @@ com.jayway.jsonpath json-path - test ${json-path.version} + test org.springframework.boot diff --git a/spring-web-modules/spring-rest-query-language/pom.xml b/spring-web-modules/spring-rest-query-language/pom.xml index b44972603d..4f4bb78ad8 100644 --- a/spring-web-modules/spring-rest-query-language/pom.xml +++ b/spring-web-modules/spring-rest-query-language/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 @@ -90,10 +90,14 @@ com.querydsl querydsl-apt + ${querydsl.version} + jakarta com.querydsl querydsl-jpa + ${querydsl.version} + jakarta @@ -111,6 +115,7 @@ commons-logging + ${httpclient.version} org.apache.httpcomponents @@ -128,6 +133,7 @@ org.hibernate hibernate-core + ${hibernate-core.version} xml-apis @@ -150,14 +156,20 @@ - javax.servlet - javax.servlet-api + jakarta.servlet + jakarta.servlet-api provided + ${jakarta.servlet-api.version} - javax.servlet - jstl - runtime + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + ${jakarta.servlet.jsp.jstl.version} + + + org.glassfish.web + jakarta.servlet.jsp.jstl + ${jakarta.servlet.jsp.jstl.version} @@ -181,6 +193,12 @@ spring-test test + + io.rest-assured + rest-assured + ${rest-assured.version} + test + @@ -216,23 +234,6 @@ - - - com.mysema.maven - apt-maven-plugin - ${apt-maven-plugin.version} - - - - process - - - target/generated-sources/java - com.querydsl.apt.jpa.JPAAnnotationProcessor - - - - @@ -305,6 +306,13 @@ 1.7.0 1.1.3 + 6.4.2.Final + 4.5.8 + 3.14.0 + ${querydsl.version} + 2.0.0 + 5.4.0 + 5.0.0 \ No newline at end of file diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java index 6bc899176a..afedb2544b 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java @@ -2,12 +2,12 @@ package com.baeldung.persistence.dao; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import org.springframework.stereotype.Repository; diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java index a3e619ad21..a6100a9c66 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java @@ -2,9 +2,9 @@ package com.baeldung.persistence.dao; import java.util.function.Consumer; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import com.baeldung.web.util.SearchCriteria; diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java index 928e75aea7..cb3a04fd6c 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java @@ -5,10 +5,10 @@ import org.springframework.data.jpa.domain.Specification; import com.baeldung.persistence.model.User; import com.baeldung.web.util.SpecSearchCriteria; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; public class UserSpecification implements Specification { diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java index 87a46d4a85..c50f258bf6 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java @@ -3,10 +3,10 @@ package com.baeldung.persistence.dao.rsql; import java.util.List; import java.util.stream.Collectors; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import org.springframework.data.jpa.domain.Specification; diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java index f3b9dc3810..b8f7c93a23 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java @@ -1,9 +1,9 @@ package com.baeldung.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; // used for Querydsl test diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java index dbc2b9360f..8a019eccaf 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java @@ -1,9 +1,9 @@ package com.baeldung.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class User { diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java index c101b1d9b3..056f8e09dd 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java @@ -1,7 +1,7 @@ package com.baeldung.persistence.model; -import javax.persistence.metamodel.SingularAttribute; -import javax.persistence.metamodel.StaticMetamodel; +import jakarta.persistence.metamodel.SingularAttribute; +import jakarta.persistence.metamodel.StaticMetamodel; @StaticMetamodel(User.class) public class User_ { diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java index 371377021a..c869949162 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java @@ -1,7 +1,7 @@ package com.baeldung.spring; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; diff --git a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java index b30f435ee4..bf6aad064e 100644 --- a/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java +++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java @@ -1,6 +1,6 @@ package com.baeldung.web.error; -import javax.persistence.EntityNotFoundException; +import jakarta.persistence.EntityNotFoundException; import org.hibernate.exception.ConstraintViolationException; import org.springframework.dao.DataAccessException; @@ -8,6 +8,7 @@ import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -42,14 +43,14 @@ public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionH } @Override - protected ResponseEntity handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + protected ResponseEntity handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatusCode status, final WebRequest request) { final String bodyOfResponse = "This should be application specific"; // ex.getCause() instanceof JsonMappingException, JsonParseException // for additional information later on return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); } @Override - protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatusCode status, final WebRequest request) { final String bodyOfResponse = "This should be application specific"; return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); } diff --git a/spring-web-modules/spring-rest-testing/pom.xml b/spring-web-modules/spring-rest-testing/pom.xml index db1ec6c165..d3f110bb90 100644 --- a/spring-web-modules/spring-rest-testing/pom.xml +++ b/spring-web-modules/spring-rest-testing/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 @@ -74,6 +74,7 @@ commons-logging + ${httpclient.version} org.apache.httpcomponents @@ -91,6 +92,7 @@ org.hibernate hibernate-core + ${hibernate-core.version} xml-apis @@ -132,6 +134,14 @@ spring-test test + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + test + + @@ -238,6 +248,10 @@ 1.9.9 1.1.3 + 6.4.2.Final + 4.5.8 + 3.14.0 + com.baeldung.spring.Application \ No newline at end of file diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java index 9af3d07bed..99a6a8a3ce 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java @@ -2,11 +2,11 @@ package com.baeldung.persistence.model; import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class Foo implements Serializable { diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java index dbc2b9360f..8a019eccaf 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java @@ -1,9 +1,9 @@ package com.baeldung.persistence.model; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; @Entity public class User { diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java index 5a5d9d6241..a7122248d1 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.util.List; import com.baeldung.persistence.IOperations; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.transaction.annotation.Transactional; @@ -40,6 +41,6 @@ public abstract class AbstractService implements IOperat return getDao().save(entity); } - protected abstract PagingAndSortingRepository getDao(); + protected abstract JpaRepository getDao(); } diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java index 92fb6c28a0..3da077183e 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java @@ -5,6 +5,7 @@ import com.baeldung.persistence.model.Foo; import com.baeldung.persistence.service.IFooService; import com.baeldung.persistence.service.common.AbstractService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,7 +24,7 @@ public class FooService extends AbstractService implements IFooService { // API @Override - protected PagingAndSortingRepository getDao() { + protected JpaRepository getDao() { return dao; } diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java index b5350c33c1..45f9ca443f 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java @@ -2,7 +2,7 @@ package com.baeldung.web.controller; import java.util.List; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import com.baeldung.persistence.model.Foo; import com.baeldung.persistence.service.IFooService; diff --git a/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java index e66e9d49e2..89f76b2990 100644 --- a/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java +++ b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java @@ -6,7 +6,7 @@ import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.io.Serializable; import java.util.List; diff --git a/spring-web-modules/spring-session/pom.xml b/spring-web-modules/spring-session/pom.xml index aec64da088..119c71af55 100644 --- a/spring-web-modules/spring-session/pom.xml +++ b/spring-web-modules/spring-session/pom.xml @@ -3,7 +3,6 @@ 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 spring-session 1.0.0-SNAPSHOT spring-session diff --git a/spring-web-modules/spring-thymeleaf-5/README.md b/spring-web-modules/spring-thymeleaf-5/README.md index 7b64a4e423..dcf5dd91b3 100644 --- a/spring-web-modules/spring-thymeleaf-5/README.md +++ b/spring-web-modules/spring-thymeleaf-5/README.md @@ -7,4 +7,5 @@ This module contains articles about Spring with Thymeleaf - [Conditionals in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-conditionals) - [Iteration in Thymeleaf](https://www.baeldung.com/thymeleaf-iteration) - [Spring with Thymeleaf Pagination for a List](https://www.baeldung.com/spring-thymeleaf-pagination) +- [Display Image With Thymeleaf](https://www.baeldung.com/spring-thymeleaf-image) - More articles: [[<-- prev]](../spring-thymeleaf-4) diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/controller/PetController.java b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/controller/PetController.java new file mode 100644 index 0000000000..c2071ac9c7 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/controller/PetController.java @@ -0,0 +1,13 @@ +package com.baeldung.thymeleaf.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class PetController { + + @RequestMapping("/") + public String home() { + return "index"; + } +} diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/cat.jpg b/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/cat.jpg new file mode 100644 index 0000000000..cd92bb4a16 Binary files /dev/null and b/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/cat.jpg differ diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/images/cat.jpg b/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/images/cat.jpg new file mode 100644 index 0000000000..cd92bb4a16 Binary files /dev/null and b/spring-web-modules/spring-thymeleaf-5/src/main/resources/static/images/cat.jpg differ diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/resources/template/index.html b/spring-web-modules/spring-thymeleaf-5/src/main/resources/template/index.html new file mode 100644 index 0000000000..7e045e9769 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/resources/template/index.html @@ -0,0 +1,13 @@ + + + + + Baeldung Pet Store + + +

Welcome Image

+
Pet Store
+ cat + cat + + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf/pom.xml b/spring-web-modules/spring-thymeleaf/pom.xml index ca94d4581e..9f6c62847d 100644 --- a/spring-web-modules/spring-thymeleaf/pom.xml +++ b/spring-web-modules/spring-thymeleaf/pom.xml @@ -108,7 +108,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false diff --git a/testing-modules/groovy-spock/README.md b/testing-modules/groovy-spock/README.md index e61c56d470..14c4b145f9 100644 --- a/testing-modules/groovy-spock/README.md +++ b/testing-modules/groovy-spock/README.md @@ -3,3 +3,4 @@ - [Introduction to Testing with Spock and Groovy](http://www.baeldung.com/groovy-spock) - [Difference Between Stub, Mock, and Spy in the Spock Framework](https://www.baeldung.com/spock-stub-mock-spy) - [Guide to Spock Extensions](https://www.baeldung.com/spock-extensions) +- [Improving Test Coverage and Readability With Spock’s Data Pipes and Tables](https://www.baeldung.com/java-spock-improve-test-coverage-data-feeds-tables) diff --git a/testing-modules/jmeter/pom.xml b/testing-modules/jmeter/pom.xml index 67a21f6c86..868023e762 100644 --- a/testing-modules/jmeter/pom.xml +++ b/testing-modules/jmeter/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../../parent-boot-3 @@ -156,14 +156,11 @@
- - - 3.7.0 - + com.baeldung.dashboard.DashboardApplication 3.7.0 diff --git a/testing-modules/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java b/testing-modules/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java index 033281e07f..1893389fae 100644 --- a/testing-modules/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java +++ b/testing-modules/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java @@ -1,5 +1,7 @@ package com.baeldung.configuration; +import static org.springframework.security.config.Customizer.withDefaults; + import java.util.HashSet; import java.util.Set; @@ -12,6 +14,7 @@ import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration public class WebSecurityConfiguration { @@ -30,15 +33,17 @@ public class WebSecurityConfiguration { } @Bean - public SecurityFilterChain securityFilter(HttpSecurity http) throws Exception { - + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - .authorizeRequests() - .antMatchers("/secured/**").authenticated() - .anyRequest().permitAll() - .and() - .httpBasic(); + .authorizeHttpRequests(authorizeRequests -> + authorizeRequests + .requestMatchers(new AntPathRequestMatcher("/secured/**")) + .authenticated() + .anyRequest().permitAll() + ) + .httpBasic(withDefaults()); return http.build(); + } } diff --git a/testing-modules/jmeter/src/main/java/com/baeldung/domain/Student.java b/testing-modules/jmeter/src/main/java/com/baeldung/domain/Student.java index 0f6150fc48..942a43b215 100644 --- a/testing-modules/jmeter/src/main/java/com/baeldung/domain/Student.java +++ b/testing-modules/jmeter/src/main/java/com/baeldung/domain/Student.java @@ -1,6 +1,6 @@ package com.baeldung.domain; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; diff --git a/testing-modules/selenide/pom.xml b/testing-modules/selenide/pom.xml index 99538d2d14..791dead47d 100644 --- a/testing-modules/selenide/pom.xml +++ b/testing-modules/selenide/pom.xml @@ -17,7 +17,7 @@ com.codeborne selenide - 6.15.0 + ${selenide.version} test @@ -54,6 +54,7 @@ + 6.15.0 6.10 4.8.3 5.3.2 diff --git a/timefold-solver/pom.xml b/timefold-solver/pom.xml index a16afb9e54..8ef97c337a 100644 --- a/timefold-solver/pom.xml +++ b/timefold-solver/pom.xml @@ -36,8 +36,6 @@ - 17 - 17 1.4.0 diff --git a/web-modules/pom.xml b/web-modules/pom.xml index 6119316a62..a23bc9a7a6 100644 --- a/web-modules/pom.xml +++ b/web-modules/pom.xml @@ -35,7 +35,6 @@ ratpack resteasy - restx rome spark-java struts-2 diff --git a/web-modules/restx/pom.xml b/web-modules/restx/pom.xml index 58877ca72c..f0b4bace48 100644 --- a/web-modules/restx/pom.xml +++ b/web-modules/restx/pom.xml @@ -9,9 +9,10 @@ war + parent-modules com.baeldung - web-modules 1.0.0-SNAPSHOT + ../../