Merge branch 'eugenp:master' into master
This commit is contained in:
commit
36363a112e
|
@ -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
|
|
@ -14,16 +14,6 @@
|
|||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,8 +20,4 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<cxf.version>4.0.0</cxf.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -48,7 +48,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<cxf.version>4.0.0</cxf.version>
|
||||
<jakarta-xml.version>4.0.0</jakarta-xml.version>
|
||||
<jakarta.jws.version>3.0.0</jakarta.jws.version>
|
||||
</properties>
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>${cxf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-transports-http-jetty</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>${cxf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.ws</groupId>
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
</profiles>
|
||||
|
||||
<properties>
|
||||
<cxf.version>3.1.8</cxf.version>
|
||||
<spring.version>5.3.25</spring.version>
|
||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<cxf.version>3.1.8</cxf.version>
|
||||
<cxf.version>4.0.0</cxf.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -16,12 +16,12 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-rs-client</artifactId>
|
||||
<version>${cxf-version}</version>
|
||||
<version>${cxf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-rs-sse</artifactId>
|
||||
<version>${cxf-version}</version>
|
||||
<version>${cxf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.ws.rs</groupId>
|
||||
|
@ -60,7 +60,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<cxf-version>4.0.0</cxf-version>
|
||||
<jakarta-ws.version>3.1.0</jakarta-ws.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
<json-simple.version>1.1.1</json-simple.version>
|
||||
<aws-lambda-java-events.version>3.11.0</aws-lambda-java-events.version>
|
||||
<aws-lambda-java-core.version>1.2.1</aws-lambda-java-core.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -46,7 +46,7 @@
|
|||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||
<jackson.version>2.16.0</jackson.version>
|
||||
<gson.version>2.10</gson.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
<name>core-java-arrays-guides</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<system-stubs.jupiter.version>2.1.5</system-stubs.jupiter.version>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
|
@ -34,7 +30,10 @@
|
|||
<version>${system-stubs.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<system-stubs.jupiter.version>2.1.5</system-stubs.jupiter.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -5,18 +5,6 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-collections-5</artifactId>
|
||||
<name>core-java-collections-5</name>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
|
@ -61,6 +49,19 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<junit.version>5.9.2</junit.version>
|
||||
<roaringbitmap.version>0.9.38</roaringbitmap.version>
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
<version>${org.json.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.9</version>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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.");
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Hello, world!
|
|
@ -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<String> 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<String> queue;
|
||||
private final String inputFileName;
|
||||
|
||||
public FileProducer(BlockingQueue<String> 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<String> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
Hello,
|
||||
Baeldung!
|
||||
Nice to meet you!
|
||||
My name is
|
||||
Wynn.
|
|
@ -0,0 +1 @@
|
|||
Hello, world!
|
|
@ -0,0 +1,5 @@
|
|||
Hello,
|
||||
Baeldung!
|
||||
Nice to meet you!
|
||||
My name is
|
||||
Wynn.
|
|
@ -82,6 +82,7 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-io-apis-2</finalName>
|
||||
<resources>
|
||||
|
@ -91,6 +92,7 @@
|
|||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<junit-jupiter-version>5.9.3</junit-jupiter-version>
|
||||
</properties>
|
||||
|
|
|
@ -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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-lang-6</artifactId>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>core-java-lang-6</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
|
||||
<dependency>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-lang-math</artifactId>
|
||||
<name>core-java-lang-math</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
@ -13,13 +21,6 @@
|
|||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-lang-math</finalName>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
<gson.version>2.10.1</gson.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-numbers-6</finalName>
|
||||
<resources>
|
||||
|
@ -44,4 +45,5 @@
|
|||
<properties>
|
||||
<commons-codec>1.16.0</commons-codec>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-numbers-7</finalName>
|
||||
<resources>
|
||||
|
@ -34,4 +35,5 @@
|
|||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -2,14 +2,15 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-records</artifactId>
|
||||
|
||||
<parent>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>core-java-records</artifactId>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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">
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-swing</artifactId>
|
||||
<name>core-java-swing</name>
|
||||
|
@ -12,6 +12,7 @@
|
|||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>20</maven.compiler.source>
|
||||
<maven.compiler.target>20</maven.compiler.target>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Difference Between mvn install and mvn verify](https://www.baeldung.com/maven-install-versus-verify)
|
|
@ -41,7 +41,7 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring-cloud-dependencies.version>2020.0.3</spring-cloud-dependencies.version>
|
||||
<spring-cloud-dependencies.version>2023.0.0</spring-cloud-dependencies.version>
|
||||
<spring-boot.repackage.skip>true</spring-boot.repackage.skip> <!-- to avoid repackaging of the jar -->
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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"});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Introduction to Apache Calcite](https://www.baeldung.com/apache-calcite)
|
|
@ -102,7 +102,7 @@
|
|||
<module>spring-data-solr</module>
|
||||
<module>spring-data-shardingsphere</module>
|
||||
<module>spring-hibernate-3</module>
|
||||
<!-- <module>spring-hibernate-5</module> FAILED --> <!-- long running -->
|
||||
<module>spring-hibernate-5</module>
|
||||
<module>spring-hibernate-6</module>
|
||||
<module>spring-jpa</module>
|
||||
<module>spring-jpa-2</module>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -125,6 +125,20 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<!-- Spring -->
|
||||
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||
|
@ -132,7 +146,7 @@
|
|||
<org.springframework.security.version>4.2.1.RELEASE</org.springframework.security.version>
|
||||
<!-- persistence -->
|
||||
<hibernate.version>5.6.15.Final</hibernate.version>
|
||||
<hibernatesearch.version>5.8.2.Final</hibernatesearch.version>
|
||||
<hibernatesearch.version>5.11.12.Final</hibernatesearch.version>
|
||||
<mysql-connector-java.version>8.2.0</mysql-connector-java.version>
|
||||
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>
|
||||
<jta.version>1.1</jta.version>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ehcache xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
|
||||
monitoring="autodetect" dynamicConfig="true">
|
||||
|
||||
<diskStore path="java.io.tmpdir/ehcache" />
|
||||
|
||||
<defaultCache maxEntriesLocalHeap="10000" eternal="false"
|
||||
timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
|
||||
maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
|
||||
memoryStoreEvictionPolicy="LRU" statistics="true">
|
||||
<persistence strategy="localTempSwap" />
|
||||
</defaultCache>
|
||||
|
||||
<cache name="org.hibernate.cache.internal.StandardQueryCache"
|
||||
maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
|
||||
<persistence strategy="localTempSwap" />
|
||||
</cache>
|
||||
|
||||
</ehcache>
|
|
@ -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;
|
||||
}
|
|
@ -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() {
|
||||
|
|
12
pom.xml
12
pom.xml
|
@ -465,10 +465,10 @@
|
|||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-spring-6</module>
|
||||
|
||||
<module>apache-spark</module>
|
||||
|
||||
<module>apache-spark</module>
|
||||
<module>jhipster-modules</module>
|
||||
<module>web-modules/restx</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
|
@ -615,10 +615,10 @@
|
|||
<module>parent-spring-4</module>
|
||||
<module>parent-spring-5</module>
|
||||
<module>parent-spring-6</module>
|
||||
|
||||
<module>apache-spark</module>
|
||||
|
||||
<module>apache-spark</module>
|
||||
<module>jhipster-modules</module>
|
||||
<module>web-modules/restx</module>
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
@ -828,7 +828,7 @@
|
|||
<module>spring-boot-rest</module>
|
||||
<module>spring-cloud-modules/spring-cloud-azure</module>
|
||||
<module>spring-cloud-modules/spring-cloud-circuit-breaker</module>
|
||||
<!--<module>spring-cloud-modules/spring-cloud-contract</module>--><!-- failing after upgrading to jdk17-->
|
||||
<module>spring-cloud-modules/spring-cloud-contract</module>
|
||||
<!--<module>spring-cloud-modules/spring-cloud-data-flow</module>--><!-- failing after upgrading to jdk17-->
|
||||
<module>spring-cloud-modules/spring-cloud-eureka</module>
|
||||
<module>spring-cloud-modules/spring-cloud-netflix-feign</module>
|
||||
|
@ -1067,7 +1067,7 @@
|
|||
<module>spring-boot-rest</module>
|
||||
<module>spring-cloud-modules/spring-cloud-azure</module>
|
||||
<module>spring-cloud-modules/spring-cloud-circuit-breaker</module>
|
||||
<!--<module>spring-cloud-modules/spring-cloud-contract</module>--><!-- failing after upgrading to jdk17-->
|
||||
<module>spring-cloud-modules/spring-cloud-contract</module>
|
||||
<!--<module>spring-cloud-modules/spring-cloud-data-flow</module>--><!-- failing after upgrading to jdk17-->
|
||||
<module>spring-cloud-modules/spring-cloud-eureka</module>
|
||||
<module>spring-cloud-modules/spring-cloud-netflix-feign</module>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Global Exception Handling with Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-global-exception-handling)
|
|
@ -48,12 +48,18 @@
|
|||
<version>${awaitility.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring.batch.version>5.0.0</spring.batch.version>
|
||||
<awaitility.version>4.2.0</awaitility.version>
|
||||
<start-class>com.baeldung.batch.SpringBootBatchProcessingApplication</start-class>
|
||||
<lombok.version>1.18.28</lombok.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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<String, Object> jobParameters) {
|
||||
|
||||
ExpiresSoonMedicineReader medicineReader = new ExpiresSoonMedicineReader(jdbcTemplate);
|
||||
enrichWithJobParameters(jobParameters, medicineReader);
|
||||
return medicineReader;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@StepScope
|
||||
public MedicineProcessor medicineProcessor(@Value("#{jobParameters}") Map<String, Object> jobParameters) {
|
||||
MedicineProcessor medicineProcessor = new MedicineProcessor();
|
||||
enrichWithJobParameters(jobParameters, medicineProcessor);
|
||||
return medicineProcessor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@StepScope
|
||||
public MedicineWriter medicineWriter(@Value("#{jobParameters}") Map<String, Object> 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).<Medicine, Medicine>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<String, Object> 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Medicine> 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<Medicine> 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);
|
||||
}
|
||||
}
|
|
@ -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<Medicine, Medicine>, 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;
|
||||
}
|
||||
}
|
|
@ -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<Medicine>, ContainsJobParameters {
|
||||
|
||||
private ZonedDateTime triggeredDateTime;
|
||||
private String traceId;
|
||||
|
||||
@Override
|
||||
public void write(Chunk<? extends Medicine> chunk) {
|
||||
chunk.forEach((medicine) -> log.info("Trace = {}. This medicine is expiring {}", traceId, medicine));
|
||||
|
||||
log.info("Finishing job started at {}", triggeredDateTime);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.batchreaderproperties.model;
|
||||
|
||||
public enum MedicineCategory {
|
||||
ANESTHETICS, ANTIBACTERIALS, ANTIDEPRESSANTS;
|
||||
}
|
|
@ -1 +1,7 @@
|
|||
file.input=coffee-list.csv
|
||||
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
|
|
@ -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);
|
|
@ -0,0 +1 @@
|
|||
spring.batch.job.enabled=false
|
|
@ -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
|
||||
);
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles
|
||||
- [Introduction to gRPC with Spring Boot](https://www.baeldung.com/spring-boot-grpc)
|
|
@ -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)
|
||||
- [Speed up Spring Boot Startup Time](https://www.baeldung.com/spring-boot-startup-speed)
|
||||
- More articles: [[<-- prev]](/spring-boot-modules/spring-boot-basic-customization)
|
|
@ -9,9 +9,10 @@
|
|||
<description>Module For Spring Boot Basic Customization 2</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||
<artifactId>spring-boot-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -9,9 +9,10 @@
|
|||
<description>Module For Spring Boot Basic Customization</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring-boot-modules</groupId>
|
||||
<artifactId>spring-boot-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -81,7 +82,7 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<spring-boot-maven-plugin.version>1.5.2.RELEASE</spring-boot-maven-plugin.version>
|
||||
<spring-boot-maven-plugin.version>3.1.5</spring-boot-maven-plugin.version>
|
||||
<!-- The main class to start by executing "java -jar" -->
|
||||
<start-class>com.baeldung.changeport.CustomApplication</start-class>
|
||||
</properties>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue